[Algorithm] Maximum Flow

Ref MIT: lecture-13-incremental-improvement-max-flow-min-cut/html

 


 

Ford Fulkerson algorithm for finding maximal flow in a flow network:node

  • Keep adding flow through new augmenting paths for as long as it is possible;
  • When there are no more augmenting paths, you have achieved the largest possible flow in the network.

 

Ford Fulkerson最大流算法 (Depth-First)算法

    -- Aleksandar Ignjatovic version.spring

左邊是Residual flow network,必定要親自畫出來。數組

(a) 初始狀態,經過DFS找一條路徑做爲augmented path; 可見瓶頸是4,而後獲得右圖。網絡

【注意,爲什麼這裏augmented path的選擇是如此方式,是否能夠變爲最短路徑做爲更好的選擇呢】ide

(b) 同上。函數

(c) 同上。性能

(d) 正向的有權邊愈來愈少;而後畫出右圖(update後的)的residual flow netowork以下。測試

      

(e) 這個residual flow netowork貌似已經沒有了正向有權邊。那麼,就能夠end了。(d)右就是最終結果,以上是最小割。

 

良心視頻 + 我的補充https://www.youtube.com/watch?v=Z8gcjuS0Vb8&t=393s

此處注意標號(s,8)表示上一個節點是s node,(s,8)容許經過的流量是8。

增廣鏈的選擇,從t node的標號倒推所得。

此時,最大流等於最小割。

 

Follow an arbitrary path until you reach the sink.

Not guaranteed to terminate.

 

舉例演示其繁瑣性:

最後一張 右邊的1->2 又變回了 初始狀態 value=1。

 

讓咱們抽出兩張對比:

可見,中間的這條邊value=1成了瓶頸。致使了i++相似緩慢的遞歸過程。

 

Time complexity

O(KE) K=Maximum Flow, E=Edge

Dependency on the flow

 

 

最大流最小割定理

  Ref: http://www.cnblogs.com/TreeDream/p/5929429.html

  Ref: https://wenku.baidu.com/view/d9c9b9220722192e4536f6e1.html (良心PPT

 

割的淨流f = f(2,4)+f(4,3)+f(3,5) = 12+(-4)+11=19   //等於node1的output

割的容量c(2,4)+c(3,5)=12+11=23

 

多一些例子以下:

 

能夠計算出對於這兩種狀況淨流f(S,T)仍然等於19。  //等於node1的output

 

割的淨流:f = f(2,4)+f(4,3)+f(5,4)+f(5,6) = 12+(-4)+7+4=19   //等於node1的output

 

割的容量:c(2,4)+c(5,4)+c(5,6)=12+7+4=23

 

割的淨流:f = f(1,2)+f(3,2)+f(4,3)+f(5,4)+f(5,6) = 11+1+(-4)+7+4=19   //等於node1的output

割的容量:c(1,2)+c(3,2)+c(5,4)+c(5,6)=16+4+7+4=31 (一瞧就不是最小的割)

 

 

對於任意一個割的淨流f(S,T)必定是小於等於割的容量C(S,T)。那也便是,對於網絡的任意一個流f必定是小於等於任意一個割的容量C(S,T)。

而在全部可能的割中,存在一個容量最小的割,咱們稱其爲最小割。(迴流最小)

 

最大流最小割定理 (參考)

對於一個網絡流圖G=(V,E),其中有源點s和匯點t,那麼下面三個條件是等價的:
1. 流f是圖G的最大流
2. 殘留網絡Gf不存在增廣路
3. 對於G的某一個割(S,T),此時f = C(S,T)


首先證實1 => 2:

咱們利用反證法,假設流f是圖G的最大流,可是殘留網絡中還存在有增廣路p,其流量爲fp。則咱們有流f'=f+fp>f。這與f是最大流產生矛盾。


接着證實2 => 3:

假設殘留網絡Gf不存在增廣路,因此在殘留網絡Gf中不存在路徑從s到達t。
咱們定義S集合爲:當前殘留網絡中s可以到達的點。
同時定義T=V-S。//到達不了的點的集合T
此時(S,T)構成一個割(S,T)。且對於任意的u∈S,v∈T,有f(u,v)=c(u,v)。若f(u,v)<c(u,v),則有Gf(u,v)>0,s能夠到達v,與v屬於T矛盾。
所以有f(S,T)=Σf(u,v)=Σc(u,v)=C(S,T)。


最後證實3 => 1:

因爲f的上界爲最小割,當f到達割的容量時,顯然就已經到達最大值,所以f爲最大流。

 


 

Edmonds-Karp求最大流算法 (Breadth-First)

核心思想就是不斷找增廣路,每找到一條增廣路,記錄增廣路中 邊流量最少的值 d

而後在當前找到增廣路中

    • 每一條正向弧減去d,
    • 每一條反向弧加上d,

當再也不找到增廣路的時候,就證實當前的總流量已是最大流;

至於怎樣找增廣路。。一致認爲BFS是最好的方法了。

 

英倫良心TutorialEdmonds Karp Max Flow Algorithm Tutorial

1. 發現最短路徑

Paths:

    • S->1->2
    • S->1->3
    • S->3->4

並順便記錄了每一個node的child node。

    • S: 1, 3
    • 1: 2, 3
    • 3: 4
    • 2: t
    • 3: 4
    • 4: 2, t

可見,最短路徑只是根據BFS找,並無什麼特殊的。

 

2. 處理最短路徑

加了反向邊,每一條正向弧減去了15。

Total Flow += 15

 

3. 尋找最短路徑(again)

可見,s->3此次也變爲了0邊。

Total Flow = 15+4, 第二次迭代結果是19.

 

4. 尋找最短路徑(again)

2->t, s->3都變爲了0邊,那麼最短路徑的選擇結果便有了改變。

Total Flow = 19+7, 第二次迭代結果是26.

 

Time complexity 

All vertices in residual graph increase monotonically.

Total number of iterations is O(VE) V=Vertices, E=Edges

Each iteration O(E)

Therefore total runtime O(VE2) 

 


 

Maximum matching in bipartite graphs

二分圖最大匹配

 

二分圖:簡單來講,若是圖中點能夠被分爲兩組,而且使得全部邊都跨越組的邊界,則這就是一個二分圖。準確地說:把一個圖的頂點劃分爲兩個不相交集 UU 和VV ,使得每一條邊都分別鏈接UU、VV中的頂點。若是存在這樣的劃分,則此圖爲一個二分圖。二分圖的一個等價定義是:不含有「含奇數條邊的環」的圖。圖 1 是一個二分圖。爲了清晰,咱們之後都把它畫成圖 2 的形式。

匹配:在圖論中,一個「匹配」(matching)是一個邊的集合,其中任意兩條邊都沒有公共頂點。例如,圖 三、圖 4 中紅色的邊就是圖 2 的匹配。

Bipartite Graph(1)  Bipartite Graph(2)  Matching  Maximum Matching

咱們定義匹配點匹配邊未匹配點非匹配邊,它們的含義很是顯然。例如圖 3 中 一、四、五、7 爲匹配點,其餘頂點爲未匹配點;1-五、4-7爲匹配邊,其餘邊爲非匹配邊。

 

最大匹配:一個圖全部匹配中,所含匹配邊數最多的匹配,稱爲這個圖的最大匹配。圖 4 是一個最大匹配,它包含 4 條匹配邊。

完美匹配:若是一個圖的某個匹配中,全部的頂點都是匹配點,那麼它就是一個完美匹配。圖 4 是一個完美匹配。顯然,完美匹配必定是最大匹配(完美匹配的任何一個點都已經匹配,添加一條新的匹配邊必定會與已有的匹配邊衝突)。但並不是每一個圖都存在完美匹配。換一個說法:最多有多少互相喜歡的男孩/女孩能夠配對兒?這就是最大匹配問題。

 

1、匈牙利算法

求解最大匹配問題的一個算法是匈牙利算法,下面講的概念都爲這個算法服務。

5

交替路:從一個未匹配點出發,依次通過非匹配邊、匹配邊、非匹配邊…造成的路徑叫交替路。

增廣路:從一個未匹配點出發,走交替路,若是途徑另外一個未匹配點(出發的點不算),則這條交替路稱爲增廣路(agumenting path)。例如,圖 5 中的一條增廣路如圖 6 所示(圖中的匹配點均用紅色標出):

6

增廣路有一個重要特色:非匹配邊比匹配邊多一條。所以,研究增廣路的意義是改進匹配。只要把增廣路中的匹配邊和非匹配邊的身份交換便可。因爲中間的匹配節點不存在其餘相連的匹配邊,因此這樣作不會破壞匹配的性質。交換後,圖中的匹配邊數目比原來多了 1 條。

咱們能夠經過不停地找增廣路來增長匹配中的匹配邊和匹配點。找不到增廣路時,達到最大匹配(這是增廣路定理)。

那麼,如何在某一時刻/狀態 找增廣路呢?

匈牙利樹通常由 BFS 構造(相似於 BFS 樹)。從一個未匹配點出發運行 BFS(惟一的限制是,必須走交替路),直到不能再擴展爲止。例如,由圖 7,能夠獲得如圖 8 的一棵 BFS 樹:

7   8    9

這棵樹存在一個葉子節點爲非匹配點(7 號),可是匈牙利樹要求全部葉子節點均爲匹配點,所以這不是一棵匈牙利樹。

(由於node7,因此不是匈牙利樹)

若是原圖中根本不含 7 號節點,那麼從 2 號節點出發就會獲得一棵匈牙利樹。這種狀況如圖 9 所示(順便說一句,圖 8 中根節點 2 到非匹配葉子節點 7 顯然是一條增廣路,沿這條增廣路擴充後將獲得一個完美匹配)。

 

匈牙利算法的要點以下

  1. 從左邊第 1 個頂點開始,挑選未匹配點進行搜索,尋找增廣路

    1. 若是通過一個未匹配點,說明尋找成功。更新路徑信息,匹配邊數 +1,中止搜索。
    2. 若是一直沒有找到增廣路,則再也不從這個點開始搜索。事實上,此時搜索後會造成一棵匈牙利樹(Fig.9)。咱們能夠永久性地把它從圖中刪去,而不影響結果。
  2. 因爲找到增廣路以後須要沿着路徑更新匹配,因此咱們須要一個結構來記錄路徑上的點。DFS 版本經過函數調用隱式地使用一個棧,而 BFS 版本使用 prev 數組。

 

過程演示

先從1出發,找增廣路,找到1->A 這條路,標記並記錄。

從2出發,找到2->B這條路,標記並記錄。

從3開始找,發現3所鏈接邊所有被佔用,這時進行一個神奇的操做:

    • 從三開始找一條增廣路3 -> A -> 1 -> B -> 2 -> C
    • 下劃線要出如今兩端(增廣路的性質)
    • 有增光路,綠線所示

Finally,在圖中將有兩種顏色的邊刪去,留下綠色的邊。

 

性能比較

兩個版本的時間複雜度均爲O(VE)。DFS 的優勢是思路清晰、代碼量少,可是性能不如 BFS。

我測試了兩種算法的性能。對於稀疏圖,BFS 版本明顯快於 DFS 版本;而對於稠密圖二者則不相上下。

在徹底隨機數據 9000 個頂點 4,0000 條邊時前者領前後者大約 97.6%,9000 個頂點 100,0000 條邊時前者領前後者 8.6%, 而達到 500,0000 條邊時 BFS 僅領先 0.85%。

 

2、最大流算法

然而,咱們也能夠把這個問題看成是最大流問題,以下:(匈牙利算法其實是對最大流算法的一種改進,提升了效率

中間部分的節點容量設置爲1。

計算二分圖最大匹配除了匈牙利算法(Hungarian Algorithm),還能夠用最大流(Maximal Flow)。

Link: https://www.youtube.com/watch?v=x2BdRml5lmc

Notice:設,全部Edges的權值都是1

 


 

巧妙利用min cuts

 

(1) 實驗與儀器,以得到最大受益爲目的挑實驗來作

E1 (10) --> I1 (5), I2 (6)

E2 (25) --> I2 (6), I3 (7)

由於最大淨收益 = 全部實驗收益 - 相應實驗方案割的容量

因此最大淨收益 = 全部實驗收益 - 最大流

注意 cut的位置!如下稍做權值調整再作一次練習:

最大淨收益(9) = 全部實驗收益(20+25) - 最大流(5+6+25)

 

(2) 斷開鏈接,容量代價最小

任務:以最小的斷開link的cost分離attacher and victims的PC.

Sol:找到二者的最大流,便是最小割全部正向割邊的容量和稱爲割的容量,那個最小容量的割),斷在這些屬於min cuts的edge便可。

 

(3) 傷員分配問題

任務:左邊building裏的傷員須要運送到距離20KM之內的醫院。

Sol:左邊是building內的傷員數量,右邊對應醫院的容納量。 

 

 

(4) 宴席人員分配問題

任務:左邊家庭裏的成員坐在安排的宴席餐桌,要求家庭成員不能坐在一塊兒。

Sol:添加右邊的到T Node的流,權值便是餐桌能容納的人數。

相關文章
相關標籤/搜索