一.分治策略
1.理論介紹:
2.基本步驟:
1分解:將原問題分解爲若干個規模較小,相互獨立,與原問題形式相同的子問題;
2解決:若子問題規模較小而容易被解決則直接解,否則遞歸地解各個子問題;
3合併:將各個子問題的解合併爲原問題的解;
3.算法應用:
I. 最大子數組問題();
II.歸併排序()、快速排序(Partition每次都劃分得很均勻情況下爲);
二.動態規劃
1.理論介紹:
I.兩個要素:最優子結構和子問題重疊;
(1)最優子結構性質:問題的最優解所包含的子問題的解也是最優的;
(2)子問題重疊性質:遞歸算法自頂向下對問題進行求解時,每次產生的子問題並不總
是新問題,有些會被重複計算多次,DP利用子問題的重疊性質,對每一個子問題
只計算一次,然後將其計算結果保存,從而獲得較高的效率;
II.通常基於一個遞推公式以及一個或者多個初始狀態(狀態和狀態轉移方程);
2.算法應用:
I.湊數問題:面值爲1元、3元和5元的硬幣若干枚,如何用最少的硬幣湊夠11元?
遞推公式:,其中,表示 第j個硬幣的面值;
II.求最長非降序子序列的長度LIS:
遞推公式:,其中,求就把i前面的各個子序列中, 最後一個數不大於的序列長度加1,然後取出最大的長度即爲,若i前面的各個子序列中最後一個數都大於,那麼;
III.鋼條切割問題:
遞推公式:
IV.最長公共子序列LCS:
LCS的最優子結構:令和爲兩個序列,爲X和Y的任意LCS.
1.如果,則且是和的一個LCS;
2.如果,那麼意味着Z是和Y的一個LCS;
3.如果,那麼意味着Z是X和的一個LCS;
三.貪心算法
1.理論介紹:
I.基本概念:
II.基本思路:
1.建立數學模型來描述問題;
2.把求解的問題分成若干個子問題;
3.對每一子問題求解,得到子問題的局部最優解;
4.把子問題的解局部最優解合成原來解問題的一個解;
III.適用問題:局部最優策略能產生全局最優解;
2.貪心算法和動態規劃算法比較:
I.貪心算法作出的每步貪心決策都無法改變,由上一步的最優解推導下一步的最優解,而上一部之前的最優解則不作保留;
II.全局最優解中一定包含某個局部最優解,但不一定包含前一個局部最優解,因此需要記錄之前的所有最優解;
III. 動態規劃的關鍵是狀態轉移方程, 邊界條件是可以直接得出的局部最優解;
四.所有結點對的最短路徑問題
1.Floyd-Warshall算法
I.算法思想:
(1)從任意結點i到任意結點j的最短路徑存在2種可能:
第一種:直接從i到j;
第二種:從i經過若干個結點k到j;
(2)設Dis(i,j)爲結點i到j的最短路徑距離,對每個結點k,判斷Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立;若成立,證明從i到k再到j的路徑比i直接到j的路徑短,更新Dis(i,j),當遍歷完所有結點k,Dis(i,j)中記錄的便是i到j的最短路徑的距離;
(3)Dis(i,j)計算過程中用到子問題的最優解,同時存在子問題重疊;
II遞推公式:
III.算法僞代碼:
FLOYD-WARSHALL(W)
1 n=W.rows
2 D(0)=W
3 for k=1 to n
4 let D(k)=(d(k)ij) be a new n*n matrix
5 for i=1 to n
6 for j=1 to n
7 d(k)ij=min(d(k-1)ij,d(k-1)ik+d(k-1)kj)
8 path[i][j]=k
9 return D(n)
(注:矩陣Path記錄i,j兩點之間最短路徑所必須經過的點, 矩陣d(k)ij記錄結點之間的最短距離,時間複雜度)
五.用於稀疏圖的Johnson算法
1.算法思想:
(1)若圖G =(V, E)中權值全非負,則對所有結點運行一次dijkstra算法找出所有結點對的最短路徑;
(2)若有非負值但無負環路,則由原圖轉換得到一組新的非負權重值,再使用(1)中的方法計算,將負值權重轉換爲非負值使用的方法是:
1.在原圖上新加一個結點s,並將w(s, v) == 0;
2.對s運行BellmanFord函數計算出s到其他點的最短路徑,h[i] = ,即s到v的最短路徑值,即每個結點賦予一個值,用於重新計算邊的權重,重新計算出來的權重即爲非負值;
2.算法僞代碼:
JOHNSON(G,w)
1 compute G'
2 if BELIMAN-FORD(G',w,s)==false
return "contains a negative-weight cycle"
3 else
for each vertex v∈G'.v
h(v)= computed by the Bellman-Ford
for each edge(u,v)∈G'.E
let D=(duv)be a new n*n matrix
for each vertix u∈G.V
run Dijkstar(G,w',u) to computefor all v∈G.V
for each vertex v∈G.V
d(u,v)= +h(v)-h(u)
(注:使用菲波那挈堆實現Dijkstra,則時間複雜度爲,二叉堆實現時間複雜度爲)
六.最大流
1.概念和定理:
I.流網絡和流:
(1)容量值c(u,v),源結點s,匯點t,流f
(2)容量限制,流量守恆
II.殘存網絡:殘存容量cf(u,v),殘存網絡Gf=(V,Ef)
IV.切割:淨流量f(S,T),切割(S,T)的容量
V.最大流最小切割定理:
設f爲流網絡G=(V,E)的一個流,該流網絡的源結點爲s,匯點爲t,則下面條件等價:
(1)f是G的一個最大流
(2)殘存網絡Gf不包括任何增廣路徑
(3)|f|=c(S,T),其中(S,T)是流網絡G的某個切割
2.Ford-Fulkerson方法:
I.算法思想:
根據最大流最小切割定理
II.僞代碼:
Ford-FulKERSON(G,s,t)
1 for each edge(u,v)∈G.E
2 (u.v).f=0
3 while there exists a path p from s to t in the residual netword Gf
4 cf(p)=min{ cf(u,v):(u,v)is in p}
5 for each edge(u,v) in p
6 if(u,v) in p
7 (u,v).f=(u,v).f+ cf(p)
8 else
9 (v.u).f=(v.u).f- cf(p)
(注:算法1-2行將流f初始化爲0,算法3-9行重複在殘存網絡Gf中尋找增廣路徑,
再根據殘存容量cf(p)對路徑p上的流f增加,時間複雜度取決於尋找增廣路徑)
3.Edmonds-Karp算法
I.算法思想:
在Ford-Fulkerson算法的中採用廣度優先搜索來尋找增廣路徑,即從源節點s到匯點t的最短路徑,權重爲單位距離;
II.時間複雜度分析:O(VE2);
4.最大二分匹配
I.基本概念:
匹配,最大匹配
II.尋找最大二分匹配:
(1)多源點多匯點的最大流問題轉換爲單源點單匯點的最大流問題;
(2)二分圖G中的一個最大匹配數M的基數等於其對應的流網絡G’中最大流f值;