文章目录

  • 26.1 流网络
    • 1. 流网络和流
    • 2. 流的一个例子
    • 3. 使用反平行边来建模问题
    • 4. 具有多个源点和多个汇点的网络
  • 26.2 *Ford-Fulkerson* 方法
    • 1. 残存网络
    • 2. 增广路径
    • 3. 流网络的切割
    • 3. 基本的 *Ford-Fulkerson* 算法
    • 4. `FORD-FUKLERSON` 算法的分析
    • 5. *Edmonds-Karp* 算法

我们可通过模型化道路交通图为一个有向图、找到从一个城市到另一个城市之间的最短路径,我们也可以将一个有向图看作是一个流网络 flow network 、并使用它来回答关于物料流动方面的问题。设想一种物料从产生它的源结点、经过一个系统、流向消耗该物料的汇点这样一个过程,源结点以某种稳定的速率产生物料,汇点则以同样的速率消耗物料。从直观上看,物料在系统中任何一个点上的“流量”就是物料移动的速率。这种流网络可以用来建模很多实际问题,包括液体在管道中的流动、装配线上部件的流动、电网中电流的流动、通信网络中信息的流动。

我们可以把流网络中每条有向边看作是物料的一个流通通道,每条通道有限定的容量,是物料流经该通道时的最大速率,如一条管道每小时可以流过 200200200 加仑的液体、或一根电线可以经受 202020 安培的电流。流网络中的结点则是通道的连接点,除了源结点和终结点外,物料在其他结点上只是流过,并不积累或聚集。换句话说,物料进入一个结点的速率、必须与其离开该结点的速率相等,这一性质称为流量守恒(这里的流量守恒与 Kirchhoff 电流定律等价)。

在最大流问题中,希望在不违反任何容量限制的情况下,计算出从源结点运送物料到汇点的最大速率。这是与流网络有关的所有问题中最简单的问题之一(???),而且最大流算法中的一些基本技巧,可以用来解决其他网络流问题。下面介绍两种解决最大流问题的一般方法。

(算法导论第26章中)将看到,这个问题可以用高效的算法解决。(算导26.1节)先给出流网络、流概念、以及最大流问题的形式化定义,(算导26.2节)再描述 FordFulkerson 提出的解决最大流问题的经典方法,(算导26.3节)给出该方法的一种实际应用:在无向二分图(二分图)中找出最大匹配。(算导26.4节)阐述重要的推送-重贴标签方法,该方法是许多网络流算法的快速算法的基石,(算导26.5节)则讨论推送-重贴标签方法的一种具体实现——前置重贴标签算法,该算法的运行时间为 O(V3)O(V^3)O(V3) ,虽然该算法并不是已知算法中最快的,但它演示了渐进最快算法中用到的某些技巧,并且在实际应用中也是非常有效的。


26.1 流网络

本节给出流网络的图论定义,讨论其性质,并精确地定义最大流问题。同时还引入一些有用的记号。

1. 流网络和流

流网络 flow network G=(V,E)G = (V, E)G=(V,E) 是一个有向图,图中每条边 (u,v)∈E(u, v) \in E(u,v)∈E 有一个非负的容量值 nonnegative capacity c(u,v)≥0c(u, v) \ge 0c(u,v)≥0 。我们进一步要求,如果边集合 EEE 包含一条边 (u,v)(u, v)(u,v) ,则图中不存在反方向的边 (v,u)(v, u)(v,u)(随后我们将看到,在这个限制下如何做)。如果 (u,v)∉E(u, v) \notin E(u,v)∈/​E ,则为方便起见,我们定义 c(u,v)=0c(u, v) = 0c(u,v)=0 ,并且在图中不允许自环 self-loops

在流网络中的所有结点中,我们特别分辨出两个特殊结点:源点 source sss 和汇点 sink ttt 。为方便起见,假设每个结点都在从源点到汇点的某条路径上 we assume that each vertex lies on some path from the source to the sink 。也就是说,对于每个结点 v∈Vv \in Vv∈V ,流网络都包含一条路径 s⇝v⇝ts \leadsto v \leadsto ts⇝v⇝t 。因此,流网络图是连通的,并且由于除源结点外的每个结点,都至少有一条进入的边,我们有 ∣E∣≥∣V∣−1|E| \ge |V| - 1∣E∣≥∣V∣−1 。图26-1描述的是一个流网络的例子。

现在可以给出流的形式化定义。设 G=(V,E)G= (V, E)G=(V,E) 为一个流网络,其容量函数为 ccc 。设 sss 为网络的源结点,ttt 为汇点。GGG 中的是一个实值函数 f:V×V→Rf: V \times V \to \Rf:V×V→R ,满足下面的两条性质:

  • 容量限制:对于所有的结点 u,v∈Vu, v \in Vu,v∈V ,要求 0≤f(u,v)≤c(u,v)0 \le f(u, v) \le c(u, v)0≤f(u,v)≤c(u,v) 。
  • 流量守恒:对于所有的结点 u∈V−{s,t}u \in V - \{ s, t\}u∈V−{s,t} ,要求 ∑v∈Vf(v,u)=∑v∈Vf(u,v)\sum_{v \in V} f(v, u) = \sum_{v \in V} f(u, v)v∈V∑​f(v,u)=v∈V∑​f(u,v) 当 (u,v)≠E(u, v) \ne E(u,v)​=E 时,从结点 uuu 到结点 vvv 之间没有流量,因此 f(u,v)=0f(u, v)= 0f(u,v)=0 。

我们称非负数值 f(u,v)f(u, v)f(u,v) 为从结点 uuu 到结点 vvv 的流量。一个流 fff 的值 ∣f∣|f|∣f∣ 定义如下:
∣f∣=∑v∈Vf(s,v)−∑v∈Vf(v,s)(26.1)|f| = \sum_{v \in V} f(s, v) - \sum_{v \in V} f(v, s) \tag{26.1}∣f∣=v∈V∑​f(s,v)−v∈V∑​f(v,s)(26.1) 即,流 fff 的值是从源结点流出的总流量减去流入源结点的总流量 the total flow out of the source minus the flow into the source(这里,符号 ∣∣\mid\ {} \mid∣ ∣ 表示流的值,而不是绝对值或基数值)。通常来说,一个流网络不会有任何进入源结点的边,因此公式(26.1)中的求和项 ∑v∈Vf(v,s)=0\displaystyle \sum_{v\in V} f(v, s) = 0v∈V∑​f(v,s)=0 。我们将其囊括在该公式里的原因是后面将要讨论残存网络,在此种网络中,流入源结点的流量十分重要。在最大流问题中,给定一个流网络 GGG 、一个源结点 sss 、一个汇点 ttt ,我们希望找到值最大的一个流。

在查看任何网络流问题的例子前,我们简略地对流的定义和流的两种性质进行探讨。

  • 容量限制性质说明,从一个结点到另一个结点之间的流,必须为非负值、且不能超过给定的容量限额。
  • 流量守恒性质说明,流入一个结点(指非源结点和非汇点)的总流量,必须等于流出该结点的总流量,非形式化地称为流入等于流出

2. 流的一个例子

用流网络把图26-1(a)所示的货运问题模型化。Lucky冰球公司在温哥华有一家制造冰球的工厂(源结点 sss ),在温尼伯有一个存储物品的仓库(汇点 ttt )。Lucky冰球公司从另一家公司租用货车来将冰球从工厂运送到仓库。因为货车按指定路线(边)在城市(结点)间行驶、且其容量有限,Lucky冰球公司在图26-1(a)所示的、每对城市 u,vu, vu,v 之间每天至多运送 c(u,v)c(u, v)c(u,v) 箱产品。Lucky冰球公司无权控制运输路线和货车的运输能力,因此无法改变图26-1(a)所示的流网络。他们所能做的事情是,判断每天可以运送的最大货箱数 ppp ,并按这一数量进行生产,因为生产出来的产品多于其运输能力没有什么意义。Lucky冰球公司并不关心一个给定的冰球需要多长时间、才能从工厂运送到仓库;他们关心的只是每天可以有 ppp 箱货物离开工厂,每天可以有 ppp 箱货物到达仓库。

由于从一个城市运送到另一个城市的货箱数量,每天都有容量限制,因此可以在这个网络中用流来模拟这种运输“流”。此外,我们的模型必须遵守流量守恒性质,因为在一种稳定的状态下,冰球进入一个中间城市的速率、必须等于冰球离开该城市的速率。否则,货箱将在中间城市堆积起来。

3. 使用反平行边来建模问题

假定从埃德蒙顿到卡尔加里,货运公司提供给Lucky冰球公司 101010 个货箱。自然地,要将该容量加入到我们的例子中,从而形成一个如图26-2(a)所示的网络。但是这个网络却有一个问题:它违反了我们原来的假设——如果边 (v1,v2)∈E(v_1,v_2) \in E(v1​,v2​)∈E ,则 (v2,v1)∉E(v_2, v_1) \notin E(v2​,v1​)∈/​E 。我们称边 (v1,v2),(v2,v1)(v_1, v_2),\ (v_2, v_1)(v1​,v2​), (v2​,v1​) 为反平行 antiparallel

因此,如果要使用反平行边来模拟一个流问题,必须将这种网络转换为一个等价的、但不包括反平行边的网络。图26-2(b)描述的就是这样一个等价网络。选择两条反平行边中的一条,在这个具体例子中是 (v1,v2)(v_1, v_2)(v1​,v2​) ,通过加入一个新结点 v′v'v′ 来将其分解为两段,并以边 (v1,v′),(v′,v2)(v_1, v'), (v', v_2)(v1​,v′),(v′,v2​) 来替换边 (v1,v2)(v_1, v_2)(v1​,v2​) 。同时,将两条新设立的边的容量、设置为与原来的边的容量相同。这样得出的网络,将满足我们的限制条件:如果一条边属于该网络,则其反向边不属于该网络。(算导练习26.1-1要求:证明这样转换后的网络与原来的网络等价)

从上面的讨论可以看到,实际生活中的流问题可以自然地表示为一个带反平行边的网络。但如果不允许反平行边则将更为方便。幸运的是,我们有一个非常直接的办法,将一个带有反平行边的网络转换为不带反平行边的网络。

4. 具有多个源点和多个汇点的网络

一个最大流问题可能有几个源结点和几个汇点,而不仅仅只有一个源结点和汇点(违反了假设:每个结点都在从源点到汇点的某条路径上?)。例如,Lucky冰球公司可能有 mmm 家工厂 {s1,s2,…,sm}\{ s_1, s_2, \dots, s_m\}{s1​,s2​,…,sm​} 和 nnn 个仓库 {t1,t2,…,tn}\{ t_1, t_2, \dots, t_n\}{t1​,t2​,…,tn​} ,如图26-3(a)所示。幸运的是,多个源点和多个汇点的最大流问题,并不比普通的最大流问题更难

在具有多个源点和多个汇点的网络中,确定最大流的问题可以归约为一个普通的最大流问题。图26-3(b)描述的是,如何将图26-3(a)所示的网络转换为一个只有一个源点和一个汇点的普通流网络。转换方法是加入一个超级源点 sss ,并对于 i=1,2,…,mi = 1, 2, \dots, mi=1,2,…,m ,加入有向边 (s,si)(s, s_i)(s,si​) 和容量 c(s,si)=∞c(s,s_i) = \infinc(s,si​)=∞ ;同时创建一个新的超级汇点 ttt ,并对于 i=1,2,…,ni = 1, 2, \dots, ni=1,2,…,n ,加入有向边 (ti,t)(t_i, t)(ti​,t) 和容量 c(ti,t)=∞c(t_i, t) = \infinc(ti​,t)=∞ 。从直观上看,图26-3(a)所示网络中的任意流,均对应于图26-3(b)所示网络中的一个流,反之亦然。单源点 sss 能够给原来的多个源点 sis_isi​ 提供所需要的流量,而单汇点 ttt 则可以消费原来所有汇点 tit_iti​ 所消费的流量。(算导练习26.1-2要求:形式化证明这两个问题是等价的)


26.2 Ford-Fulkerson 方法

本节讨论用来解决最大流问题的 Ford-Fulkerson 方法。之所以称其为方法而不是算法,是因为它包含了几种运行时间各不相同的具体实现。Ford-Fulkerson 方法依赖于三种重要思想,它们与许多的流算法和问题有关,如残存网络、增广路径、切割。这些思想是最大流最小割定理(定理26.6)的精髓,该定理以流网络的切割来表述最大流的值。本节末尾给出 Ford-Fulkerson 方法的一种具体实现,并分析其运行时间。

Ford-Fulkerson 方法循环增加流的值。在开始的时候,对于所有的结点 u,v∈V,f(u,v)=0u, v \in V,\ f(u, v) = 0u,v∈V, f(u,v)=0 ,即给出的初始流值为 000 giving an initial flow of value 0 。在每一次迭代中,我们将图 GGG 的流值进行增加,方法就是在一个关联的残存网络 residual network GfG_fGf​ 中寻找一条增广路径 augmenting path 。一旦知道图 GfG_fGf​ 中一条增广路径的边,就可以很容易地辨别出 GGG 中的一些具体的边,我们可以对这些边上的流量进行修改,从而增加流的值。虽然 Ford-Fulkerson 方法的每次迭代都增加流的值,但是对于图 GGG 的一条特定边来说,其流量可能增加、也可能减少;对某些边的流量进行缩减可能是必要的,以便让算法可以将更多的流量从源点发送到汇点。重复对流进行这一过程,直到残存网络中不再存在增广路径为止。最大流最小割定理将说明,在算法终结时,该算法将获得一个最大流

FORD_FULKERSON-METHOD(G, s, t)initialize flow f to 0while there exists an augmenting path p in the residual network Gfaugment flow f along preturn f

为了实现和分析 Ford-Fulkerson 方法,需要引入几个新的概念。

1. 残存网络

从直观上看,给定流网络 GGG 和一个流 fff ,残存网络 GfG_fGf​ 由那些边组成,边的容量表示我们能怎样改变 GGG 边上的流(即由哪些仍有容量对流量进行调整的边构成) given a flow network G and a flow f, the residual network Gf consists of edges with capacities that represent how we can change the flow on edges of G 。流网络的一条边可以允许的额外流量,等于该边的容量减去该边上的流量。如果该差值为正,则将该条边置于图 GfG_fGf​ 中,并将其残存容量设置为 cf(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) 。对于图 GGG 中的边来说,只有能够允许额外流量的边才能加入到图 GfG_fGf​ 中。如果边 (u,v)(u, v)(u,v) 的流量等于其容量,则其 cf(u,v)=0c_f(u, v) = 0cf​(u,v)=0 ,该条边不属于图 GfG_fGf​ 。

残存网络 GfG_fGf​ 还可能包含图 GGG 中不存在的边。然而,算法对流量进行操作的目标是增加总流量,为此算法可能缩减某些特定边上的流量。为了表示对「图 GGG 的一条边上的一个正流量 f(u,v)f(u, v)f(u,v) 」的缩减,我们将边 (v,u)(v, u)(v,u) 加入到图 GfG_fGf​ 中,并将其残存容量设置为 cf(v,u)=f(u,v)c_f(v, u) = f(u, v)cf​(v,u)=f(u,v) 。也就是说,一条边所能允许的反向流量(即在边 (u,v)(u,v)(u,v) 相反方向上)最多将其正向流量(即沿着边 (u,v)(u, v)(u,v) )抵消。残存网络中的这些反向边,允许算法将「沿着一条边已经发送出来的流量」发送回去 These reverse edges in the residual network allow an algorithm to send back flow it has already sent along an edge 。而将流量从同一条边发送回去等同于缩减该条边的流量,这在许多算法中是必要的操作。

更形式化地,假定有一个流网络 G(V,E)G(V, E)G(V,E) ,其源点为 sss 、汇点为 ttt 。设 fff 为图 GGG 中的一个流,考虑结点对 u,v∈Vu, v \in Vu,v∈V ,定义残存容量 residual capacity cf(u,v)c_f(u, v)cf​(u,v) 如下:
cf(u,v)={c(u,v)−f(u,v)若(u,v)∈Ef(v,u)若(v,u)∈E0其他(26.2)c_f(u, v) = \begin{cases} c(u, v) - f(u, v) \quad &若(u, v) \in E \\ f(v, u) \quad &若(v, u) \in E \\ 0 \quad &其他\end{cases} \tag{26.2}cf​(u,v)=⎩⎪⎨⎪⎧​c(u,v)−f(u,v)f(v,u)0​若(u,v)∈E若(v,u)∈E其他​(26.2) 因为假定边 (u,v)∈E(u, v) \in E(u,v)∈E 意味着 (v,u)∉E(v, u)\notin E(v,u)∈/​E(或者 (v,u)∈E(v, u) \in E(v,u)∈E 意味着 (u,v)∉E(u, v) \notin E(u,v)∈/​E ),对于每一对边来说,公式 (26.2)(26.2)(26.2) 中只有一种情况成立。

作为公式 (26.2)(26.2)(26.2) 的一个例子,如果 c(u,v)=16c(u, v) = 16c(u,v)=16 ,并且 f(u,v)=11f(u, v) = 11f(u,v)=11 ,则对 f(u,v)f(u, v)f(u,v) 可以增加的量最大为 cf(u,v)=5c_f(u, v)= 5cf​(u,v)=5 ,再多就将超过边 (u,v)(u, v)(u,v) 的容量限制。同时,允许算法从结点 vvv 向结点 uuu 最多返回 111111 个单位的流量,因此 cf(v,u)=11c_f(v, u)=11cf​(v,u)=11 。

给定一个流网络 G=(V,E)G = (V, E)G=(V,E) 和一个流 fff ,则由 fff 所导出的图 GGG 的残存网络为 Gf=(V,Ef)G_f = (V, E_f)Gf​=(V,Ef​) ,其中 Ef={(u,v)∈V×V∣cf(u,v)>0}(26.3)E_f = \{ (u, v) \in V\times V \mid c_f (u, v) >0 \} \tag{26.3}Ef​={(u,v)∈V×V∣cf​(u,v)>0}(26.3) EfE_fEf​ 中的边要么是 EEE 中原有的边,要么是其反向边,因此有:∣Ef∣≤2∣E∣| E_f | \le 2|E|∣Ef​∣≤2∣E∣ 也就是说,正如在前面所承诺的,残存网络的每条边或残存边 residual edge ,必须允许大于 000 的流量通过。图26-4(a)是图26-1(b)的流网络 GGG 和流 fff 的重新绘制,图26-4(b)描述的是对应的残存网络 GfG_fGf​(图b中未显示残存容量为 000 的边,图c中没有运送流量的边如 (v3,v2)(v_3, v_2)(v3​,v2​) 则只标出了其容量)。

注意,残存网络 GfG_fGf​ 类似于一个容量为 cfc_fcf​ 的流网络,但该网络并不满足我们对流网络的定义,因为它可能包含边 (u,v)(u, v)(u,v) 和它的反向边 (v,u)(v, u)(v,u) 。除了这个区别外,残存网络具有与流网络同样的性质(边上的值都大于等于 000 、有源点和汇点、为连通图、每个结点都在从源点到汇点的某条路径上等)。我们可以在残存网络中定义一个流,它满足流的定义(容量限制、流量守恒),但是针对的是残存网络 GfG_fGf​ 中的容量 cfc_fcf​ 。

残存网络中的一个流给我们指出的是一条路线图:如何在原来的流网络中增加流。如果 fff 是图 GGG 的一个流,f′f'f′ 是对应的残存网络 GfG_fGf​ 中的一个流,定义 f↑f′f \uparrow f'f↑f′ 为流 f′f'f′ 对流 fff 的递增/增广 augmentation ,它是一个从 V×VV \times VV×V 到 R\RR 的函数(是一个新的流),其定义如下:
(f↑f′)(u,v)={f(u,v)+f′(u,v)−f′(v,u)若(u,v)∈E0其他(26.4)(f \uparrow f') (u, v) = \begin{cases} f(u, v) + f'(u, v) - f'(v, u) \quad &若(u, v)\in E \\ 0 \quad &其他\end{cases} \tag{26.4}(f↑f′)(u,v)={f(u,v)+f′(u,v)−f′(v,u)0​若(u,v)∈E其他​(26.4) 该定义背后的直观解释遵循残存网络的定义。因为在残存网络中将流量发送到反向边上,等同于在原来的网络中缩减流量,所以将边 (u,v)(u, v)(u,v) 的流量增加 f′(u,v)f'(u, v)f′(u,v) ,但减少 f′(v,u)f'(v, u)f′(v,u) 。在残存网络中将流量推送回去,也称为抵消操作 cancellation 。例如,如果将 555 货箱的冰球从城市 uuu 发送到城市 vvv ,同时将 222 货箱冰球从城市 vvv 发送到城市 uuu ,那么可以等价(以最后结果来看)地将 333 个货箱从城市 uuu 发送到城市 vvv 、而不从城市 vvv 发送任何货箱到城市 uuu 。这类抵消操作对于任何最大流算法来说都是非常关键的。

引理26.1 设 G=(V,E)G = (V, E)G=(V,E) 为一个流网络,源点为 sss 、汇点为 ttt ,设 fff 为 GGG 中的一个流。设 GfG_fGf​ 为流 fff 所导出的 GGG 的残存网络,f′f'f′ 为 GfG_fGf​ 中的一个流。那么式 (26.4)(26.4)(26.4) 所定义的函数 f↑f′f \uparrow f'f↑f′ 是 GGG 的一个流,其值为 ∣f↑f′∣=∣f∣+∣f′∣| f\uparrow f'| = |f| + | f'|∣f↑f′∣=∣f∣+∣f′∣ 。
证明:首先证明 f↑f′f \uparrow f'f↑f′ 满足对 EEE 中每条边的容量限制性质,以及对每个结点 v∈V−{s,t}v \in V- \{ s , t\}v∈V−{s,t} 的流量守恒限制。

  • 对于容量限制,注意到如果边 (u,v)∈E(u, v) \in E(u,v)∈E ,则 cf(v,u)=f(u,v)c_f(v, u) = f(u, v)cf​(v,u)=f(u,v) 。而且 f′(v,u)≤cf(v,u)=f(u,v)f'(v, u) \le c_f(v, u) = f(u, v)f′(v,u)≤cf​(v,u)=f(u,v) ,因此:(f↑f′)(u,v)=f(u,v)+f′(u,v)−f′(v,u)根据式26.4≥f(u,v)+f′(u,v)−f(u,v)因为f′(v,u)≤f(u,v)=f′(u,v)≥0\begin{aligned} (f\uparrow f')(u, v) &= f(u, v) + f'(u, v) - f'(v, u) \quad &根据式26.4 \\ &\ge f(u, v) + f'(u, v) - f(u, v) \quad &因为f'(v,u) \le f(u,v) \\ &= f'(u, v)\\ &\ge 0\end{aligned}(f↑f′)(u,v)​=f(u,v)+f′(u,v)−f′(v,u)≥f(u,v)+f′(u,v)−f(u,v)=f′(u,v)≥0​根据式26.4因为f′(v,u)≤f(u,v) 此外:(f↑f′)(u,v)=f(u,v)+f′(u,v)−f′(v,u)根据式26.4≤f(u,v)+f′(u,v)因为流量为非负值即f′(v,u)≥0≤f(u,v)+cf(u,v)容量限制=f(u,v)+c(u,v)−f(u,v)根据cf的定义=c(u,v)\begin{aligned} (f\uparrow f')(u, v) &= f(u, v) + f'(u, v) - f'(v, u) \quad &根据式26.4 \\ &\le f(u, v) + f'(u, v) \quad &因为流量为非负值即f'(v,u) \ge 0 \\ &\le f(u, v) + c_f(u, v) &容量限制 \\ &=f(u, v) + c(u, v) - f(u, v) \quad &根据c_f的定义 \\ &= c(u, v) \end{aligned}(f↑f′)(u,v)​=f(u,v)+f′(u,v)−f′(v,u)≤f(u,v)+f′(u,v)≤f(u,v)+cf​(u,v)=f(u,v)+c(u,v)−f(u,v)=c(u,v)​根据式26.4因为流量为非负值即f′(v,u)≥0容量限制根据cf​的定义​

  • 对于流量守恒性质,因为 f,f′f, f'f,f′ 均遵守流量守恒性质,对于所有的结点 u∈V−{s,t}u \in V - \{ s, t\}u∈V−{s,t} ,我们有:
    ∑v∈V(f↑f′)(u,v)=∑v∈V[f(u,v)+f′(u,v)−f′(v,u)]根据式26.4=∑v∈Vf(u,v)+∑v∈Vf′(u,v)−∑v∈Vf′(v,u)=∑v∈Vf(v,u)+∑v∈Vf′(v,u)−∑v∈Vf′(u,v)根据流量守恒=∑v∈V(f(v,u)+f′(v,u)−f′(u,v))=∑v∈V(f↑f′)(v,u)根据(f↑f′)定义\begin{aligned} \sum_{v \in V} (f\uparrow f')(u, v) &= \sum_{v\in V}\ [f(u, v) + f'(u, v) - f'(v, u) ] \quad 根据式26.4 \\ &= \sum_{v \in V} f(u, v) + \sum_{v \in V}f'(u, v) - \sum_{v \in V}f'(v, u) \\ &= \sum_{v \in V} f(v, u) + \sum_{v \in V} f'(v, u) - \sum_{v \in V} f'(u, v) \quad &根据流量守恒\\ &=\sum_{v \in V} (f(v, u) + f'(v, u) - f'(u, v)) \\ &= \sum_{v \in V} (f \uparrow f')(v, u) \quad &根据(f\uparrow f')定义 \end{aligned}v∈V∑​(f↑f′)(u,v)​=v∈V∑​ [f(u,v)+f′(u,v)−f′(v,u)]根据式26.4=v∈V∑​f(u,v)+v∈V∑​f′(u,v)−v∈V∑​f′(v,u)=v∈V∑​f(v,u)+v∈V∑​f′(v,u)−v∈V∑​f′(u,v)=v∈V∑​(f(v,u)+f′(v,u)−f′(u,v))=v∈V∑​(f↑f′)(v,u)​根据流量守恒根据(f↑f′)定义​
    因为流量守恒,所以上面的第 222 行推导出了第 333 行。

  • 最后,计算 f↑f′f \uparrow f'f↑f′ 的值。回忆前面讨论过的内容,我们不允许图 GGG 中包含反平行边(但不禁止图 GfG_fGf​ 中有这种边),因此对于每个结点 v∈Vv \in Vv∈V ,可以有边 (s,v)(s, v)(s,v) 或者 (v,s)(v, s)(v,s) ,但不能二者同时存在 for each vertex v in V , we know that there can be an edge (s, v) or (v, s), but never both 。定义 V1={v∣(s,v)∈E}V_1 = \{ v\mid (s, v) \in E\}V1​={v∣(s,v)∈E} 为「有边从源点 sss 到达的结点集合」,V2={v∣(v,s)∈E}V_2 = \{ v \mid (v, s) \in E \}V2​={v∣(v,s)∈E} 为有边通往 sss 的结点集合。我们有 V1∪V2⊆VV_1 \cup V_2 \subseteq VV1​∪V2​⊆V ,并且因为不允许有反平行边,我们有 V1∩V2=∅V_1 \cap V_2 = \varnothingV1​∩V2​=∅ 。现在来计算:
    ∣f↑f′∣=∑v∈V(f↑f′)(s,v)−∑v∈V(f↑f′)(v,s)=∑v∈V1(f↑f′)(s,v)−∑v∈V2(f↑f′)(v,s)(26.5)|f \uparrow f' | = \sum_{v \in V} (f \uparrow f') (s, v) - \sum_{v \in V} (f \uparrow f') (v, s) \\ = \sum_{v\in V_1} (f \uparrow f') (s, v) - \sum_{v \in V_2} (f \uparrow f') (v, s) \tag{26.5}∣f↑f′∣=v∈V∑​(f↑f′)(s,v)−v∈V∑​(f↑f′)(v,s)=v∈V1​∑​(f↑f′)(s,v)−v∈V2​∑​(f↑f′)(v,s)(26.5) 这里的第 222 行成立是因为 (f↑f′)(w,x)(f \uparrow f')(w, x)(f↑f′)(w,x) 的值在 (w,x)∉E(w, x) \notin E(w,x)∈/​E 时为 000 。现在将 f↑f′f\uparrow f'f↑f′ 的定义应用到式 (26.5)(26.5)(26.5) 上,然后对和值项进行重新排序与重组可以获得:
    ∣f↑f′∣=∑v∈V1(f(s,v)+f′(s,v)−f′(v,s))−∑v∈V2(f(v,s)+f′(v,s)−f′(s,v))=∑v∈V1f(s,v)+∑v∈V1f′(s,v)−∑v∈V1f′(v,s)−∑v∈V2f(v,s)−∑v∈V2f′(v,s)+∑v∈V2f′(s,v)=∑v∈V1f(s,v)−∑v∈V2f(v,s)+∑v∈V1f′(s,v)+∑v∈V2f′(s,v)−∑v∈V1f′(v,s)−∑v∈V2f′(v,s)=∑v∈V1f(s,v)−∑v∈V2f(v,s)+∑v∈V1∪V2f′(s,v)−∑v∈V1∪V2f′(v,s)(26.6)\begin{aligned}| f \uparrow f' | &= \sum_{v \in V_1} (f(s, v) + f'(s, v) - f'(v, s)) - \sum_{v \in V_2 } (f (v, s) +f'(v, s) - f'(s, v)) \\ &= \sum_{v \in V_1} f(s, v) + \sum_{v \in V_1} f'(s, v) - \sum_{v \in V_1} f'(v, s) \\ {}&\quad - \sum_{v \in V_2}f(v, s) - \sum_{v \in V_2} f'(v,s) + \sum_{v \in V_2} f'(s, v) \\ &= \sum_{v \in V_1}f(s, v) - \sum_{v \in V_2} f(v, s) \\ {}& \quad + \sum_{v\in V_1} f'(s, v) + \sum_{v \in V_2} f'(s, v) - \sum_{v \in V_1} f'(v, s) - \sum_{v \in V_2} f'(v, s) \\ &=\sum_{v \in V_1}f(s, v) - \sum_{v \in V_2} f(v, s) + \sum_{v \in V_1 \cup V_2}f'(s, v) - \sum_{v \in V_1 \cup V_2}f'(v, s) \end{aligned} \tag{26.6}∣f↑f′∣​=v∈V1​∑​(f(s,v)+f′(s,v)−f′(v,s))−v∈V2​∑​(f(v,s)+f′(v,s)−f′(s,v))=v∈V1​∑​f(s,v)+v∈V1​∑​f′(s,v)−v∈V1​∑​f′(v,s)−v∈V2​∑​f(v,s)−v∈V2​∑​f′(v,s)+v∈V2​∑​f′(s,v)=v∈V1​∑​f(s,v)−v∈V2​∑​f(v,s)+v∈V1​∑​f′(s,v)+v∈V2​∑​f′(s,v)−v∈V1​∑​f′(v,s)−v∈V2​∑​f′(v,s)=v∈V1​∑​f(s,v)−v∈V2​∑​f(v,s)+v∈V1​∪V2​∑​f′(s,v)−v∈V1​∪V2​∑​f′(v,s)​(26.6) 在式 (26.6)(26.6)(26.6) 中,可以将四个求和项的范围都扩展到整个结点集合 VVV 上,因为每个额外的项的值都为 000(算导26.2-1要求证明这一点)。因此有:
    ∣f↑f′∣=∑v∈Vf(s,v)−∑v∈Vf(v,s)+∑v∈Vf′(s,v)−∑v∈Vf′(v,s)=∣f∣+∣f′∣(26.7)|f \uparrow f'| = \sum_{v \in V} f(s, v) - \sum_{v \in V} f(v, s) + \sum_{v \in V}f'(s, v) - \sum_{v \in V} f'(v, s) \\ = |f| + |f'| \tag{26.7}∣f↑f′∣=v∈V∑​f(s,v)−v∈V∑​f(v,s)+v∈V∑​f′(s,v)−v∈V∑​f′(v,s)=∣f∣+∣f′∣(26.7)

2. 增广路径

给定路网络 G=(V,E)G= (V, E)G=(V,E) 和流 fff ,增广路径 ppp 是残存网络 GfG_fGf​ 中一条从源点 sss 到汇点 ttt 的简单路径。根据残存网络的定义,对于一条增广路径上的边 (u,v)(u, v)(u,v) ,我们可以增加其流量的限度最大到 cf(u,v)c_f(u, v)cf​(u,v) ,而不会违反原始流网络 GGG 中对边 (u,v)(u, v)(u,v) 或 (v,u)(v, u)(v,u) 的容量限制。

图26-4(b)中阴影覆盖的路径是一条增广路径。如果将图中的残存网络 GfG_fGf​ 看做一个流网络,那么可以对这条路径上每条边的流量增加 444 个单位,而不会违反容量限制,因为该条路径上最小的残存容量是 cf(v2,v3)=4c_f(v_2, v_3) = 4cf​(v2​,v3​)=4 。我们称在一条增广路径 ppp 上能够为每条边增加的流量的最大值为路径 ppp 的残存容量,该容量由下面的表达式给出:cf(p)=min⁡{cf(u,v)∣(u,v)∈p}c_f(p) = \min \{ c_f(u, v) \mid (u, v) \in p \}cf​(p)=min{cf​(u,v)∣(u,v)∈p}

下面的引理将上面的论断阐述得更加精确。该引理的证明是算导练习26.2-7。

引理26.2 设 G=(V,E)G = (V, E)G=(V,E) 为一个流网络,设 fff 为图 GGG 中的一个流,设 ppp 为残存网络 GfG_fGf​ 中的一条增广路径。定义一个函数 fp:V×V→Rf_p : V\times V \to \Rfp​:V×V→R 如下:
fp(u,v)={cf(p)若(u,v)在p上0其他(26.8)f_p(u, v) = \begin{cases} c_f(p) \quad &若(u,v)在p上 \\ 0 \quad &其他 \end{cases} \tag{26.8}fp​(u,v)={cf​(p)0​若(u,v)在p上其他​(26.8) 则 fpf_pfp​ 是残存网络 GfG_fGf​ 中的一个流,其值为 ∣fp∣=cf(p)>0| f_p | = c_f(p) > 0∣fp​∣=cf​(p)>0 。

下面的推论证明,如果将流 fff 增加 fpf_pfp​ 的量,则将获得 GGG 的另一个流,该流的值更加接近最大值 The following corollary shows that if we augment f by fp, we get another flow in G whose value is closer to the maximum 。图26-4 c)所描述的是对图26-4(a)的流 fff 、增加图26-4(b)所示的 fpf_pfp​ 的量所获得的结果,而图26-4(d)描述的则是残存网络 GfG_fGf​ 。

推论26.3 设 G=(V,E)G= (V, E)G=(V,E) 为一个流网络,设 fff 为 GGG 中的一个流。设 ppp 为残存网络 GfG_fGf​ 中的一条增广路径,流 fpf_pfp​ 由式 (26.8)(26.8)(26.8) 所定义,假定将 fff 增加 fpf_pfp​ 的量。则函数 f↑fpf \uparrow f_pf↑fp​ 是图 GGG 的一个流,其值为 ∣f↑fp∣=∣f∣+∣fp∣>∣f∣| f \uparrow f_p | = | f | + | f_p | > | f|∣f↑fp​∣=∣f∣+∣fp​∣>∣f∣ 。
证明:根据引理26.1和引理26.2,可立即得到上述推论。

3. 流网络的切割

Ford-Fulkerson 方法的核心就是,沿着增广路径重复增加路径上的流量,直到找到一个最大流为止。我们怎么知道在算法终止时,确实找到了一个最大流呢?稍后将要证明的最大流最小割定理 max-flow min-cut theorem 告诉我们,一个流是最大流、当且仅当其残存网络不包含任何增广路径 a flow is maximum if and only if its residual network contains no augmenting path 。为了证明这个定理,首先来探讨一下流网络中的切割概念。

流网络 G=(V,E)G= (V, E)G=(V,E) 中的一个切割 (S,T)(S, T)(S,T) 将结点集合 VVV 划分为 SSS 和 T=V−ST = V-ST=V−S 两个集合,使得 s∈S,t∈Ts \in S, t \in Ts∈S,t∈T(该定义与算导第23章讨论最小生成树时定义的“切割”类似,只不过这里切割的是有向图、而不是无向图,并且要求 s∈S,t∈Ts \in S, t \in Ts∈S,t∈T )。若 fff 是一个流,则定义横跨切割 (S,T)(S, T)(S,T) 的净流量 f(S,T)f(S, T)f(S,T) the net flow f(S, T) across the cut (S, T) 如下:
f(S,T)=∑u∈S∑v∈Tf(u,v)−∑u∈S∑v∈Tf(v,u)(26.9)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) \tag{26.9}f(S,T)=u∈S∑​v∈T∑​f(u,v)−u∈S∑​v∈T∑​f(v,u)(26.9) 切割 (S,T)(S, T)(S,T) 的容量是:c(S,T)=∑u∈S∑v∈Tc(u,v)(26.10)c(S, T) = \sum_{u \in S}\sum_{v \in T} c(u, v) \tag{26.10}c(S,T)=u∈S∑​v∈T∑​c(u,v)(26.10) 一个网络的最小割是「整个网络中容量最小的切割」A minimum cut of a network is a cut whose capacity is minimum over all cuts of the network

流的定义和切割容量的定义之间存在着不对称性,但这种不对称性是有意而为,并且很重要 The asymmetry between the definitions of flow and capacity of a cut is intentional and important 。对于容量来说,我们只计算从集合 SSS 发出进入集合 TTT 的边的容量、而忽略反方向边上的容量。对于流,我们考虑的则是从 SSS 到 TTT 的流量减去从 TTT 到 SSS 的反方向的流量。这种区别的原因在本节稍后就清楚了。

图26-5描述的是图26-1(b)的流网络的一个切割 ({s,v1,v2},{v3,v4,t})( \{ s, v_1, v_2\}, \{ v_3, v_4, t\})({s,v1​,v2​},{v3​,v4​,t}) ,横跨该切割的净流量是:f(v1,v3)+f(v2,v4)−f(v3,v2)=12+11−4=19f(v_1, v_3) + f(v_2, v_4) - f(v_3, v_2) = 12 + 11 - 4 = 19f(v1​,v3​)+f(v2​,v4​)−f(v3​,v2​)=12+11−4=19 该切割的容量是:c(v1,v3)+c(v2,v4)=12+14=26c(v_1, v_3) + c(v_2, v_4) = 12 + 14 = 26c(v1​,v3​)+c(v2​,v4​)=12+14=26

下面的引理将证明,对于给定流 fff 来说,横跨任何切割的净流量都相同,都等于 ∣f∣|f|∣f∣ 即流的值

引理26.4 设 fff 为流网络 GGG 的一个流,该流网络的源点为 sss 、汇点为 ttt ,设 (S,T)(S, T)(S,T) 为流网络 GGG 的任意切割,则横跨切割 (S,T)(S, T)(S,T) 的净流量为 f(S,T)=∣f∣f(S, T)= |f|f(S,T)=∣f∣ 。
证明:对于任意结点 u∈V−{s,t}u \in V - \{ s, t\}u∈V−{s,t} ,重写流量守恒性质如下:∑v∈Vf(u,v)−∑v∈Vf(v,u)=0(26.11)\sum_{v \in V} f(u, v) - \sum_{v\in V} f(v, u) = 0 \tag{26.11}v∈V∑​f(u,v)−v∈V∑​f(v,u)=0(26.11) 根据式 (26.1)(26.1)(26.1) 对 ∣f∣|f|∣f∣ 的定义,并将式 (26.11)(26.11)(26.11) 左边的项加进来,针对所有结点 S−{s}S - \{ s\}S−{s} 进行求和,我们得到:
∣f∣=∑v∈Vf(s,v)−∑v∈Vf(v,s)+∑u∈S−{s}(∑v∈Vf(u,v)−∑v∈Vf(v,u))|f | = \sum_{v \in V} f(s, v)- \sum_{v \in V} f(v, s) + \sum_{u \in S - \{ s \} } \bigg( \sum_{v \in V} f(u, v) - \sum_{v \in V} f(v, u)\bigg)∣f∣=v∈V∑​f(s,v)−v∈V∑​f(v,s)+u∈S−{s}∑​(v∈V∑​f(u,v)−v∈V∑​f(v,u)) 将右边的求和项展开并重新组合,可以获得:
∣f∣=∑v∈Vf(s,v)−∑v∈Vf(v,s)+∑u∈S−{x}∑v∈Vf(u,v)−∑u∈S−{s}∑v∈Vf(v,u)=∑v∈V(f(s,v)+∑u∈S−{s}f(u,v))−∑v∈V(f(v,s)+∑u∈S−{s}f(v,u))=∑v∈V∑u∈Sf(u,v)−∑v∈V∑u∈Sf(v,u)\begin{aligned} | f| &= \sum_{v \in V} f(s, v) - \sum_{v \in V} f(v, s) + \sum_{u \in S - \{ x \} } \sum_{v \in V} f(u, v) - \sum_{u \in S - \{ s \} } \sum_{v \in V} f(v, u) \\ &= \sum_{v \in V} \bigg(f(s, v) + \sum_{u \in S - \{ s\}} f(u, v)\bigg) - \sum_{v \in V} \bigg(f (v, s) +\sum_{u \in S - \{ s\} } f(v, u)\bigg) \\ &= \sum_{v \in V }\sum_{u \in S} f(u, v) - \sum_{v \in V} \sum_{u \in S} f(v, u) \end{aligned}∣f∣​=v∈V∑​f(s,v)−v∈V∑​f(v,s)+u∈S−{x}∑​v∈V∑​f(u,v)−u∈S−{s}∑​v∈V∑​f(v,u)=v∈V∑​(f(s,v)+u∈S−{s}∑​f(u,v))−v∈V∑​(f(v,s)+u∈S−{s}∑​f(v,u))=v∈V∑​u∈S∑​f(u,v)−v∈V∑​u∈S∑​f(v,u)​

因为 V=S∪TV= S\cup TV=S∪T 并且 S∩T=∅S \cap T= \varnothingS∩T=∅ ,我们可以将「上述表达式中针对集合 VVV 的求和」分解为针对 SSS 和 TTT 的求和,得到:
∣f∣=∑v∈S∑u∈Sf(u,v)+∑v∈T∑u∈Sf(u,v)−∑v∈S∑u∈Sf(v,u)−∑v∈T∑u∈Sf(v,u)=∑v∈T∑u∈Sf(u,v)−∑v∈T∑u∈Sf(v,u)+(∑v∈S∑u∈Sf(u,v)−∑v∈S∑u∈Sf(v,u))| f | = \sum_{v \in S }\sum_{u \in S} f(u, v) + \sum_{v \in T} \sum_{u \in S} f(u, v) - \sum_{v \in S} \sum_{u \in S} f(v, u) - \sum_{v \in T}\sum_{u \in S} f(v, u) \\ = \sum_{v \in T}\sum_{u \in S} f(u, v) - \sum_{v \in T}\sum_{u \in S} f(v, u) + \bigg( \sum_{v \in S}\sum_{u \in S}f(u, v) - \sum_{v \in S} \sum_{u \in S}f(v, u)\bigg)∣f∣=v∈S∑​u∈S∑​f(u,v)+v∈T∑​u∈S∑​f(u,v)−v∈S∑​u∈S∑​f(v,u)−v∈T∑​u∈S∑​f(v,u)=v∈T∑​u∈S∑​f(u,v)−v∈T∑​u∈S∑​f(v,u)+(v∈S∑​u∈S∑​f(u,v)−v∈S∑​u∈S∑​f(v,u)) 因为对于所有的结点 x,y∈Sx, y \in Sx,y∈S ,项 f(x,y)f(x, y)f(x,y) 在每个求和项中刚好出现一次,上述表达式括号里面的两个求和项实际上是一样的。因此,这些求和项互相抵消,我们有:
∣f∣=∑u∈S∑v∈Tf(u,v)−∑u∈S∑v∈Tf(v,u)=f(S,T)|f| = \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)∣f∣=u∈S∑​v∈T∑​f(u,v)−u∈S∑​v∈T∑​f(v,u)=f(S,T)

引理26.4的一个推论,说明如何使用切割容量来限定一个流的值

推论26.5 流网络 GGG 中任意流 fff 的值不能超过 GGG 的任意切割的容量。
证明:设 (S,T)(S, T)(S,T) 为流网络 GGG 的任意切割,设 fff 为 GGG 中的任意流。根据引理26.4和容量限制性质,我们有:∣f∣=f(S,T)=∑u∈S∑v∈Tf(u,v)−∑u∈S∑v∈Tf(v,u)≤∑u∈S∑v∈Tf(u,v)≤∑u∈S∑v∈Tc(u,v)=c(S,T)|f| = 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) \\ \le \sum_{u \in S}\sum_{v \in T} f(u, v)\le \sum_{u \in S} \sum_{v \in T} c(u, v) = c(S, T)∣f∣=f(S,T)=u∈S∑​v∈T∑​f(u,v)−u∈S∑​v∈T∑​f(v,u)≤u∈S∑​v∈T∑​f(u,v)≤u∈S∑​v∈T∑​c(u,v)=c(S,T) 推论 26.526.526.5 给出的一个直接结论是:一个流网络中最大流的值不能超过该网络最小割的容量。这就是下面要来陈诉和证明的、非常重要的最大流最小割定理。该定理表明一个最大流的值事实上等于一个最小割的容量

定理26.6最大流最小割定理)设 fff 为流网络 G=(V,E)G = (V, E)G=(V,E) 中的一个流,该流网络的源点为 sss 、汇点为 ttt ,则下面的条件是等价的:

  1. fff 是 GGG 的一个最大流;
  2. 残存网络 GfG_fGf​ 不包括任何增广路径;
  3. ∣f∣=c(S,T)|f | = c(S, T)∣f∣=c(S,T) ,其中 (S,T)(S, T)(S,T) 是流网络 GGG 的某个切割。

证明

  1. (1)⇒(2)(1) \rArr (2)(1)⇒(2) :使用反证法。假定 fff 是 GGG 的一个最大流,但残存网络 GfG_fGf​ 同时包含一条增广路径 ppp 。那么根据推论26.3,对 fff 增加流量 fpf_pfp​ augmenting f by fp(这里的 fpf_pfp​ 由式 (26.8)(26.8)(26.8) 给出)所形成的流是 GGG 中一个值严格大于 ∣f∣| f|∣f∣ 的流,这与 fff 是最大流的假设矛盾。
  2. (2)⇒(3)(2) \rArr (3)(2)⇒(3) :假定 GfG_fGf​ 不包含任何增广路径,也就是说,在残存网络 GfG_fGf​ 中不存在任何从源点 sss 到汇点 ttt 的路径。定义 S={v∣v∈V∪在Gf中存在一条从s到v的路径},T=V−SS = \{ v \mid v \in V \cup 在G_f中存在一条从s到v的路径\},\ T= V- SS={v∣v∈V∪在Gf​中存在一条从s到v的路径}, T=V−S 。显然,s∈Ss \in Ss∈S ,而因为 GfG_fGf​ 中不存在从 sss 到 ttt 的路径,所以 t∉St \notin St∈/​S 。因此,划分 (S,T)(S, T)(S,T) 是流网络的一个切割。现在,考虑一对结点 u∈Su \in Su∈S 和 v∈Tv \in Tv∈T 。
    • 如果 (u,v)∈E(u, v) \in E(u,v)∈E ,则必有 f(u,v)=c(u,v)f(u, v) = c(u, v)f(u,v)=c(u,v) ,因为否则边 (u,v)(u, v)(u,v) 将属于 EfE_fEf​(残存网络的边集合;因为 (u,v)∈E(u, v)\in E(u,v)∈E 时,残存容量为 cf(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) ,如非零则 (u,v)∈Ef(u, v) \in E_f(u,v)∈Ef​ ),而这将把结点 vvv 置于集合 SSS 中。
    • 如果边 (v,u)∈E(v, u)\in E(v,u)∈E ,则必有 f(v,u)=0f(v, u) = 0f(v,u)=0 ,因为否则 cf(u,v)=f(v,u)c_f(u, v) = f(v, u)cf​(u,v)=f(v,u) 将为正值,边 (u,v)(u, v)(u,v) 将属于 EfE_fEf​ ,而这将把结点 vvv 置于集合 SSS 中。
    • 当然,如果边 (u,v)(u, v)(u,v) 和边 (v,u)(v, u)(v,u) 都不在集合 EEE 中,则 f(u,v)=f(v,u)=0f(u, v) = f(v, u) = 0f(u,v)=f(v,u)=0 。
    • 因此有:f(S,T)=∑u∈S∑v∈Tf(u,v)−∑v∈T∑u∈Sf(v,u)=∑u∈S∑v∈Tc(u,v)−∑v∈T∑u∈S0=c(S,T)f(S, T)= \sum_{u \in S} \sum_{v \in T} f(u, v) - \sum_{v \in T}\sum_{ u \in S} f(v, u) \\= \sum_{u \in S} \sum_{v \in T} c(u, v) - \sum_{v \in T} \sum_{u \in S} 0 = c(S, T)f(S,T)=u∈S∑​v∈T∑​f(u,v)−v∈T∑​u∈S∑​f(v,u)=u∈S∑​v∈T∑​c(u,v)−v∈T∑​u∈S∑​0=c(S,T) 根据引理26.4,∣f∣=f(S,T)=c(S,T)|f| = f(S, T) = c(S, T)∣f∣=f(S,T)=c(S,T) 。
  3. (3)⇒(1)(3) \rArr (1)(3)⇒(1) :根据推论26.5,对于所有切割 (S,T)(S, T)(S,T) ,∣f∣≤c(S,T)|f | \le c(S, T)∣f∣≤c(S,T) 。因此,条件 ∣f∣=c(S,T)|f| = c(S, T)∣f∣=c(S,T) 隐含着 fff 是一个最大流

3. 基本的 Ford-Fulkerson 算法

Ford-Fulkerson 方法的每次迭代中,寻找某条增广路径 ppp ,然后使用 ppp 来对流 fff 进行修改(增加)。正如引理26.2和推论26.3所示,我们以 f↑fpf \uparrow f_pf↑fp​ 来替换 fff ,从而获得一个值为 ∣f∣+∣fp∣|f| + |f_p|∣f∣+∣fp​∣ 的更大的流。在下面的算法实现中,通过为每条边 (u,v)∈E(u, v) \in E(u,v)∈E 更新流属性 (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 。另外,假设流网络的容量 c(u,v)c(u, v)c(u,v) 都已经给出,如果边 (u,v)∉E(u, v) \notin E(u,v)∈/​E ,则 c(u,v)=0c(u, v) = 0c(u,v)=0 。根据式 (26.2)(26.2)(26.2) 来计算残存容量 cf(u,v)c_f(u, v)cf​(u,v) 。代码中的表达式 cf(p)c_f(p)cf​(p) 只是一个临时变量,用来存放路径 ppp 的残存容量

FORD-FULKERSON(G, s, t)for each edge(u, v) in G.E(u, v).f = 0while there exists a path p from s to t in the residual network Gfcf(p) = min{ cf(u, v) : (u, v) is in p }for each edge(u, v) in pif (u, v) in E(u, v).f = (u, v).f + cf(p)else // (u, v)不存在E中,是某个反向边(v, u).f = (v, u).f - cf(p)

FORD-FULKERSON 算法仅是对早先给出的 FORD-FULKERSON-METHOD 过程的简单扩展。图26-6所描述的是一个样本运行过程的每次迭代的结果。算法前两行初始化流 fff 为 000 ;第三行到第八行的while循环,重复在残存网络 GfG_fGf​ 中寻找一条增广路径 ppp ,然后使用残存容量 cf(p)c_f(p)cf​(p) 来对路径 ppp 上的流 fff 进行增广。路径 ppp 上每条残存边要么是原来网络中的一条边,要么是原来网络中的边的反向边,算法第6到第8行针对每种情况对流进行相应的更新:如果残存边是原来网络中的一条边,则加增流量,否则缩减流量(不用同时更新残存网络吗?)。当不再有增广路径时,流 fff 就是最大流。

4. FORD-FUKLERSON 算法的分析

这一算法的运行时间,取决于算法第 333 行是如何寻找增广路径的。如果选择不好,算法可能不会终止:流的值会随着后续的递增而增加,但它却不一定收敛于最大的流值。如果使用广度优先搜索来寻找增广路径,算法的运行时间将是多项式数量级。在证明该结果前,先来为任意选择增广路径的情况获取一个简单的上限,这里假定所选择的任意增广路径和所有的容量都是整数

在实际情况中,最大流问题中的容量常常是整数。如果容量为有理数,则可以通过乘以某个系数来将其转换为整数;只有当边的容量为无理数时,Ford-Fulkerson 方法才有可能不被终止。如果 f∗f^*f∗ 表示转换后网络中的一个最大流,则在 FORD-FULKERSON 算法的一个直接实现中,执行第三行到第八行的while循环的次数最多为 ∣f∗∣| f^* |∣f∗∣ 次,因为流量值在每次迭代中最少增加一个单位。

如果用来实现流网络 G=(V,E)G=(V, E)G=(V,E) 的数据结构是合理的,并且寻找一条增广路径的算法时间是线性的,则整个while循环的执行将非常有效。假设有一个与有向图 G′=(V,E′)G' = (V, E')G′=(V,E′) 相对应的数据结构,这里 E′={(u,v)∣(u,v)∈E或(v,u)∈E}E' = \{ (u, v) \mid (u, v) \in E 或 (v, u) \in E\}E′={(u,v)∣(u,v)∈E或(v,u)∈E} 。网络 GGG 中的边也是网络 G′G'G′ 中的边,因此在这一数据结构中,保持其容量和流就非常简单了。给定网络 GGG 的一个流 fff ,残存网络 GfG_fGf​ 中的边由网络 G′G'G′ 中所有满足条件 cf(u,v)>0c_f(u, v) > 0cf​(u,v)>0 的边 (u,v)(u, v)(u,v) 所构成,其中 cfc_fcf​ 遵守式 (26.2)(26.2)(26.2) 。因此,如果使用深度优先搜索或广度优先搜索,在一个残存网络中找到一条路径的时间应该是 O(V+E′)=O(E)O(V+E') = O(E)O(V+E′)=O(E) 。while循环的每一遍执行所需的时间因此为 O(E)O(E)O(E) ,这与算法第 1∼21 \sim 21∼2 行的初始化成本一样,从而整个 FORD-FULKERSON 算法的运行时间为 O(E∣f∗∣)O(E | f^*|)O(E∣f∗∣) 。

英文版原图26.6, continued,在 s→v2s\to v_2s→v2​ 的两条边的权重上画反了!

当容量都是整数值、且最优的流量值 ∣f∗∣|f^*|∣f∗∣ 较小时,FORD-FULKERSON 算法的 运行时间相当不错。图26-7(a)描述的是当 ∣f∗∣|f^*|∣f∗∣ 的取值较大时可能发生的情况。该网络的一个最大流取值为 20000002000 0002000000 —— 10000001000 0001000000 单位的流量流经路径 s→u→ts \to u \to ts→u→t ,另外 10000001 000 0001000000 单位的流量流经路径 s→v→ts \to v \to ts→v→t 。如果 FORD-FULKERSON 算法找到的第一条增广路径为 s→u→v→ts \to u \to v \to ts→u→v→t ,如图26-7(a)所示,则在第一次迭代后,流的值为 111 。这样产生的残存网络如图26-7(b)所示,然后流的值将为 222 ,图26-7 c)描述的是该结果的残存网络。在每个奇数次迭代中,选择增广路径 s→u→v→ts \to u \to v \to ts→u→v→t ,在每个偶数次迭代中,选择增广路径 s→v→u→ts \to v \to u \to ts→v→u→t ,并如此继续下去。这样将一共执行 20000002000 0002000000 次递增操作,每次将流量增加 111 个单位。

5. Edmonds-Karp 算法

我们可以通过在「算法第三行寻找增广路径的操作」中,使用广度优先搜索来改善 FORD-FULKERSON 算法的效率。也就是说,我们在残存网络中选择的增广路径是一条从源点 sss 到汇点 ttt 的最短路径,其中每条边的权重为单位距离。我们称如此实现的 Ford-Fulkerson 方法为 Edmonds-Karp 算法。现在来证明这一算法的运行时间为 O(VE2)O(V E^2)O(VE2) 。

我们的分析取决于残存网络 GfG_fGf​ 中结点之间的距离。下面的引理使用符号 δf(u,v)\delta_f(u, v)δf​(u,v) 来表示残存网络 GfG_fGf​ 中从结点 uuu 到结点 vvv 的最短路径距离,其中每条边的权重为单位距离。

引理26.7 如果 Edmonds-Karp 算法运行在流网络 G=(V,E)G = (V, E)G=(V,E) 上,该网络的源点为 sss 、汇点为 ttt ,则对于所有的结点 v∈V−{s,t}v \in V- \{ s, t\}v∈V−{s,t} ,残存网络 GfG_fGf​ 中的最短路径距离 δf(s,v)\delta_f(s, v)δf​(s,v) 随着每次流量的递增而单调递增 the shortest-path distance δf(s, v) in the residual network Gf increases monotonically with each flow augmentation

证明:我们的证明思路是,(假设)对于某个结点 v∈V−{s,t}v \in V - \{ s, t\}v∈V−{s,t} ,存在一个流量递增操作,导致从源点 sss 到结点 vvv 的最短路径距离减少,然后以此来导出一个矛盾。设 fff 是在「第一个导致某条最短路径距离减少的流量递增操作」之前的流,设 f′f'f′ 为该流量递增操作之后的流。令 vvv 为「在递增操作中最短路径距离被减少的所有结点中」δf′(s,v)\delta_{f'} (s, v)δf′​(s,v) 最小的结点。显然可知,δf′(s,v)<δf(s,v)\delta_{f'} (s, v) < \delta_f (s, v)δf′​(s,v)<δf​(s,v) 。

令 p=s⇝u→vp = s \leadsto u \to vp=s⇝u→v 为残存网络 Gf′G_{f'}Gf′​ 中从源点 sss 到结点 vvv 的一条最短路径,因此 (u,v)∈Ef′(u, v) \in E_{f'}(u,v)∈Ef′​ ,并且 δf′(s,u)=δf′(s,v)−1(26.12)\delta_{f'} (s, u) = \delta_{f'} (s, v) - 1 \tag{26.12}δf′​(s,u)=δf′​(s,v)−1(26.12)

因为无论怎样选择结点 vvv ,我们知道从源点 sss 到结点 uuu 的距离并没有减少——因为如果 δf′(s,u)\delta_{f'} (s, u)δf′​(s,u) 减少了,且 δf′(s,u)=δf′(s,v)−1<δf′(s,v)\delta_{f'} (s, u) = \delta_{f'} (s, v) - 1 < \delta_{f'} (s, v)δf′​(s,u)=δf′​(s,v)−1<δf′​(s,v) ,vvv 就不是「最短路径距离被减少的所有结点中」δf′(s,v)\delta_{f'} (s, v)δf′​(s,v) 最小的结点。即:δf′(s,u)≥δf(s,u)(26.13)\delta_{f'} (s, u) \ge \delta_f (s, u) \tag{26.13}δf′​(s,u)≥δf​(s,u)(26.13)

我们断言 (u,v)∉Ef(u, v) \notin E_f(u,v)∈/​Ef​ 。为什么呢?如果有 (u,v)∈Ef(u, v) \in E_f(u,v)∈Ef​ ,则有:
δf(s,v)≤δf(s,u)+1根据引理24.10的三角不等式≤δf′(s,u)+1根据不等式26.13≤δf′(s,v)根据等式26.12\begin{aligned} \delta_f(s, v) &\le \delta_f (s, u) + 1 \quad &根据引理24.10的三角不等式 \\ &\le \delta_{f'} (s, u) + 1 \quad &根据不等式26.13 \\ &\le \delta_{f'} (s, v) \quad &根据等式26.12 \end{aligned}δf​(s,v)​≤δf​(s,u)+1≤δf′​(s,u)+1≤δf′​(s,v)​根据引理24.10的三角不等式根据不等式26.13根据等式26.12​ 而上述结果与我们的假设 δf′(s,v)<δf(s,v)\delta_{f'}(s, v) < \delta_f(s, v)δf′​(s,v)<δf​(s,v) 相矛盾。

如何才能有 (u,v)∉Ef(u, v) \notin E_f(u,v)∈/​Ef​ 且 (u,v)∈Ef′(u, v) \in E_{f'}(u,v)∈Ef′​ ?递增操作必定增加从结点 vvv 到结点 uuu 的流量 The augmentation must have increased the flow from v to u(先前 (v,u)∈Ef∪(u,v)∉Ef(v, u) \in E_f \cup (u, v) \notin E_{f}(v,u)∈Ef​∪(u,v)∈/​Ef​ ,此后 (u,v)∈Ef′(u, v) \in E_{f'}(u,v)∈Ef′​ )。Edmonds-Karp 算法总是沿最短路径来增加流,因此残存网络 GfG_fGf​ 中从源点 sss 到结点 uuu 的最短路径上的最后一条边是 (v,u)(v, u)(v,u)(而 s⇝u→vs \leadsto u \to vs⇝u→v 为残存网络 Gf′G_{f'}Gf′​ 中从源点 sss 到结点 vvv 的一条最短路径)。因此:
δf(s,v)=δf(s,u)−1≤δf′(s,u)−1根据不等式26.13=δf′(s,v)−2根据等式26.12\begin{aligned} \delta_f (s, v) &= \delta_f(s, u) - 1\\ &\le \delta_{f'} (s, u) - 1 \quad &根据不等式26.13 \\ &= \delta_{f'} (s, v) - 2 \quad &根据等式26.12 \end{aligned}δf​(s,v)​=δf​(s,u)−1≤δf′​(s,u)−1=δf′​(s,v)−2​根据不等式26.13根据等式26.12​ 这与我们的假设 δf′(s,v)<δf(s,v)\delta_{f'} (s, v) < \delta_f(s, v)δf′​(s,v)<δf​(s,v) 相矛盾。因此可以得出结论,我们关于存在这样一个结点 vvv 的假设是不正确的。

下面的定理给出了 Edmonds-Karp 算法的迭代次数的上界。

定理26.8 如果 Edmonds-Karp 算法运行在源点为 sss 、汇点为 ttt 的流网络 G=(V,E)G= (V, E)G=(V,E) 上,则该算法所执行的流量递增操作的总次数为 O(VE)O(VE)O(VE) 。
证明:在残存网络 GfG_fGf​ 中,如果一条路径 ppp 的残存容量是该条路径上边 (u,v)(u, v)(u,v) 的残存容量,也就是说,如果 cf(p)=cf(u,v)c_f(p) = c_f(u, v)cf​(p)=cf​(u,v) ,则称边 (u,v)(u, v)(u,v) 为增广路径 ppp 上的关键边。在沿一条增广路径增加流后,处于该条路径上的所有关键边都将从残存网络中消失。而且,任何一条增广路径上都至少存在一条关键边。我们将证明,对于 ∣E∣|E|∣E∣ 中的每条边来说,其成为关键边的次数最多为 ∣V∣/2|V| / 2∣V∣/2 次 each of the |E| edges can become critical at most |V| / 2 times

设 uuu 和 vvv 为集合 VVV 中的结点,这两个结点由 EEE 中的一条边连接在一起。由于增广路径都是最短路径,当边 (u,v)(u, v)(u,v) 第一次成为关键边时,我们有:δf(s,v)=δf(s,u)+1\delta_f(s, v) = \delta_f(s, u) +1δf​(s,v)=δf​(s,u)+1 一旦对流进行增加后,边 (u,v)(u, v)(u,v) 就从残存网络中消失。以后也不能重新出现在另一条增广路径上,直到从 uuu 到 vvv 的网络流减小后为止,并且只有当 (u,v)(u, v)(u,v) 出现在增广路径上时,这种情况才会发生(指边 (u,v)(u, v)(u,v) 重新出现) It cannot reappear later on another augmenting path until after the flow from u to v is decreased, which occurs only if (u, v) appears on an augmenting path 。如果当这一事件发生时 f′f'f′ 是 GGG 的流,则有:δf′(s,u)=δf′(s,v)+1\delta_{f'} (s, u) = \delta_{f'} (s, v)+ 1δf′​(s,u)=δf′​(s,v)+1

中文版的这里,上个公式写错了:

由于根据引理26.7,δf(s,v)≤δf′(s,v)\delta_{f} (s, v) \le \delta_{f'} (s, v)δf​(s,v)≤δf′​(s,v) ,因此有:
δf′(s,u)=δf′(s,v)+1≥δf(s,v)+1=δ(s,u)+2\delta_{f'} (s, u) = \delta_{f'} (s, v) + 1 \ge \delta_f(s, v) + 1 = \delta(s, u) + 2δf′​(s,u)=δf′​(s,v)+1≥δf​(s,v)+1=δ(s,u)+2 因此,从边 (u,v)(u, v)(u,v) 成为关键边、到下一次再成为关键边,从源点 sss 到结点 uuu 的距离至少增加了 222 个单位,而从源点 sss 到结点 uuu 的最初距离至少为 000 ,从 sss 到 uuu 的最短路径上的中间结点中不可能包括结点 s,us, us,u 或者 ttt(因为边 (u,v)(u, v)(u,v) 处于一条增广路径上,意味着 u≠tu \ne tu​=t )。因此,一直到结点 uuu 成为不可到达的结点前 until u becomes unreachable from the source ,其距离最多为 ∣V∣−2|V| - 2∣V∣−2(图 GGG 有 ∣V∣|V|∣V∣ 个顶点,边权为 111 ,则 sss 到 ttt 可能的最大距离为 ∣V∣−1|V| - 1∣V∣−1 ,且 u≠tu \ne tu​=t )。因此,在边 (u,v)(u, v)(u,v) 第一次成为关键边时,它还可以至多再成为关键边 (∣V∣−2)/2=∣V∣/2−1(|V| - 2) / 2= |V| / 2 - 1(∣V∣−2)/2=∣V∣/2−1 次,即边 (u,v)(u, v)(u,v) 成为关键边的总次数为 ∣V∣/2|V| / 2∣V∣/2 。由于一共有 O(E)O(E)O(E) 对结点 (u,v)(u, v)(u,v) 可以在一个残存网络中有边连接彼此,因此在 Edmonds-Karp 算法执行的全部过程中,关键边的总数为 O(VE)O(VE)O(VE) 。每条增广路径至少有一条关键边,因此定理成立。

由于在用广度优先搜索寻找增广路径时,FORD-FULKERSON 中的每次迭代可以在 O(E)O(E)O(E) 时间内实现(每次迭代找到一条增广路径,每条增广路径至少有一条关键边),所以 Edmonds-Karp 算法的总运行时间为 O(VE2)O(VE^2)O(VE2) 。我们在后面将看到,推送-重贴标签算法能够取得更好的界。算法导论 26.4节给出了一个时间复杂度为 O(V2E)O(V^2 E)O(V2E) 的最大流算法,该算法是算法导论 26.5节中讨论的 O(V3)O(V^3)O(V3) 算法的基础。

算法学习笔记 网络流之最大流算法相关推荐

  1. 算法学习笔记13:哈希算法

    哈希算法(上):如何防止数据库中的用户信息被脱库 什么是哈希算法 应用一:安全加密 应用二:唯一标识 应用三:数据校验 应用四:散列函数 解答开篇 哈希算法(下):哈希算法在分布式系统中有哪些应用 应 ...

  2. 算法学习笔记之滑动平均滤波算法

    滑动平均滤波算法只采样一次,将一次采样值和过去的若干次采样值一起求平均,得到的有效采样值即可投入使用.如果取N个采样值求平均,存储区中必须开辟N个数据的暂存区.每新采集一个数据便存入暂存区中,同时去掉 ...

  3. 算法学习笔记:网络流#4——ISAP 求解最大流

    算法学习笔记:网络流#4--ISAP 求解最大流 1. 前言 2. 模板 2.1 详解 2.2 正确性证明 2.3 代码 3. 算法对比 3.1 一般数据下的对比 3.2 特殊数据下的对比 4. 总结 ...

  4. 网络流算法学习笔记——最大流问题基本概念和Ford-Fulkerson方法(标号法C++实现)

    屈婉玲<算法设计与分析>第2版第7章网络流算法学习笔记. 基本概念 最大流问题,相当于有从s到t的供水系统,每段路径都有限定流量,除了s.t两地外,每个中间点都不能滞留,从s流入多少,就从 ...

  5. Python最优化算法学习笔记(Gurobi)

    微信公众号:数学建模与人工智能 github地址:https://github.com/QInzhengk/Math-Model-and-Machine-Learning Python最优化算法学习笔 ...

  6. 网络流之最大流算法(EdmondsKarp)

    网络流之最大流算法(EdmondsKarp) 标签: 网络流算法EdmondsKarp流量最大流 2014-03-11 18:05 34795人阅读 评论(12) 收藏 举报  分类: 图论~~网络流 ...

  7. 【C++ Primer 学习笔记】: 容器和算法之【泛型算法】

    本系列博客主要是在学习 C++ Primer 时的一些总结和笔记. [C++ Primer 学习笔记]: 容器和算法之[泛型算法] 本文地址:http://blog.csdn.net/shanglia ...

  8. 数据结构与算法学习笔记15:最大流问题 / 二分图 / 有权无权二分图的匹配 / 匈牙利算法 / 银行家算法 / 稳定婚配

    数据结构与算法学习笔记15:最大流问题 / 二分图 / 有权无权二分图的匹配 / 匈牙利算法 / 银行家算法 / 稳定婚配 引入小题:最短路径 最大流问题(maximum flow problem) ...

  9. 大顶堆删除最大值_算法学习笔记(47): 二叉堆

    堆(Heap)是一类数据结构,它们拥有树状结构,且能够保证父节点比子节点大(或小).当根节点保存堆中最大值时,称为大根堆:反之,则称为小根堆. 二叉堆(Binary Heap)是最简单.常用的堆,是一 ...

最新文章

  1. phpstorm设置的快捷键突然失效了,提示: IdeaVim ...
  2. CCNA实验解析——VLAN间的路由的配置
  3. linux高通平台代码,高通linux系统初始化
  4. 容器安全最佳实践入门
  5. Kibana停止kibana的方法命令:找到5601端口对应的进程ID 把此进程进行kill即可
  6. 浏览器中关于事件的那点事儿
  7. Busy Dialog init - hashchange will call BusyDialog.open - flower
  8. miniui datagrid 隐藏列默认赋值_Qt商业组件DataGrid:内置视图和布局详解(一)
  9. 【windows】windows 11 安装解决 这台电脑无法运行 Windows 11
  10. IntelliJ IDEA 2017新工具
  11. 项目管理:如何显性管理并提升Story分解能力
  12. 【报告分享】2020中国数字化后浪:中小企业转型与创新实录.pdf(附下载链接)...
  13. Mycat读写分离以及拆库拆表综合实验3:通过日志分析mycat路由过程
  14. 模糊逻辑学习--模糊逻辑的基础
  15. 电脑连接移动设备android驱动程序,手机连接电脑驱动程序下载汇总
  16. 在html用微信跳转,H5如何跳转微信小程序?
  17. 五分钟学会文献管理神器—— Zotero
  18. DHTML 页面对象属性
  19. 爱剪辑如何解决分段视频在串接处快两秒的问题
  20. pyth命令_如何:在Windows上设置用于从命令行运行.py文件的Python可执行文件

热门文章

  1. Ribbon客户端负载
  2. 关于Hibernate中inverse=true的转载
  3. 计算机鼻祖-Donald Knuth(高德纳) 的传奇
  4. jpg格式图片如何转换成Word?
  5. 【HDOJ】1009 FatMouse' Trade_天涯浪子_新浪博客
  6. GBase 8c 函数和操作符 - HLL函数和操作符 之 聚合函数
  7. elasticsearch 一款高扩展性的分布式全文检索引擎
  8. 将一个任意整数插入到已排列的整型数组中,插入后,数组中的数仍保持有序
  9. 认养一头牛更新IPO招股书:十分依赖第三方,酸奶产品后劲乏力?
  10. 2017年上半年信息安全2017年上半年信息安全工程师考试_试题四答案(解题步骤详解)