标号法求最大流
图论中网络的相关概念见上篇博客
算法基本思想:
从某个初始流开始,重复地增加流的值到不能再改进为止,则最后所得的流将是一个最大流。为此,不妨将每条边上的流量设置为0作为初始流量。为了增加给定流量的值,我们必须找出从发点到收点的一条路并沿这条路增加流量。
当前流为最大流的充要条件:网络中不存在增广路
最大流最小截定理:在任何网络中,最大流的流量等于最小截集的容量。
整数流定理:在任何网络中,如果网络所有的弧容量都是整数,则存在整数最大流。
明确一点:最大流是指网络中流的值达到最大,即源的出流量或汇的入流量达到最大,每段弧都有对应的流量,而不是求网络中某个路径的流量。
把最大流算法想象成两个运输站之间运货,两个运输站之间有很多个中转站,每个中转站都有一个最大容量,站与站之间运货都有不同的运货量,而且中转站不会留货物,所以货物的总量一定等于源站的出货数或者汇站的进货数。最大流算法就是在不超过所有中转站的容量的情况下,求最大出货量/进货量以及所有中转站之间的运货量。
如下图所示,左边是容量,右边是流量,在如图所示的流中,流的值达到了最大,为13,也不存在增广路,所谓增广路就是一条从源到汇的路径,路径上的所有弧非饱和(正向)或非空(反向),即一条仍能增加流量的路。
为什么说增广路是一条仍能增加流量的路?其实不难理解,增广路的定义如上文,路径上的所有弧非饱和(正向)或非空(反向),反向弧的流量假设为n,实际上等价于为正向弧的流量为-n,因为n不能小于0,所以n=0的时候,反向弧的流量虽然达到了最小,但是把他当做正向弧的时候,流量却达到了最大。
对于一条路径而言,非饱和弧和非空弧都意味着该条路径的流量没有达到饱和。既然网络中存在一条没有达到饱和的路径,那么网络的流也没有达到最大。这就是当前流为最大流的充要条件,可用数学语言证明。
算法文字描述:
步骤0:将网络中所有弧流量全部置0
步骤1:将源的点流量设为无穷大,令u=s。
步骤2:标记 点的所有未被标记的邻点的点流量(BFS)。
标记方法:若u到邻点是正向弧,且流量小于容量,则点流量取前点流量和弧的容流量差值的较小者
若是反向弧连接,且流量大于0,则点流量取前点流量和弧流量的较小者
步骤3:若标记到了汇则转步骤4,否则任选一个刚刚被标记的点设为,转步骤2,若刚刚没有标记任何点则算法结束。(步骤2由于会执行多次,刚刚表示步骤2最近一次执行时标记的点,即的可被标记的邻点)
步骤4:从汇开始,依次回溯被标记的点,并将两点之间的弧加/减一个汇流量,正向则加,反向则减,回溯到源后,转步骤1。
算法符号描述:
步骤0: 设F是从源s到汇t的任意可行流,对任意,令。//从零流开始。
步骤1: 对源标记为(S表示已标记的顶点集,U未检查的顶点集,初始值为全体顶点。)
步骤2: 对(S的补)中与的所有邻点,有:
(1) 若,则将标记为,其中。
(2) 若,且,则将标记为,其中。
步骤3: 若,转步骤4,否则,令,若,则算法结束,当前流为最大流;否则若,任选,转步骤2。(实际上,S∩U就是步骤2中刚刚被标记的点)
步骤4: 令。
步骤5: 若的标记为,则;
若z的标记为,则。
步骤6: 若,则取消所有点的标号,转步骤1,否则,令,转步骤5。
标记的意义:表示点经流量为的正向弧到达点
表示点经流量为的反向弧到达点
符号描述可能不好理解,对照文字描述理解。
例子:(编辑太麻烦了,从word截的图)
欢迎讨论