网络流各种算法简单总结与比较

信息学竞赛的算法理论分析是个深海,趁着没掉进去,写个总结,而后赶忙去刷题...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中没什么用....

相关文章
相关标签/搜索