《算法导论3rd第二十六章》最大流

前言

最短路径解决的是一个成本问题。而生活中一些问题需要考虑更多的因素,如通讯中的“带宽”;物流中的“路宽”…。我们把这类问题,归结为“网络流” 问题。 即如 容量限制。即把这物流方面的问题,称为“流网络”。网络流,它分为两部分:网络和流。

  • 网络,其实就是一张有向图,其上的边权称为容量。额外地,它拥有一个源点和汇点。
  • 流,顾名思义,就像水流或电流,也具有它们的性质。如果把网络想象成一个自来水管道网络,那流就是其中流动的水。每条边上的流不能超过它的容量,并且对于除了源点和汇点外的所有点(即中继点),流入的流量都等于流出的流量。

网络流

一个带权有向图 G = ( V , E ) G=(V,E) G=(V,E),其中 V是图中所有点的集合, E是所有边的集合,且每一条边都有其流量上限

这个带权有向图中有两个特殊的点:源(source)节点 s 和汇(sink)节点 t,且这两个点满足 s , t ∈ V , s ≠ t s,t\in V, s\ne t s,tV,s=t。从 s 到 t 的流函数 f将这个有向图中的每条边 e 映射到一个非负实数,即 f(e) 表示边 e所承载的流量。

作为流网络,这个带权有向图需要满足两个条件:

  • 容量条件,流网络中任意边上的流量不超过流网络的容量,即对于任意边 e ∈ E e\in E eE ,有 0 ⪯ f ( e ) ≤ c e 0\preceq f(e)\leq c_{e} 0f(e)ce
  • 守恒条件,对于非源节点和汇节点的任意内部节点 e ,流入该结点的流量之和等于流出该结点的流量之和,即 ∑ i n f ( e ) = ∑ o u t f ( e ) \sum_{in}^{ }{f(e)}=\sum_{out}^{ }{f(e)} inf(e)=outf(e)

最大流问题就是求解源节点和汇节点之间的最大流量

反平行边的问题

在这里插入图片描述

多个源点和多个汇点的网络

在这里插入图片描述

Ford-Fulkersion方法

之所以称其为“方法”,而不是“算法”。是因为它包含了几种运行时间各不相同的具体实现。Ford-Fulkersion方法主要依赖于三种重要的思想:残存网络,增广路径和切割。

残存网络

对于给定流 f, G f G_f Gf是流网络 G = ( V , E ) G =(V,E) G=(V,E)中所有结点和残存容量 c f c_f cf大于0的边所构成的子图,即:
c f ( u , v ) = c ( u , v ) − f ( u , v ) c_f(u,v) = c(u,v) - f(u,v) cf(u,v)=c(u,v)f(u,v)
G f = ( V f = V , E f = { ( u , v ) ∈ E : c f ( u , v ) > 0 } G_f = (V_f = V, E_f = \{(u,v) \in E : c_f(u,v) \gt 0 \} Gf=(Vf=V,Ef={(u,v)E:cf(u,v)>0}

残存容量 c f c_f cf, 表示的是这条边容量与流量的**差值.**即此边还可以通行的流量

需要注意的是,残存网络 G f G_f Gf还可能包含图 G中不存在的边。算法对流量进行操作的目标是增加总流量,为此,算法可能对某些特定边上流量进行缩减。为了表示对一个正流量 f ( u , v ) f(u,v) f(u,v)的缩减,我们将边 ( u , v ) (u,v) (u,v)加入到图 G f G_f Gf中,并将其残存容量设置为 c f ( v , u ) = f ( u , v ) c_f(v,u) = f(u,v) cf(v,u)=f(u,v)。也就是说,一条边所能允许的反向流量最多将其正向流量抵消。

也就是,对于一个流网络 G = ( V , E ) G=(V,E) G=(V,E),设f为图 G中的一个流,考虑对于结点对 u , v ∈ E u,v \in E u,vE,残存容量 c f ( u , v ) c_f(u,v) cf(u,v)的值为下列三种情况之一:

c f ( u , v ) = { c ( u , v ) − f ( u , v ) if  ( u , v ) ∈ E f ( v , u ) if  ( v , u ) ∈ E 0 other  c_f(u,v) = \begin{cases} c(u,v)-f(u,v) &\text{if } (u,v) \in E \\ f(v,u) &\text{if } (v,u) \in E \\ 0 &\text{other } \end{cases} cf(u,v)=c(u,v)f(u,v)f(v,u)0if (u,v)Eif (v,u)Eother 

举个例子,下图中,a 为流网络G,b 为流网络上G的一个流 f,c 为f引导出的残存网络 G f G_f Gf
在这里插入图片描述
以图中 ( s , v 1 ) (s, v_1) (s,v1)这条边为例,

  1. 流网络G中该边的容量为16,
  2. 在流f中该边的流为 11,则还可以对 f ( s , v 1 ) f(s, v_1) f(s,v1) 增加的量最大为 5,再多就将超过边 ( s , v 1 ) (s, v_1) (s,v1)的容量限制。
  3. 同时,从结点 v 1 v_1 v1向结点s最多可以返回 11个单位的流量,也就是从s到 v 1 v_1 v1最多可以缩减11 个单位,因此, c f ( v , u ) = 11 c_f(v,u) = 11 cf(v,u)=11
增广路径

给定流网络 G = ( V , E ) G=(V,E) G=(V,E)和流 f ,增广路径 p 是残存网络 G f G_f Gf中从源结点s到汇点 t到简单路径。根据残存网络到定义,对于一条增广路径上的边 ( u , v ) (u,v) (u,v),我们可以增加其流量的幅度最大为 c f ( u , v ) c_f(u,v) cf(u,v),而不会违反原始流网络G中对边 ( u , v ) (u,v) (u,v) ( v , u ) (v,u) (v,u)的容量限制。
在这里插入图片描述
增广路径p 上能够为每条边增加的流量的最大值为增广路径p 的残存容量,即:
c f ( p ) = m i n { c f ( u , v ) : ( u , v ) ∈ P } c_f(p) = min\{c_f(u,v):(u,v) \in P \} cf(p)=min{cf(u,v):(u,v)P}

流网络的切割

流网络 G = ( V , E ) G=(V,E) G=(V,E)中的一个切割 ( S , T ) (S,T) (S,T) 将结点集合V 划分为 S 和 T= V-S两个集合,使得 s ∈ S , t ∈ T s \in S,t \in T sStT

  • 净流量:若f是一个流,则定义横跨切割 ( S , T ) (S,T) (S,T) 的净流量 f ( S , T ) f(S,T) f(S,T)为: f ( S , T ) = ∑ u ∈ S ∑ v ∈ T f ( u , v ) − ∑ u ∈ S ∑ v ∈ T f ( v , u ) f(S,T) = \sum_{u \in S} \sum_{v \in T} f(u,v) - \sum_{u \in S} \sum_{v \in T} f(v,u) f(S,T)=uSvTf(u,v)uSvTf(v,u)

  • 割的容量:切割 ( S , T ) (S,T) (S,T)的容量为所有从S到 T 的边的容量之和,即:
    c ( S , T ) = ∑ u ∈ S ∑ v ∈ T c ( u , v ) c(S,T) = \sum_{u \in S} \sum_{v \in T} c(u,v) c(S,T)=uSvTc(u,v)

  • 最小切割:整个网络中容量 c ( S , T ) c(S,T) c(S,T)最小的切割。

在这里插入图片描述
上图表示流网络的一个切割 ( { s , v 1 , v 4 } , { v 2 , v 3 , t } ) (\{s, v_1, v_4 \},\{ v_2, v_3, t \}) ({s,v1,v4},{v2,v3,t}):

  • 净流量: f ( v 1 , v 2 ) + f ( v 4 , v 3 ) − f ( v 2 , v 4 ) = 12 + 11 − 4 = 9 f(v_1, v_2) + f(v_4, v_3)-f(v_2, v_4) = 12 +11 -4 = 9 f(v1,v2)+f(v4,v3)f(v2,v4)=12+114=9
  • 割的容量: c ( v 1 , v 2 ) + c ( v 4 , v 3 ) = 12 + 14 = 26 c(v_1, v_2) + c(v_4, v_3)= 12 +14 = 26 c(v1,v2)+c(v4,v3)=12+14=26
最大流最小割定理

设 f是流网络 G = ( V , E ) G=(V,E) G=(V,E)中的一个流,该流网络的源结点为 s ,汇点为 t,则下面的条件是等价的:

  1. f 是 G 的一个最大流。
  2. 残存网络 G f G_f Gf不包括任何增广路径。
  3. 净流量 ∣ f ∣ = c ( S , T ) |f|=c(S,T) f=c(S,T),其中 ( S , T ) (S,T) (S,T)是流网络G的某个切割。
基本的Ford-Fulkerson的实现

在Ford-Fulkerson方法的每次迭代中,寻找某条增广路径p,然后使用p 来对流 f来进行修改,从而获得一个值为 ∣ f ∣ + ∣ f p ∣ |f| + |f_p| f+fp 的更大的流。

我们为每条边 ( u , v ) ∈ E (u,v) \in E (u,v)E, 容量为 c ( u , v ) c(u,v) c(u,v), 更新流属性 ( u , v ) . f (u,v).f (u,v).f 来计算流网络 G = ( V , E ) G=(V,E) G=(V,E)中的最大流。

  • 如果边 ( u , v ) ∉ E (u,v) \notin E (u,v)/E,则设 ( u , v ) . f = 0 (u,v).f = 0 (u,v).f=0
  • 如果边 ( u , v ) ∉ E (u,v) \notin E (u,v)/E,则 c ( u , v ) = 0 c(u,v)=0 c(u,v)=0

根据上述公式计算残存容量 c f ( u , v ) c_f(u,v) cf(u,v)

FORD-FULKERSON(G, s, t)
  for each edge(u,v) in G.E
    (u, v).f = 0
  while there exit a path p from s to t in the residual network Gf
    cf(p) = min{cf(u,v) : (u,v) is in p}
    for each edge(u,v) in p
      if(u,v) in G.E
        (u,v).f = (u,v).f + cf(p)
      else (u,v).f = (v,u).f - cf(p)

在这里插入图片描述

算法重复在残存网络 G f G_f Gf中寻找一条增广路径 p ,然后使用残存容量 c f ( p ) c_f(p) cf(p)来对路径 p上的流 f进行增加。路径p上的每条残存边要么是原来网络中的一条边,要么是原来网络中的一条反向边。算法根据这两种情况进行相应的更新:如果是原来网络中的一条边,则增加流,否则缩减流。当不在有增广路径时,流f 就是最大流。

最大二分匹配

在一群人中,有一些人可以俩俩友好的共住一个房间,在什么条件下,可以将所有这群人俩俩配对,安排它们共住一套房屋呢?类似问题在生活中很常见,比如如说男女配对问题。

图表示

G = ( V , E ) G=(V,E) G=(V,E) 的一个 匹配 是由一组没有公共端点的不是圈的边构成的集合。换句话说,也就是,一组俩俩没有公共结点的边集称为图 G 的匹配。可以看出匹配是图边E的一个子集 M ⊆ E M \subseteq E ME。其中匹配中的边称为 匹配边,反之称为 未匹配边
在这里插入图片描述
二分图中,结点集合可以划分为 V = L ∪ R V = L \cup R V=LR,其中 L 和 R是不相交的,并且边的集合 E中所有边都横跨 L 和 R。

一个匹配是由若干条边构成,故其大小就是边的数量( ∣ M ∣ |M| M)。最大匹配顾名思义就是大小最大的匹配。

寻找最大二分匹配

将二分图 G = ( V , E ) G=(V,E) G=(V,E) 转为对应的流网络 G ′ = ( V ′ , E ′ ) G'=(V',E') G=(V,E),给 E ′ E' E 中的每条边赋予单位容量
在这里插入图片描述
二分图 G 的一个最大匹配对应于流网络 G ′ G' G中的一个最大流,因此可以通过在对应流网络 G ′ G' G上运行一个最大流算法(EK)来计算图G的最大匹配。

主要参考

流网络,流和增广路算法基础
详解最大流问题和Ford-Fulkerson算法
最大二分匹配
Maximum Flow

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值