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


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

本人不是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

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

 
  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.

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)來的

但是,實際上無論是網絡流還是費用流,我們目前均不需要復雜度如此低的算法

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

研究大量復雜度相近而實現方式不同的算法,在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中沒什么用....


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM