網絡流各種算法簡單總結與比較

信息學競賽的算法理論分析是個深海,趁着沒掉進去,寫個總結,而後趕忙去刷題...html

本人不是OI選手且對理論方面的研究不多,這只是我這些天(從新)入門網絡流的一個小總結,問題是大大的有的,歡迎評論!算法

容量,流量,可行流,殘量網絡等等基礎概念不贅述了網絡

第一類,增廣路算法(Augmenting-Path):
    該類算法是基於路徑/割的,由Ford和Fulkerson兩我的提出,實際上表明瞭一類算法,:
    從零流開始考慮,假若有這麼一條路,這條路從源點開始到達匯點,而且這條路上的每一段都知足$Flow<C$,
    則咱們必定能找到這條路上的每一段的$C-Flow$的值當中的最小值$δ$
    把這條路上每一段的$Flow$都加上這個$δ$,必定是一個可行流,這樣咱們就獲得了一個更大的可行流,而這條路就叫作增廣路
    咱們不斷地從起點開始尋找增廣路,每次都對其進行增廣,直到找不到增廣路爲止。當找不到增廣路的時候,當前的流量就是最大流
    這也是增廣路類網絡流的核心思路,下來就是這麼找增廣路,怎麼增廣了
 
(1)Dfs尋找任意一個增廣路,並沿着路進行增廣複雜度爲$O(E|Maxflow|)$這個算法通常認爲這個是Ford-Fulkerson算法
    實際上通常認爲的FF算法是不尋找最短增廣路也不劃分層次圖,每次只是對任意一個增廣路去增廣的算法.
 
(2)Edmonds-Karp/SAP/最短增廣路算法 利用BFS尋找最短增廣路徑,
    因爲存圖方式的不一樣,鄰接表$O(VE^2)$,鄰接矩陣$O(V^3)$
 
(3)MPLA/最短路徑增值算法 在殘量網絡上引入層次,
    構建層次圖$O(V)$,$V$個階段每一個階段屢次BFS尋找增廣路$O(E^2)$,總複雜度上界爲$O(VE^2)$
 
(4)Dinic/Blocking Flow Algorithm/阻塞流算法 用一次DFS代替MPLA的屢次BFS增廣
    一樣創建層次圖$O(V)$,$V$個階段,每一個階段一次DFS尋找增光路$O(VE)$,總複雜度上界爲$O(V^2E)$.
 
(5)ISAP,通常認爲是加入了GAP優化的SAP算法,時間效率和 Dinic差很少,能夠說爲 EK算法的優化版。時間複雜度$O(V^2E)$
 
  (6)   Capacity-Scaling/ScalingFord-Fulkerson/Bit-Scaling/容量縮放算法,
    把容量視做二進位數字,從最高位開始,每回合添加一個位數,擴充流量,尋找增廣路,填滿多出的容量,達到最大流。
    顯然,當使用鄰接矩陣時,複雜度$O(E^2log(Cmax)V^2)$,使用鄰接表時是$O((V+E)Elog(Cmax)) $Cmax$爲邊上的最大容量
 
第二類,預流推動類算法
   該類算法是以點爲基礎的
   1.推動/push:
    咱們認爲匯點是最低點,源點是最高的,推動模擬水流在圖上流動到匯點的過程,咱們每次先把水流流入中間節點,再逐步向後推動
 
   2.儲流,過載/excess/overflowing:
    爲了實現推動,咱們給每一個點一個儲流量,點就能夠分爲儲流點/非儲流點,儲流點(也叫過載點),爲了下一步的推動保存當前流量,
    顯然,對於任意一個點,實際上的流入==流出,換句話說,除了匯點和源點,全部點應該是不儲流的,但顯然目前是"過載"/overflowing的
 
   3.可行邊/admissible edge與高度標號/height label:
    給每一個點進行高度標號,並規定只能從高點向地點流量,與層次圖相似
 
   4.預流/preflow:
    因爲每次只到下一層推動,因此預先推動源點的流量到全部相鄰點中
 
   5.重標號/relabel:
    當一個點沒法流動,就擡高它,讓水能夠迴流/流到同高度的點上
 
   6.重回/retreat:
    能夠想見的是,全部中間節點都沒法繼續流下去,顯然根據重標號,中間節點會越來越高,甚至高於源點,當全部的過載流量終將沿着反向邊迴流到源點,至此算法結束
 
    實際過程當中的基本框架就是對圖上各點不斷推動和重標號,直到沒法進行爲止,或者說,最大流存入匯點,多餘的流量流回起點,全部其餘點均不儲流/不過載
    最終匯點的儲流量/源點所流出的流量,就是最大流。
    下來就是怎麼推動,怎麼重標號了
 
  1.樸素預流推動算法/ Push-relabel algorithm with FIFO :
    每一個點重標號次數 $O(V)$ 一共 $O(V^2)$ ,鄰接矩陣每推一次爲 $O(V)$ 鄰接表 爲常數
    標號一共$O(V^3)$ 或 $O(EV^2)$
    每一個邊可能被推動$O(V)$飽和狀況下一共$O(VE)$非飽和狀況下一共$O(EV^2)$
    用一個隊列保存儲流點便可.
 

  2.重標優先預流推動/Relabel-to-front Algorithm框架

    創建鏈表,保存當前圖的拓撲序形式,不含源點匯點,按照拓撲序取點,跳過非儲流點,把以前被推動過的點從新放入表頭,並推動ide

 
  3.最高標號預流推動/Highest-Label Preflow-Push Algorithm/HLPP
    使用優先隊列,每次取出最高標號點進行推動,直到結束,理論複雜度$O(sqrt(m)n^2)$可使用GAP優化!
 
其實也能夠發現,高度標號和層次圖有殊途同歸之妙
最後 給一個權威表格,甚至引入了動態樹,不過沒有HLPP算法
Method Complexity Description
Linear programming   Constraints given by the definition of a legal flow. See the linear program here.
Ford–Fulkerson algorithm $O(Emax|f|)$ As long as there is an open path through the residual graph, send the minimum of the residual capacities on the path.

The algorithm is only guaranteed to terminate if all weights are rational. Otherwise it is possible that the algorithm will not converge to the maximum value. However, if the algorithm terminates, it is guaranteed to find the maximum value.post

Edmonds–Karp algorithm $O(VE^2)$ A specialization of Ford–Fulkerson, finding augmenting paths with breadth-first search.
Dinic's blocking flow algorithm $O(V^2E)$ In each phase the algorithms builds a layered graph with breadth-first search on the residual graph. The maximum flow in a layered graph can be calculated in O(VE) time, and the maximum number of the phases is n-1. In networks with unit capacities, Dinic's algorithm terminates in O(\min\{V^{2/3}, E^{1/2}\}E) time.
MPM (Malhotra, Pramodh-Kumar and Maheshwari) algorithm
$O(V^3)$ Only works on acyclic networks. Refer to the Original Paper.
Dinic's algorithm $O(VE log(V))$ The dynamic trees data structure speeds up the maximum flow computation in the layered graph to O(V E log(V)).
General push-relabel maximum flow algorithm $O(V^2E)$ The push relabel algorithm maintains a preflow, i.e. a flow function with the possibility of excess in the vertices. The algorithm runs while there is a vertex with positive excess, i.e. an active vertex in the graph. The push operation increases the flow on a residual edge, and a height function on the vertices controls which residual edges can be pushed. The height function is changed with a relabel operation. The proper definitions of these operations guarantee that the resulting flow function is a maximum flow.
Push-relabel algorithm with FIFO vertex selection rule $O(V^3)$ Push-relabel algorithm variant which always selects the most recently active vertex, and performs push operations until the excess is positive or there are admissible residual edges from this vertex.
Push-relabel algorithm with dynamic trees O\left(VE\log {\frac {V^{2}}{E}}\right) The algorithm builds limited size trees on the residual graph regarding to height function. These trees provide multilevel push operations.
KRT (King, Rao, Tarjan)'s algorithm
O(EV\log _{\frac {E}{V\log V}}V)  
Binary blocking flow algorithm
O\left(E\cdot \min(V^{\frac {2}{3}},{\sqrt {E}})\cdot \log {\frac {V^{2}}{E}}\log {U}\right) The value U corresponds to the maximum capacity of the network.
James B Orlin's + KRT (King, Rao, Tarjan)'s algorithm
O(VE) Orlin's algorithm solves max-flow in O(VE) time for E\leq O(V^{{16 \over 15}-\epsilon }) while KRT solves it in O(VE) for E>V^{1+\epsilon }.

感想....學習

但實際上目前競賽中經常使用的算法,不管是Dinic仍是ISAP或是HLPP,他們的速度都沒法與單純的最短路算法相比,就連理論上界達到$O(VE)$最高的SPFA都沒法達到優化

而目前科學界理論下界最低的,是Orlin's提出的集大成者,複雜度上界達到$O(VE)$,可是目前尚未進入算法競賽中來,目前所有的網絡流題目複雜度都是按照 O(V2E)來的

可是,實際上不管是網絡流仍是費用流,咱們目前均不須要複雜度如此低的算法ui

絕大多數模型都不會須要創建一個極端的稠密圖/鍊形圖,點數和邊數常常是處於一個數量級的,對於$O(EV^2)$的算法足夠用了this

研究大量複雜度相近而實現方式不一樣的算法,在OI中是有意義的,

OI賽制中須要大量的不一樣數據來區分不一樣的人實力,達到區分度,這也是OI選手對於複雜度,讀入輸出,花式優化的精益求精的緣由,

以Bellmon-Ford最短路爲例,的複雜度達到了$O(VE)$

可是實際上有隊列優化,不重複入隊/重複入隊,SLF,均值,轉DFS,鄰接表指針化等等不一樣的優化/實現方式

在不一樣的圖中都有不一樣的效果,即便其理論複雜度依然是$O(VE)$,但只要選手根據不一樣的圖去選擇優化方式,就幾乎沒法被卡了

並且對於一個題,即便你的複雜度沒法知足數據量,你依然能夠經過其中不少的數據組,獲得不少分,此時,一個優化到極致的算法就很重要了...

而在ICPC賽制中,區分度更多的在題目自己的思惟,程序準確性,與複雜度上界,由於全部算法都經過全部的樣例,也就是說必須用正確的複雜度經過,

在這種狀況下,錯誤的複雜度毫無心義,必須選擇一個複雜度穩定,編碼容易,靈活的穩定算法,且從下手的一開始,就必須嘗試去知足全部的極限數據和情形

OI的90分能夠接受,而ICPC90分就是0分,且0ms的AC和10000ms的AC都一樣正確,尤爲對於網絡流,建一個正確合適網絡圖,比花式優化的效果更大,尤爲是減小多餘邊

總結,最大流的推薦算法有三個,且代碼量均不長,資料也能夠找到,:
1.Dinic 最多見的算法,能夠加上各類優化方法,但沒法改變理論上界
2.ISAP 依然是常見的算法,依然能夠加上各類優化方法,聽說是實踐中最快的
3.HLPP 常見(?)算法中理論上界最低的一個,並且也能夠加入很多優化,但能夠參考的代碼較少,儘管這個算法是最短的?
 
參考閱讀:
 
趕忙實戰去了...
本人如今網絡流AC的數量還不多,以後有機會發一下Dinic,HLPP和ISAP的實戰狀況
不再進考據,比較的坑了,到時候學動態樹/平衡樹若是再考據我就吃**
費用流?GAP優化?等我實踐完了在加上吧....未完待續
 
有趣的附錄:
優化後的SPFA在Codeforce20C這個聽說"卡SPFA"的最短路裸題中的速度
 

甚至超過了在VJ的leaderboard中,全部公開代碼裏最快的dijkstra(Rank5),和第一名至關,但在ICPC中沒什麼用....

相關文章
相關標籤/搜索