Edmondskarp算法中文翻译,转载请注明出处 http://zhan.renren.com/aiiyuu?from=bar -- aiiYuu.
(以下两页是原文内容,来自网络:http://www.cs.cornell.edu/courses/cs4820/2010sp/handouts/edmondskarp.pdf)
Edmonds-Karp最大流算法导论
这部分内容展现了Edmonds-Karp最大流算法的内容。在这里假设我们的读者都了解了残留图,增广路,以及网络最小割的概念。在这里我们先了解一下 Ford-Fulkerson算法(aiiYuu注:也是一种求最大流的算法),算法的伪代码如下:
算法1:FordFulkerson(G)
1:f ← 0; Gf←G
2:while Gf 包含从s到t的路径P do
3: 设定P是任意的一条路径.
4: 通过P增加流量f
5: 更新 Gf
6:end while
7:返回最大流f的值
该算法的运行时间是伪多项式的,但不是真正多项式的。我们已经看到了Ford-Fulkerson是一个不错的最大流算法,但是每次只找一条增广路可能会导致Ford-Fulkerson算法运行指数数量的步骤。事实上,当每条边的容量是实数而不是整数的时候,Ford-Fulkerson算法的执行永远不会终止!
Edmonds-Karp算法通过每次找最短路的方法对Ford-Fulkerson算法进行了改进。在接下来的Edmonds-karp算法的伪代码中,我们可以看出该算法的时间复杂度是真的一个关于点数n和变数m的一个多项式。
算法2:EdmondsKarp(G):
1:f ← 0; Gf←G
2:while Gf 包含从s到t的路径P do
3: 设定P是从s到t的一条最短路径
4: 通过P增加流量f
5: 更新 Gf
6:end while
7:返回最大流f的值
在我们对Edmonds-Karp算法进行分析之前,注意用广度优先搜索(Breadth-first search)的方法在s到t之间找一条最短路径的时间复杂度是O(m)。(事实上,用广度优先搜索的方法在s到t之间找一条最短路径的时间复杂度是O(n+m),但是在我们的分析中假设图G中的每一个点都有至少一条邻边,所以n≤2m(( ⊙o⊙?)),所以得到O(m+n)=O(m)。)一旦路径P被发现了,它花费O(n)的时间增广流量f,从而更新图Gf,所以—再次使用n=O(m),我们发现Edmonds-Karp算法的被一次while循环都用时O(m)的时间。然而,我们仍然需要考虑最坏情况下需要进行几次while循环。
为了计算最坏情况下需要进行几次while循环,我们间接地思考Gfc从s开始的广度优先搜索树。(这里简称BFS树)回想一下,BFS树的顶点可以分层为L0,L1,...,Lk,其中L0={s},
Li表示搜索树中所有和s距离为i的点的集合。BFS的几个基本的但是有用的优点就是:对于某个顶点v∈Lj,自由一条最短路径而且路径中包含且只包含了L0,L1,...,Lj当中的元素各一个(按照这种顺序)并且最短路径中没有包含其他节点。所以BFS每次都从s到t之间找这样一条路径s=v0,v1,...,vj=t,其中vi∈Li,0≤i≤j。
现在我们考虑图Gf中如何通过求得的最短路P来增广流量f。
•如果P中包含一条正向边e,那么这条边将被从Gf中删除,而e的反向边e’会被添加入Gf
•如果P中包含一条反向边e’,那么这条边将被从Gf中删除,而e’对应的正向边e将会被添加入Gf
•除此以外,不添加或删除任一条边
•所以,每一条边的建立都是建立在它的反向边被删除的基础上的。
回顾P中所有从level i连向level i+1的边,我们发现Gf中新建的边都是从level i+1连向level i的。我们在运行Edmonds-karp算法的时候,对于所有的节点v,从s到v的距离从来没有减小过!(因为在BFS数中从一个高level的点连一条边向一个低level的点永远不会生成一条更近的路线)这是指导我们对该算法进行分析的关键属性。
当我们选择Gf的增广路经P的时候,我们说边e∈E(Gf)是P的一个瓶颈如果cf(e)=瓶颈(f,P)。注意到如果e是P的一个瓶颈,那么当选择到P作为图Gf的一条增广路经之后,e将会从Gf删除。假设e链接u∈Li,v∈Lj,为了方便e在被删除之后还能够恢复,u必须拥有一个比v更高的level。(注意边添加到网络中两个相邻level的电上。)因为s到v的距离是不会减小的,这就意味着v保持在level i+1或者升高到了更高的level中,而u升高到了level i+2或者升高到了更高的level中。BFS树不可能有超过n的level,所以每一条边作为瓶颈的次数最高也只有n/2次,所以这里总共最多也只有nm次的瓶颈边出现。每次while循环都会找到一条赠广路,而每次找到一条增广路都肯定会有至少一条瓶颈边出现,所以最多进行mn次while循环,而每次while循环都需要O(m)的时间,所以Edmonds-Karp算法的时间复杂度为O(m²n)。
更快地网络硫酸法已经被发现了(相对于Ford-Funkerson算法)。Dinic发现了一个与Edmonds-Karp算法类似的算法但时间复杂度只有O(mn²)。预流推进算法的时间复杂度只有O(n³),现在已知的最快的网络最大流算法是Goldberg 和Rao发明的,对于整数容量点的编号从1到U的图时间复杂度可以降到O(m min{n2/3,m1/2}log(n²/m)log(U))。