INT102 算法笔记
PDF版本下載
文章目錄
- week1 偽代碼與時間復雜度
- 偽代碼(Pseudo Code)
- 時間復雜度(Time complexity)
- week2 評估基礎查找與排序算法
- 線性查找(Linear Search)
- 二分法查找(Binary Search)
- 尋找連續子串出現位置 (Search for a pattern)
- 選擇排序 (Selection Sort)
- 冒泡排序(Bubble Sort)
- 插入排序 (Insertion Sort Algorithm)選讀
- week3 分治思想和基礎圖論
- 分而治之(Divide and Conquer)
- 歸并排序(Merge Sort)(O(nlogn))
- 基礎圖論
- 圖(Graphs)
- 樹(Tree)
- 樹的遍歷
- 歐拉回路(Euler circuit)
- 哈密頓圖(Hamiltonian circuit / path)
- week4 深度優先與廣度優先
- 深度優先(Deep First Search)
- 廣度優先(Breadth First Search)
- week5 貪心算法及最小生成樹
- 貪心算法(Greedy Algorithms)
- 貪心背包問題(Knapsack Problem)
- 最小生成樹(Minimum Spanning Tree)
- Prim's algorithm( O(|E|*log|V|) )
- Kruskal's algorithm ( O(|E|*log|V|) )
- Dijkstra’s algorithm ( O(|E|*log|V|) )
- week6 動態規劃
- 斐波拉契(Fibonacci numbers)(O(n) )
- 流水線調度(Assembly line scheduling)(O(nm^2^) )
- week8 時空轉換相關算法和圖的最短路徑
- 時空轉換 (Space-for-time tradeoffs)
- 計數排序(Counting Sort)(O(n+k))
- 確認連續子串出現位置Horspool's Algorithm
- 圖的最短路徑
- 單起點最短路徑(Single-source shortest paths)
- Bellman-Ford Algorithm
- 多源最短路徑
- Floyd Algorithom(All-pairs shortest paths)(O(n^3^))
- 構建傳遞閉包
- Warshall’s Algorithm(O(n^3^))
- week9 查找最長相同子序列
- 最長相同子序列問題(LCS Intuitive Solution)
- 爆算
- dp
- 雙序列比對問題(Pairwise Sequence Alignment Problem)
- 全局比對dp
- 局部比對(Local alignment)
- 回溯dp的table
- week 10 NP問題
- Circuit-SAT問題
- 范式(Normal form (NF))
- 合取范式 (Conjunctive Normal Form)
- 析取范式 (Disjunctive Normal Form)
- 判斷問題和最優化問題
- 判斷問題(Decision problems)
- 最優化問題(Optimisation problems)
- 解決(solving)問題和判別(verifying)待定解
- P和NP復雜類
- P復雜類(Complexity Classes P )
- NP復雜類(Complexity Classes NP )
- 多項式規約(Polynomial-time reduction)
- NP-hard
- NP-complete
- NP=P?
- week11 回溯剪枝DFS算法設計
- 精確解策略(Exact Solution Strategies)
- 算法設計(Algorithm Design Techniques)
- [n皇后問題(n-Queens Problem)](https://leetcode-cn.com/problems/n-queens/)
- 哈密頓電路(Hamiltonian Circuit )
- [N數之和問題(Subset-Sum Problem)](https://leetcode-cn.com/problems/4sum/)
- 指派問題(Assignment Problem)
- 旅行商問題(Traveling Salesman Problem)
- week12 更多動態規劃dp
- 一維動態規劃問題 1-dimensional DP
- 目標和的加法式數量
- 貼磚 Troll Tiling
- 二維動態規劃問題 2-dimensional DP
- LCS Problem
- 間隔DP Interval DP
- Tree DP
- dp背包問題 Knapsack 0-1 Example
- week13 近似求解
- 爆算 Brute-force algorithms
- 啟發法 Heuristics
- 近似算法 Approximation algorithms
- 準確率Accuracy Ratio
- c-approximation algorithm
- 近似解頂點覆蓋問題VERTEX-COVER
- 近似解TSP問題
- Nearest-neighbor
- Euclidean instances
- Multifragment-heuristic
- Twice-Around-the-Tree Algorithm
week1 偽代碼與時間復雜度
偽代碼(Pseudo Code)
這部分略過
時間復雜度(Time complexity)
要注意的是f(n)和大O(g(n)), f(n)=O(g(n))
下圖展示了時間復雜度之間的大小比較關系
部分題型:
給定一式子,要求求解時間復雜度—》證明各項在某個n值時恒小于某一項
week2 評估基礎查找與排序算法
線性查找(Linear Search)
從頭到尾查,O(n)
二分法查找(Binary Search)
原數組已排序時可用該算法,確定數組的左界和右界,每次查找查兩界中間的數,如果想找的數比中間的數大,把中間+1更新為左界;反之,如果想找的數比中間的數小,把中間-1更新為右界,O(log n)
尋找連續子串出現位置 (Search for a pattern)
從子串第一個字符位置依次向后比較,出現不相同的字符就把整體子串往后移一位繼續從子串第一個字符開始向后比,O(nm)
選擇排序 (Selection Sort)
每次從原始數組中選擇最小數,append到新數組中,O(n^2)
冒泡排序(Bubble Sort)
從前到后,將原數組的相鄰兩數進行比較換位,直到數組末尾,此時末尾的數字已確定,下次(第2次)循環只需比較0到n-1個數字,以此類推,在第i次循環只需比較至n-i+1個數,直到i等于n結束循環,O(n^2)
插入排序 (Insertion Sort Algorithm)選讀
順序遍歷原始數組中的數,插入新數組中,將其放置于新數組里小于該數的數字與大于該數的數字之間,O(n^2)
week3 分治思想和基礎圖論
分而治之(Divide and Conquer)
將大問題轉化為小問題去解決,有時需要舍棄部分子問題。一般來說小問題與大問題之間是類似而不是完全相同,求解一個大問題下的小問題不代表這個解一定對于其他包含該小問題的大問題有用。
一個例子是二分法查找,將在全數組中查找轉化為在半個數組中查找,舍棄另半個數組,往下依次類推…四分之一個數組…八分之一個數組…直到最終只有一個數字。
關于遞歸的時間復雜度
大問題的計算次數=子問題的計算次數+計算子問題結果之間的過程所需次數
三種T(n)對應的大O:
歸并排序(Merge Sort)(O(nlogn))
將數組二分至幾個數字單元,然后有序合并單元化后的數組。
重點在于合并時的操作,新數組依次append(兩個單元數組間最小的第一個數.pop())
總時間復雜度O(nlogn),(上圖,T(n)= 2T(n/2)+ n , 2T(n/2)代表兩個子問題的運行次數,加的那個n是歸并兩子問題所需的遍歷數組的次數)
基礎圖論
圖(Graphs)
- 無向圖(undirected graph) 沒箭頭
節點的度(degree of a vertex v):等于這個節點相連的邊的量
- 有向圖(directed graph) 有箭頭
出度與入度(out-degree and in-degree):出去的邊和進來的邊的數量 - 鄰接矩陣(Adjacency matrix):表示節點間連結與否或距離的矩陣
- 關聯矩陣(Incidence matrix):表示節點與邊的關聯與否或距離的矩陣
- 關聯列表Incidence list,表示最左邊的一列與哪些點相連,如a與b,c相連
左圖鄰接矩陣,右圖關聯矩陣
關聯列表Incidence list,如a與b,c相連,b與a,c,f相連
樹(Tree)
無向圖無環且連續可構造樹
相關術語:
| root | children | parent | degree | leaf | internal vertices | left subtree |
樹的遍歷
L代表遍歷左子樹,R代表遍歷右子樹,v代表當前節點值
歐拉回路(Euler circuit)
既一筆畫問題
能一筆畫的條件:
或者除兩個頂點外,D的其余頂點的出度與入度都相等,而這兩個頂點中一個頂點的出度與入度之差為1,另一個頂點的出度與入度之差為-1。
哈密頓圖(Hamiltonian circuit / path)
給定一個圖,存在有一種一筆畫能夠走完這個圖的所有節點(走過的邊不可再走,不必經過所有邊),也就是這個圖的節點可以一筆畫走完,則稱這個圖為哈密頓圖。
**部分題型:
給定一個遞推公式,證明其O(n)為某值—》以某值為基礎假設T(n)恒等式,證明T(n)有上界為O(n)乘一常數
給定一棵樹,按照前序中序后序對其遍歷
week4 深度優先與廣度優先
深度優先(Deep First Search)
深度優先專注于先找到一個葉子節點,找到一個葉子再依次返回上級繼續往下找與之相近的葉子節點
廣度優先(Breadth First Search)
廣度優先專注于先找里層節點,找完一層再依次往外找外層節點
部分例題:
給定一無向圖,按DFS或BFS按照字母順序對其進行遍歷
week5 貪心算法及最小生成樹
貪心算法(Greedy Algorithms)
每步都選擇最優情況,貪就完事了
在按步進行貪心時,往往會錯過全局最優解,
但是通過合理的貪心策略也可以求得全局最優解或近似解。
貪心背包問題(Knapsack Problem)
給定各個物品的重量和價值,要求在一個限重的背包里面塞入盡可能多值錢的東西。
這時用貪心基本上會錯過最優解。貪值錢/貪輕量/貪價質比這三種策略都有可能錯過最優解。
最小生成樹(Minimum Spanning Tree)
給定一圖,選擇使該圖所有點連通且總權值最小的邊的集合
E邊,V點
最小生成樹有兩種算法:
prim和kruskal
Prim’s algorithm( O(|E|*log|V|) )
這個算法需要維護點的初始集合S和點的最終集合T
初始時T為空,S為所有節點,將任意一節點從S移入T
以下是例題,一行一行來看,每行選取前一行距離最終集合最小的點,然后更新兩集合間線的距離
Kruskal’s algorithm ( O(|E|*log|V|) )
這個算法維護一個已確定的邊的集合T,
起始時圖上所有邊初始化為未確定狀態,集合T為空
Dijkstra’s algorithm ( O(|E|*log|V|) )
針對于邊權值非負的圖,尋求從起點開始到其他各個節點的最短距離。
PPT里有詳細過程
這個算法中每個點都有距離值,初始化為無窮,代表從起點到該點的最短距離。
算法需要維護已確定的點的集合True和一個已探明的集合Light,其余點均未探明。集合T中的點已經確定最小距離值,集合L中的點已被探知但未確定最小距離值。(可以想象為這是一個礦工在探索漆黑礦洞的過程,有些礦洞已走進去過,有些礦洞沒進去過但是在路牌上見過,有些礦洞見都還沒見著)
起始時只有起點在確定集合T中,與起點直接相連的點在探知集合L中,這些點的距離值為它們到起點的邊長。
如果點p在已探明集合L中,再檢查p的新距離值是否小于原來記錄的距離值,如果小于就更新距離值,同時記錄下是從點m這兒發現更短的路的。
如果點p未探明,恭喜,你在黑暗中解鎖了一個新礦洞,將p和其距離值加入集合L,同時記錄下是從點m這兒探知到的。
如果點p在已確定集合T中,則其新距離值一定大于已記錄的距離值。因為這個算法會將當前L中距離值最小的點加入T,又因為邊權值非負,意味著加入T的時間越靠前,其距離值必定越小。
以下是例題,按行來看,每行選取前一行的最小值,然后重新計算更新各個點的距離值。
week6 動態規劃
動規屬于分治的一種,但是分出來的小問題和原先大問題互相是等價的,求解小問題相當于求解大問題,因此動規多了種自下而上求解的方式,減少了時間復雜度。
不妨與分治的例子----二分法查找作比較:
求解大問題【1,2,3,4,5,6】中是否有6,二分法會繼續找【4,5,6】中是否有6。二分法必須要先知道大問題,將他拆解成小問題,無法忽略大問題直接對小問題求解——它不先解決大問題它甚至不知道小問題是啥(是【1,2,3】還是【4,5,6】?還是【7,8,9】?)
一個動規的例子是數字的冪次方,要求算2的8次方,可以通過小問題2乘自己,2的2次方乘自己,2的4次方乘自己這樣自下而上的求解。可以看出,動規可以在求解小問題后,逐步遞推至解決大問題。
斐波拉契(Fibonacci numbers)(O(n) )
自左到右,維護當前F(n)
| 1 | 1 | 2 | 3 | 5 | 8 | 13 |
流水線調度(Assembly line scheduling)(O(nm2) )
給定點和邊的權值
自左到右,維護 到當前步為止,從上到下m個站點最短路徑的距離
一共走n步,每前進一步,更新該步的m個站點最短路徑。更新方程:
該步第i個站點的最短路徑=min(上一步第1個站點的距離值+上一步第1個站點走到這個站點i的距離,上一步第2個站點的距離值+上一步第2個站點走到這個站點i的距離…上一步第m個站點的距離值+上一步第m個站點走到這個站點i的距離)。
右下角的表: j 代表當前步,fm[j]代表第 j 步的從上到下第m個站點
week8 時空轉換相關算法和圖的最短路徑
時空轉換 (Space-for-time tradeoffs)
空間換時間,時間換空間
空間換時間的例子:
預處理輸入存儲一些信息,以待后續使用
使用一個數據結構處理輸入,以便更簡單地處理問題
計數排序(Counting Sort)(O(n+k))
比較排序依靠值比較進行排序,其算法時間復雜度下限O(nlog(n))
而計數排序依靠已排序的桶進行計數排序,不需要進行值比較
其算法時間復雜度O(n+k) ,其中k為原始數列中數的范圍,也就是桶的數量。
該算法維護一個計數數組(就是許多桶)
首先,根據數列的范圍設置多個桶,數列元素的范圍為多少就設置幾個桶。例如,待排序數列中只包含個位數,那么就設置從0~9十個桶。初始時桶內計數都為0。
遍歷原始數列,將遍歷到的數對應的桶內計數自增1。
遍歷桶,更新每個桶的計數=這個桶的計數+前一個桶的計數。遍歷結束后各個桶內計數既代表該桶對應元素在排序后數組中最后處于的位置。
從后向前遍歷原始數列,將遍歷的元素按照對應桶內的計數作為地址依次放在新數組中,然后該桶計數減1。遍歷結束新數組就是排序后的數組
確認連續子串出現位置Horspool’s Algorithm
尋找一字符串的某一連續子串出現位置
算法需要連續子串的shift table來確認按位匹配出錯時,子串需要往右移動多少位,基本思想是“需要將子串往右移多少,才能使當前子串末尾對應的字符串元素再次與子串中最靠右的同名元素匹配”。
創建shift table,初始化shift table中元素為字符串中元素范圍的所有元素。
遍歷shift table:
使用shift table找子串位置:
例題:給一子串求shift table,BAOBAB, 去掉最后一位→BAOBA_,下面以這個去掉最后一位的殘缺串討論
范圍為26個字母,所以table長為26
殘缺串的_往左數1位到A,A對應1
殘缺串的_往左數兩位到B,B對應2
殘缺串的_左邊沒有C,C對應子串長度6
…
圖的最短路徑
單起點最短路徑(Single-source shortest paths)
從一個起點到別的點的最短路徑
邊權值非負: Dijkstra’s Algorithm
邊權值可負:Bellman-Ford Algorithm
Bellman-Ford Algorithm
該算法允許出現負權有向邊,但是不允許出現負權回路
算法維護一個記錄點的走法和距離值的集合T:
算法定義一個操作 松弛(a,b):
算法:
例題,按行看,紅線隔開的行代表從之前行中選擇了節點
紅線區域之內的兩行代表將該點作為松弛時的b點,其他所有點作為a點進行松弛
多源最短路徑
Floyd Algorithom(All-pairs shortest paths)(O(n3))
各個點到各個點的最短路徑,不能有負權回路
維護記錄了點到點距離值的鄰接矩陣。
假設一共有n個城市,對于鄰接矩陣e,依次假設將第k個城市作為中轉,看是否有兩城市 i,j 通過這個中轉城市走路更近些
例題
看每個矩陣,十字型排列既是討論十字里面的有向邊作為兩條中轉邊去更新其他邊距離值(不包括交叉處的0)
如:
第一幅矩陣D(0)中的十字作為坐標軸,計算軸間值之和,發現可以更新出來個5和9,比目前的無窮小,于是把無窮變成5和9
類推即可
構建傳遞閉包
傳遞閉包內點a若能中轉到達點b,則有(a連b)這條線。
Warshall’s Algorithm(O(n3))
算法維護一個狀態矩陣,1表示a點可達b點,0表示不能達到。
例題:
依舊是紅十字,
比如R0中,把十字看成坐標軸,坐標軸間進行并計算,發現二行三列出來個1,于是R1中二行三列更新為1
week9 查找最長相同子序列
最長相同子序列問題(LCS Intuitive Solution)
Leetcode:最長公共子序列
給定兩字符串,可以在保留他們順序的前提下提取部分元素組成子序列,也就是子序列可以不連續取,要求求解最長且相同的子序列,下面是兩種解決方法:
爆算
字符串構造2n個子序列,看是否也是另一個字符串的子序列,直到找到最大且符合條件的子序列,O(2n)
dp
維護一個當前的最長子序列數值c[i,j],依次從1迭代到總長度(或者用遞歸從總長度遞歸到1)。
迭代方程,
第一行表示有一序列為空,
第二行表示當前兩序列最后一位相同,直接引用上一個dp的結構,
第三行表示當前兩序列最后一位不同,試圖gap其中一個從以往dp中找最大值:
例題,尋找ABCBDAB與BDCABA的最長子序列
算出dp后,右下角的值就是最長子序列長度
從右下角向左上回溯可以得出子序列,深色斜著的箭頭代表取當前x軸和y軸元素
也就是BCBA和BCBA
雙序列比對問題(Pairwise Sequence Alignment Problem)
給定兩個序列,遍歷并比對序列元素,根據元素比對結果按照打分表上對應的score值累加score。求解比對到末尾為止,最大的總的score(兩串序列的相似度)
全局比對dp
維護一個當前最大score的二維矩陣,依次從1,1迭代到各自的總長度(或者從各自的總長度遞歸至1,1)。
舉個例子,現在比對字符串abc和abh,求現在最大的score,在以下三種中選最大
迭代方程:
局部比對(Local alignment)
可以得到有較高相似度的子序列,部分比對的dp與全局比對的dp差不多,但是每次迭代時當前score最小為0,意味著迭代時max函數中多了一個常數0。
回溯dp的table
· 通過從全局比對的最終值(最右下角)回溯可以得出使兩序列相似度最大的排列方式
· 通過從部分比對得出來的最大值位置回溯就能得出較高相似度的子序列的排列方式
其中垂直于當前序列方向的箭頭表示那個軸當前位置的一個gap(空格),斜著的箭頭沒影響
如:
global:
對于橫軸而言,豎著的箭頭代表一個_
對于縱軸而言,橫著的箭頭代表一個_
local:
與global相似,不過是從最大值開始取
week 10 NP問題
P指Polynomial Time,多項式時間(指數不含n),P問題表示可以在多項式時間內求出解的問題(哈密頓圖Hamiltonian Circuit(一筆畫問題),背包問題Knapsack Problem,Circuit-SAT問題)
Circuit-SAT問題
給定一布爾電路表達式,檢查是否存在一種輸入,使得其結果可滿足為1(satisfiability)。
范式(Normal form (NF))
這邊引用同站的帖子解釋鏈接
————————————————
析取 (Disjunctive) 就是或操作 (∨)。那些僅由或運算符連接而成的布爾表達式稱之為 析取子句 (Disjunctive clause)。如 ( a ∨ b ∨ ? c ) 。
合取 (Conjunctive) 就是與操作 (∧)。那些僅由與運算符連接而成的布爾表達式稱之為 合取子句 (Conjunctive clause)。如 ( a ∧ b ∧ ? c ) 。
合取范式 (Conjunctive Normal Form)
是命題公式的一個標準型,它由一系列 析取子句 用 合取操作 連接而來。如 ( a ) ∧ ( a ∨ ? c ) ∧ ( b ∨ c )。
析取范式 (Disjunctive Normal Form)
是命題公式的另一個標準型,它由一系列 合取子句 用 析取操作 連接而來。如 ( a ) ∨ ( a ∧ ? c ) ∨ ( b ∧ c )。
————————————————
判斷問題和最優化問題
判斷問題(Decision problems)
輸出為1或0的問題–Circuit-SAT問題。存在不能被算法解決的判斷問題。
Halting Problem (AlanTuring 1936):
“Given a computer program and an input to it, determine whether the program will halt on that input or continue working indefinitely on it.”
最優化問題(Optimisation problems)
試圖找出使結果最大或最小的組合的問題–背包問題
最優化問題可以變為判斷問題,例如,背包問題中給一待定解,詢問算法是否存在能使背包更值錢,更輕的解法。
如果判斷問題是復雜(hard)的,那么最優化問題也是hard的。
解決(solving)問題和判別(verifying)待定解
解決一個問題往往比較復雜,但驗證一個待定解candidate是否正確certificate則比較簡單。
例如:Circuit-SAT問題中,給定一個輸入,咱們能夠驗證這個輸入的結果是否為1,進而為判斷問題提供正確解。
P和NP復雜類
P復雜類(Complexity Classes P )
能夠在多項式時間內解決的問題集合(MST,Single-source-shortest-path)
NP復雜類(Complexity Classes NP )
算法求解過程是不確定的Nondeterministic,但是能夠在多項式Polynomia時間內驗證一個待定解是否正確的問題集合(Hamiltonian circuit,Knapsack problem,Circuit-SAT)
P類是NP類的子類
多項式規約(Polynomial-time reduction)
對于判斷問題A,B,如果存在一轉換關系,可以將待定解a轉化為待定解b,當且僅當問題B有解的時候問題A有解,則稱A規約B(A is reducible to B), 符號為A≤pB,意味著B至少和A一樣難,或者說A是B的一個子類問題。進一步說,如果B存在一個高效算法,則A也存在一個高效算法。
NP-hard
如果NP問題都多項式制約于一個問題M,則稱該問題M為NP-hard問題。
NP-complete
如果M既是NP問題,又是NP-hard,則M為NP-complete問題。
或者另一種表述
即是NP問題,又被其他NP問題多項式制約的問題M,M為NP-complete問題。
(Hamiltonian Circuit Problem,Knapsack Problem,Circuit-SAT)
NP=P?
如果P問題和NP-comlete問題存在非空交集,那么NP=P—》代表NP問題可以規約成一個NP-complete問題,象征著這些交集內的NP-complete問題下屬NP問題都可以在多項式時間內求解,也就是存在NP問題多項式可解。
部分例題:
Given a weighted graph G and a source vertex a, find the shortest paths from a to every other vertex
----》
Given a weighted graph G, a source vertex a and a value k, are there shortest paths from a to every other vertex such that each path is of weight at most k ?
week11 回溯剪枝DFS算法設計
解決NP-hard問題有兩種主要解決方案
精確解策略(Exact Solution Strategies)
算法設計(Algorithm Design Techniques)
創建狀態空間樹(state space tree),二叉樹的節點記錄的是值,狀態空間樹的節點記錄的是當前待定解,一般來說精確解就在葉子節點中,算法整體就是對這顆樹的DFS。
回溯就是找到一個葉子節點后繼續DFS,尋找其他葉子,直到找到一個精確解或者全部葉子都找完。
剪枝(Prune)就是發現當前節點的子樹不可能到達最優解,直接舍棄當前樹枝,返回當前節點上一個節點繼續DFS。
n皇后問題(n-Queens Problem)
國際象棋中,將n個皇后放到一個n x n方格中,使每行每列每對角線上只有一個皇后。
通過剪枝(不滿足條件)回溯可以DFS所有排列方式,找到符合條件的。
哈密頓電路(Hamiltonian Circuit )
給定圖要求一筆畫
通過剪枝(重復走過某一節點)回溯可以DFS所有筆畫方式,直到符合一筆畫條件。
N數之和問題(Subset-Sum Problem)
給定一非負數組和數字t,從數組中選擇若干個數字,使其總和為該特定數字t
剪枝(當前選擇的數字之和大于t)回溯DFS所有選擇,直到總和等于該特定數字。
指派問題(Assignment Problem)
將4個人分配到4個崗位,16種組合都有各自的工資,求解使總工資最少的分配方式(?ppt說的cost指的是工資嗎)。
該算法有個剪枝策略,需要記錄各個節點的下限,如果有節點下限高于現存最優解,則舍棄那個節點。
各個節點的下限計算方式為:
算法:
DPS狀態空間樹,剪枝:刪除下限值高于現存最優解的節點及其子節點
找到葉子節點后,如果葉子節點的下限值低于現存最優解,則更新最優解。
例題:
- 簡便計算
旅行商問題(Traveling Salesman Problem)
給定一無向圖,要求算出旅行商從一點出發盡可能短地走過所有節點然后回到起點的走法。
依舊是剪枝,下限計算:
每次在狀態空間樹中選擇下限值最低的節點或多個下限值最低相等的節點,進入它的子樹進行DFS選擇如何走剩下幾座城市,剪掉其他下限值較高的節點。
例題:
week12 更多動態規劃dp
一維動態規劃問題 1-dimensional DP
目標和的加法式數量
例題:求出所有由1,3,4組成的和為5加法算式(如:1+1+3=5)的數量
大問題:在數組[a1,a2…am]中尋找和為n的加法算式有多少
如:1+1+1+1+1,1+1+3,1+3+1,3+1+1,1 +4,4 +1
子問題:假設ai必在大問題的加法算式內,在數組[a1,a2…am]中尋找和為n-ai的加法算式有多少
如:假設1在父問題的加法算式內,子問題既是求解1,3,4組成的和為5-1=4的加法算式的數量
假設3在父問題的加法算式內,子問題既是求解1,3,4組成的和為5-3=2的加法算式的數量
假設4在父問題的加法算式內,子問題既是求解1,3,4組成的和為5-4=1的加法算式的數量
dp自底部向上求解,算法維護一個數組,記錄不同和的情況下加法式子的數量,和的值將從0逐漸迭代到大問題中的n(i會逐漸增加到n),D[n]即為問題答案
(基本情況base case:前 數組長度+1 個dp值需要先自己算):
貼磚 Troll Tiling
問題:用2x1的小磚塊鋪滿3xn的區域
問題以二維表述,但仍然是個一維dp問題。要點主要在于大問題和小問題之間的銜接過程。
算法維護兩個一維數組,分別記錄兩種情況下的小瓷磚排列情況。
大問題是正好擺放n列,小問題是正好擺放n-1列
首先討論子問題的兩種情況,當我們盡可能照樣子按照每列排放 j 列小瓷磚時,可能:
此時白色的鋪法稱為G(n-1),當然因為空法不同,所以這個方法包含兩個G(n-1)
對于以上兩種情況:
觀察其邊界,發現鋪下一個情況1且不違反其定義的鋪法各自有一種和兩種(彩色)。
(為什么第一種情況三個彩色的小瓷磚只能全橫著鋪:
···· 豎著鋪的途中會變成第二種情況,禁止情況間交叉)
觀察其邊界,發現鋪下一個情況2且不違反定義的鋪法各自有一種和一種(彩色)
最后分析大問題與子問題的關系:
(基本情況base case:只有0,1,2 列時的G(),F()的值)
二維動態規劃問題 2-dimensional DP
LCS Problem
week9講過了,可以看出dp是以二維table的形式體現。
間隔DP Interval DP
給定一字符串,添加最少的字符,使字符串變成對稱的回文字符串 (palindrome)
Example:
– x: “Ab3bd”
– Can get “dAb3bAd” or “Adb3bdA” by inserting 2 characters (one ‘d’, one ‘A’)
將字符串看成滑塊,左邊界i和右邊界j可以滑動。
大問題:字符串需要添加至少多少字符使之回文
子問題:左右邊界同時向內移1的字符串需要添加至少多少字符使之回文
dp維護一個table,記錄不同滑塊范圍時使之回文的添加的字符數
問題間關系:
如果內移掉的字符與另一側內移掉的字符不同,則需要 一側不移動的子問題的dp值 加上一個另一側的內移掉的額外字符 使之回文,在兩側之間找最小。
如果內移掉的字符與另一側內移掉的字符相同,代表該次dp不要添加字符,大問題與子問題dp值相同。
基本情況base case:dpi,i,dpi,i-1=0 for all i
Tree DP
問題:
直接貼dp式子了,
v:根節點
Bv:根節點為黑色,其子樹的最大黑色數量
Wv:根節點為白色,其子樹的最大黑色數量
dp從葉子推到樹根
dp背包問題 Knapsack 0-1 Example
大問題:物品有重量和價值,給定一限重為5的背包,怎樣挑選物品使背包內價值最大
dp思想大問題:物品有重量和價值,dp可供挑選的物品范圍和限重從0到w的背包,求每次dp怎么在當前可選的物品范圍挑選物品使物品價值最大
wi:當前dp背包限重
vt:當前dp預拿取物品的價值
dpi,w:當前dp背包最大價值
wt:當前dp預拿取物品的重量
子問題:背包限重縮小1,或者物品范圍縮小1,或者物品范圍縮小1同時背包限重縮小1
自底向上:
大問題與子問題的關系,隨著背包的容量逐步上漲和物品范圍的擴大,會出現兩種情況:
(例如,dp限重為10的時候物品范圍新增了一個重量為10的物品,這時就要判斷是維持限重為9時的配置還是單獨拿重量為10的那一個物品)
也就是與上次比物品范圍變大,容量上漲,價值變動
也就是與上次比物品范圍變大但是不拿,容量上漲,價值與上次一樣
也就是物品范圍沒法變大,容量上漲一格,價值與上次一樣
以下既是推至背包限重為5,物品范圍為4的情況
根據這個dp table可以從取值方向逐漸逆推至最佳拿取組合
從右下角7開始:(4,5,7)-沒拿-(3,5,7)-沒拿-(2,5,7)-拿2-(1,2,3)-拿1-(0,0,0)
拿取的物品有2和1
算法復雜度O(n*W)
week13 近似求解
NP-completeness 問題是沒辦法在多項式時間求最優解的,
但是可以用較好的方法在多項式內求得足夠優秀的解
三種思路:
爆算 Brute-force algorithms
枚舉所有解;能找到最優,沒法保證運行時間
啟發法 Heuristics
開發直觀算法intuitive algorithms;不確定找的是最優,可以保證多項式時間
基于先驗規則(或者說經驗)的方法,例如:TSP問題中下一個選最近的城市走,背包問題選價質比最高的物品。
近似算法 Approximation algorithms
可以保證找到最優解的近似值(誤差很小);可以保證多項式時間
準確率Accuracy Ratio
在最優化極小值問題中r(sa) = f(sa)/f(s*) =近似算法結果/最優解結果
在最優化極大值問題中r(sa) = f(s*)/f(sa) =最優解結果/近似算法結果
c-approximation algorithm
常數c≥1,能使得對于任意參數的一種問題(all instance of a problem)的準確率都能≤c的算法叫做c近似算法
在這之中最小的c被稱為performance ratio,RA
不幸的是c幾乎沒有上限。
if P≠NP, no c-approximation algorithm for TSP exists.
近似解頂點覆蓋問題VERTEX-COVER
問題:給定一無向圖,找到一個最小的點的集合,使無向圖中的線至少有一個端點在該集合中。
VC - Approximation Algorithm:把問題近似解
隨機選一個邊及其兩端點,然后在圖中去掉與這個邊的兩點相連的所有邊,重復直到未選邊為空
近似解的一個結果:
評估VC問題的近似算法:
顯然不是OPT(最優)的,按理來說最優解中的點之間應該盡可能不相連以分散所有點而減少點的數量,但是近似解法要求每對被選取的連線同時取其兩端點。
近似解TSP問題
Nearest-neighbor
旅行者下一步走向離自己最近且未走過的城市
但是這個近似解準確度與最后一條邊關聯性大,因為最后一條邊無論多長都得走
Euclidean instances
既要求城市滿足2d地圖的自然幾何學(natural geometry):
也就是兩城市之間直接相連的距離要短于經過中轉城市的距離
Multifragment-heuristic
把邊按照距離從小到大排列,每次選擇一個邊加入集合,要求:
比nearest-neighbor復雜,正確率相同
Twice-Around-the-Tree Algorithm
往往比nearest-neighbor算法的正確率高
完
總結
以上是生活随笔為你收集整理的INT102 算法笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 备战面试日记(6.1) - (缓存相关.
- 下一篇: s3c2450下AC97驱动研究