标号法求最大流

图论中网络的相关概念见上篇博客

算法基本思想:
从某个初始流开始,重复地增加流的值到不能再改进为止,则最后所得的流将是一个最大流。为此,不妨将每条边上的流量设置为0作为初始流量。为了增加给定流量的值,我们必须找出从发点到收点的一条路并沿这条路增加流量。

当前流为最大流的充要条件:网络中不存在增广路
最大流最小截定理:在任何网络中,最大流的流量等于最小截集的容量。
整数流定理:在任何网络中,如果网络所有的弧容量都是整数,则存在整数最大流。

明确一点:最大流是指网络中流的值达到最大,即源的出流量或汇的入流量达到最大,每段弧都有对应的流量,而不是求网络中某个路径的流量。

把最大流算法想象成两个运输站之间运货,两个运输站之间有很多个中转站,每个中转站都有一个最大容量,站与站之间运货都有不同的运货量,而且中转站不会留货物,所以货物的总量一定等于源站的出货数或者汇站的进货数。最大流算法就是在不超过所有中转站的容量的情况下,求最大出货量/进货量以及所有中转站之间的运货量。
如下图所示,左边是容量,右边是流量,在如图所示的流中,流的值达到了最大,为13,也不存在增广路,所谓增广路就是一条从源到汇的路径,路径上的所有弧非饱和(正向)或非空(反向),即一条仍能增加流量的路。
最大流算法 - 标号法
为什么说增广路是一条仍能增加流量的路?其实不难理解,增广路的定义如上文,路径上的所有弧非饱和(正向)或非空(反向),反向弧的流量假设为n,实际上等价于为正向弧的流量为-n,因为n不能小于0,所以n=0的时候,反向弧的流量虽然达到了最小,但是把他当做正向弧的时候,流量却达到了最大。
对于一条路径而言,非饱和弧和非空弧都意味着该条路径的流量没有达到饱和。既然网络中存在一条没有达到饱和的路径,那么网络的流也没有达到最大。这就是当前流为最大流的充要条件,可用数学语言证明。

算法文字描述:
步骤0:将网络中所有弧流量全部置0
步骤1:将源的点流量设为无穷大,令u=s。
步骤2:标记 点vi=uv_i=u的所有未被标记的邻点vjv_j的点流量(BFS)。
标记方法:若u到邻点是正向弧,且流量小于容量,则点流量Δ(vj)Δ(v_j)取前点流量Δ(vi)Δ(v_i)和弧的容流量差值CijFijC_{ij}-F_{ij}的较小者
若是反向弧连接,且流量大于0,则点流量Δ(vj)Δ(v_j)取前点流量Δ(vi)Δ(v_i)和弧流量FijF_{ij}的较小者
步骤3:若标记到了汇则转步骤4,否则任选一个刚刚被标记的点设为uu,转步骤2,若刚刚没有标记任何点则算法结束。(步骤2由于会执行多次,刚刚表示步骤2最近一次执行时标记的点,viv_i的可被标记的邻点
步骤4:从汇开始,依次回溯被标记的点,并将两点之间的弧加/减一个汇流量Δ(t)Δ(t),正向则加,反向则减,回溯到源后,转步骤1。

算法符号描述:
步骤0: 设F是从源s到汇t的任意可行流,对任意<μ,v>=<vi,vj>E<μ,v>=<v_i,v_j>∈E,令Fij=0F_{ij}=0。//从零流开始。
步骤1: 对源s=v0s=v_0标记为(s,+,Δ(s)=)S=sU=vj,j=0,1,2,,nμ=vi=s(s,+,Δ(s)=∞),S={s},U={v_j},j=0,1,2,⋯,n;μ=v_i=s。(S表示已标记的顶点集,U未检查的顶点集,初始值为全体顶点。)
步骤2:S¯(S的补)中与μ=viμ=v_i的所有邻点vjv_j,有:
(1) 若<vi,vj>EFij<Cij<v_i,v_j>∈E,且F_{ij}<C_{ij},则将vjv_j标记为(vi,+,Δ(vj))(v_i,+,Δ(v_j)),其中Δ(vj)=minΔ(vi),CijFijS=SvjΔ(v_j)=min⁡{Δ(v_i),C_{ij}-F_{ij}},S=S∪{v_j}
(2) 若<vj,vi>E<v_j,v_i>∈E,且Fij>0F_{ij}>0,则将vjv_j标记为(vi,,Δ(vj))(v_i,-,Δ(v_j)),其中Δ(vj)=minΔ(vi),FijS=SvjΔ(v_j)=min⁡{Δ(v_i),F_{ij}},S=S∪{v_j}
步骤3:vj=tSv_j=t∈S,转步骤4,否则vjtv_j≠t,令U=UviU=U-{v_i},若SU=φS∩U=φ,则算法结束,当前流为最大流;否则若SUφS∩U≠φ,任选viSUv_i∈S∩U,转步骤2。(实际上,S∩U就是步骤2中刚刚被标记的点)
步骤4:z=tz=t
步骤5:zz的标记为(g,+,Δ(z))(g,+,Δ(z)),则F(<g,z>)=F(<g,z>)+Δ(z)F(<g,z>)=F(<g,z>)+Δ(z)
若z的标记为(g,,Δ(z))(g,-,Δ(z)),则F(<z,g>)=F(<z,g>)Δ(z)F(<z,g>)=F(<z,g>)-Δ(z)
步骤6:g=sg=s,则取消所有点的标号,转步骤1,否则,令z=gz=g,转步骤5。
标记的意义:(vi,+,Δ(vj))(v_i,+,Δ(v_j ))表示点viv_i经流量为Δ(vj)Δ(v_j)的正向弧到达点vjv_j
(vi,,Δ(vj))(v_i,-,Δ(v_j ))表示点viv_i经流量为Δ(vj)Δ(v_j)的反向弧到达点vjv_j

符号描述可能不好理解,对照文字描述理解。

例子:(编辑太麻烦了,从word截的图)
最大流算法 - 标号法
最大流算法 - 标号法
最大流算法 - 标号法最大流算法 - 标号法
欢迎讨论

相关文章:

  • 2021-10-23
  • 2021-09-26
  • 2022-01-04
  • 2022-01-13
  • 2021-12-05
  • 2022-12-23
猜你喜欢
  • 2021-07-17
  • 2022-12-23
  • 2021-12-30
  • 2022-01-14
  • 2022-12-23
  • 2021-09-28
  • 2021-11-17
相关资源
相似解决方案