关于最大流增广路径算法的正确性的证明

来源:互联网 发布:net和java哪个容易学 编辑:程序博客网 时间:2024/05/18 03:15

最大流增广路径算法也叫Ford-Fulkerson算法,这个算法的思想很简单。即找一条从s到t的增广路径,然后对找到的增广点列进行流值的修改,一直迭代直到没有增广路径结束。

具体步骤:

D={V,A,s,t,c}中每一条弧的值初始化为0

1.  s是源点,设点集 U={s},弧的集合 B为空集 ;

2.  弧 a 满足下列条件之一则加入U;

     (1) a 流出U  &&  f (a) <  c (a) ; a加入B;

     (2) a 流入U  &&  f (a)  > 0 ; a加入B;

3.  重复2。

4.  (1) 若U中没有 t 则 f 是最大流;

     (2) 若U中有 t 则 f 不是最大流,且进行如下步骤;

          ①  从 B 中找到一个 s 到 t 的增广路径 s-X1-X2······Xm-t 。(其实是点列)

                  ②  改变点列上每一条弧的值 

如果点列是顺着弧 a 的方向的则 f (a) = f (a) + 1;

如果是逆着弧 a 的方向的则 f (a) = f (a) - 1;

  ③  其它弧上的流大小不改变。

          ④  s -> t 的流增加1,转到1。


现在证明 f 是最大流的充要条件是不存在增广路径

“=>”这个方向很明显,如果存在一条增广路径则 f 可以增加,f显然不是最大流。


"<="方向比较复杂,我们先证明任意的流小于等于任意一个极小割的容量。

这个很明显,设定一个有效的流,因为每一个极小割可以把图分为两部分A和B,对于s和t之外的每一个点x,流向x的量等于从x流出的量,所以从A流向B的流和网络的流相等且 <= 这个极小割的容量,这个割是任意的。

由于图中每条弧的容量确实,所以最大流确定,由于每一轮算法 f 的值增加1,所以最终能得到一个不含t的点集U,(3)结束后点集U划分了一个 s - t 割 ,并且把图分成A和B两部分,U中包含所有s能达到的顶点。由于不存在增广路径,则对于 s-t 割中所有流出U的弧有 f(u,v) == c(u,v),对于所有流入U的弧有 f (u,v) == 0 ;如果 s-t 割不是最小割 ,则存在一个割的容量小于 f 也和前面的证明产生矛盾,所以此时 s-t 割是最小割。把 s-t 割中的每条弧的流值相加得到从 A 流向 B 的流,也是整个网络的流f。显然由每条边 f(u,v) = c(u,v) 知 f == c (s - t)。若 f 不是最大流,则存在 f ’ > f ,则 f ‘ 大于 s-t 割的容量,和前面的证明矛盾,所以 f 是最大流,同时最大流也等于最小割,"<="方向成立。


然后是算法的完善:

每一次的f值可以增加 Min{c(s,x1)-f(s,x1) , c(x1,x2) - f(x1,x2) ······,c(xm,t)-f(xm,t) };因为若Min{c(s,x1)-f(s,x1) , c(x1,x2) - f(x1,x2) ······,c(xm,t)-f(xm,t) }< 1 ,则增加 1 之后一定能找到一条相同的增广路径。所以不妨一次性使这条路径达到饱和!

by zhr2010





 

原创粉丝点击