6-1 网络最大流
网络流问题
(1) 概念:
网络流问题是图论中一类常见的问题, 应用在许多包含流量的系统中,同时也是求解其他一些图论问题的基础, 如求解图的顶点的连通度和边连通度、匹配问题等。
(2) 网流问题分类:
- 网络最大流
- 流量有上下界网络的最大流和最小流
- 最小费用最大流
- 流量有上下界网络的最小费用最大流
- …
6.1 网络最大流
6.1.1 基本概念
1. 网络流理论基础
最大流最小割定理构成网络流理论基础。该定理包含以下几个概念
- 网络最大流
- 增广路
- 残留网络
- 最小割
2. 容量网络和网络最大流
-
a. 容量网络(capacity network)
有向图 G ( V , E ) G(V,E) G(V,E)中, 指定了源点 V s V_s Vs 汇点 V t V_t Vt,每一条边上都有一个权值 c ( u , v ) > 0 c(u,v)> 0 c(u,v)>0即弧的容量。 -
b. 弧的容量
容量网络G中任意一条弧上的权值。表示最大可以通过的流量。 -
c. 弧的流量(Flow Rate)
通过网络G中每条弧 < u , v > <u,v> <u,v>上的实际流量(流量), 记为 f ( u , v ) f(u,v) f(u,v)。 -
d. 网络流(Network Flow)
所有弧上流量的集合 f = { f ( u , v ) } f=\{f(u,v)\} f={f(u,v)} , 称为容量网络G的一个网络流。 如图6.2 (b)所示, u u u代表容量, v v v代表弧上当前流量。
[!info]
- 弧上流量小于弧的容量
- 源 V s V_s Vs流出的流量等于流入汇点 V t V_t Vt 的流量
- 任意的中间顶点 V i V_i Vi , 流入与流出的流量相等
- e. 可行流
作为可行流需要满足,弧流量限制条件和平衡条件的流。对任何一个容量网络可行流总是存在的。
- 弧流量限制
0 ≤ f ( u , v ) ≤ c ( u , v ) 0\leq f(u,v) \leq c(u,v) 0≤f(u,v)≤c(u,v)
f ( u , v ) f(u,v) f(u,v) : 弧 ⟨ u , v ⟩ \braket {u,v} ⟨u,v⟩ 的流量 - 平衡条件
∑ v f ( u , v ) − ∑ v f ( v , u ) = { ∣ f ∣ , 当 u = V s 0 , 当 u ≠ V s , V t − ∣ f ∣ , 当 u = V t \sum_vf(u,v) - \sum_vf(v,u) = \begin{cases} |f|, & \text{当$u=V_s$} \\ 0, & \text{当$u\neq V_s,V_t$} \\ -|f|, & \text{当$u=V_t$} \end{cases} v∑f(u,v)−v∑f(v,u)=⎩ ⎨ ⎧∣f∣,0,−∣f∣,当u=Vs当u=Vs,Vt当u=Vt
∑ v f ( u , v ) \sum_vf(u,v) ∑vf(u,v): 从顶点 u u u流出的流量总和
∑ v ( v , u ) \sum_v(v,u) ∑v(v,u) : 流入顶点 u u u的流量总和
f f f : 该可行流的流量,即源点的净流出流量,或汇点的净流入流量
-
f. 零流(Zero Flow)
网络图中,每条弧上的流量为0,该网络流被称为零流 -
g. 伪流(Pseudoflow) 或容量可行流
一个网络流只满足弧的容量限制条件,不满足平衡条件,这种网络流被称为伪流。或称为容量可行流。在预流推进算法中用到。 -
h. 最大流(Maximum Flow)
在容量网络 G ( V , E ) G(V,E) G(V,E)中,满足弧流量限制条件和平衡条件,且具有最大流量的可行流,称为网络最大流,简称最大流。
3. 链与增广路
容量网络G根据弧上流量和容量的关系,可以将分为4中类型
- 饱和弧 : f ( u , v ) = c ( u , v ) f(u,v) = c(u,v) f(u,v)=c(u,v)
- 非饱和弧 : f ( u , v ) < c ( u , v ) f(u,v) < c(u,v) f(u,v)<c(u,v)
- 零流弧: f ( u , v ) = 0 f(u,v) = 0 f(u,v)=0
- 非零流弧 : f ( u , v ) > 0 f(u,v) >0 f(u,v)>0
(1) 链
链: 容量网络图
G
G
G中的,源
u
u
u到汇
v
v
v的顶点序列,如:
(
u
,
u
1
,
u
2
,
⋯
,
u
n
,
v
)
(u, u_1, u_2, \cdots, u_n, v)
(u,u1,u2,⋯,un,v) 。 要求相邻的两个顶点之间有一条弧,如
⟨
u
,
u
1
⟩
或
⟨
u
1
,
u
⟩
\braket {u,u1} 或 \braket{u1, u}
⟨u,u1⟩或⟨u1,u⟩为容量网络的一条弧。
各弧分类:
- 前向弧(P+): 弧的方向与链的正方向一致的弧
- 后向弧(P-): 弧的方向与链的正方向相反的弧
链
P
1
=
{
<
V
s
,
V
1
>
,
<
V
1
,
V
2
>
,
<
V
2
,
V
4
>
,
<
V
4
,
V
t
>
}
P1=\{<V_s, V_1>, <V_1, V_2>, <V_2, V_4>,<V_4, V_t>\}
P1={<Vs,V1>,<V1,V2>,<V2,V4>,<V4,Vt>}
前向弧:
P
1
+
=
{
<
V
s
,
V
1
>
,
<
V
1
,
V
2
>
,
<
V
2
,
V
4
>
,
<
V
4
,
V
t
>
}
P1+=\{<V_s, V_1>,<V_1, V_2>, <V_2, V_4>,<V_4, V_t>\}
P1+={<Vs,V1>,<V1,V2>,<V2,V4>,<V4,Vt>}
后向弧:
P
1
−
=
{
<
V
2
,
V
1
>
}
P1-=\{<V_2, V_1>\}
P1−={<V2,V1>}
- 同一条弧在不同的链中可能是前向弧也可能是后向弧
链 P 2 = { < V s , V 2 > , < V 2 , V 1 > , < V 1 , V 3 > , < V 3 , V t > } P2=\{<V_s, V_2>, <V_2, V_1>, <V_1, V_3>,<V_3, V_t>\} P2={<Vs,V2>,<V2,V1>,<V1,V3>,<V3,Vt>}
如弧 < v 2 , v 1 > <v_2,v_1> <v2,v1>在链P1中为后向弧,在链P2中为前向弧
(2) 增广路
概念
满足一下两个条件的链P,成为增广路(增广链,可改进路):
- P+中每一条弧都是非饱和弧
链P上的所有前向弧 < u , v > <u, v> <u,v>上, 0 ≤ f ( u , v ) < c ( u , v ) 0\leq f(u, v) <c(u, v) 0≤f(u,v)<c(u,v) - P-中每一天弧都是非零流弧
链P上的所有后向弧 < u , v > <u, v> <u,v>上, 0 < f ( u , v ) ≤ c ( u , v ) 0<f(u,v)\leq c(u,v) 0<f(u,v)≤c(u,v)
成为增广路的原因
增广的规则
4. 残留容量和残留网络
在残留网络中,从源点到汇点的任意一条简单路径都对应一条增广路。
路径上每条弧容量的最小值即为能够一次增广的最大流量。
5. 割与最小割
6.1.2 最大流最小割定理
- 网络流是最大流的判定定理:
-
- 增广路定理:
设容量网络G(V, E)的一个可行流f, f为最大流的充要条件是在容量网络中不存在增广路。
- 增广路定理:
-
- 最大流最小割定理:
对容量网络G(V, E), 其最大流的流量等于最小割的容量
以上定理推算出一下四个等价结论:
- 最大流最小割定理:
-
- f是容量网络的最大流
- |f|等于容量网络最小割的容量
- 容量网络中不存在增广路径
- 残留网络G’中不存在从源点到汇点的路径
6.1.3 网络最大流求解
求容量网路的最大流有两大类算法:增广路算法(Augmenting Path Algorithm)和预流推进算法(Preflow-push Algorithm)
1. 增广路算法
-
思路:
根据增广路定理,从任何一个可行流开始,沿着增广路对网络进行增广,直到网络不存在增广路为止。 -
关键:寻找增广路和改进网络流
如何有效的找到增广路,并保证算法在有限次增广后一定终止。 -
基本流程
- 增广路算法分类:
- 标号算法
- 最短增广路算法
- 连续最短增广路算法(Dinic算法)
2. 预流推进算法
预留推进算法是从一个预流(Pre-flow)出发对活跃顶点沿着允许弧进行流量增广,每次增广称为一次推进(Push).
-
推进过程中满足条件:
满足流量限制条件
一般不满足流量平衡条件
是一个伪流 -
预流
从每个顶点(除了 V s 和 V t V_s和V_t Vs和Vt)流出的流量之和总是小于等于流入该顶点的流量之和,称这样的伪流为预流。 -
预留推进算法分类
- 一般预流推进算法
- 最高标号预流推进算法
6.1.4 增广路算法
1. 一般增广路算法–Ford-Fulkerson算法
Frod-Fulkerson算法寻找增广路和改进网络流的方法为标号法
-
标号法实例
(1) 标号法求最大流的实例1— 初始流为零流
(2) 标号法求最大流的实例2— 初始流为非零流 -
标号法运算过程
(1) 标号过程
标号分量: < v i , α > <v_i, \alpha> <vi,α>
v i v_i vi: 该分量指明它的标号来源
α \alpha α: 可改进量
顶点分类:
未标号顶点
已标号,未检查邻接节点
已标号,且已检查邻接顶点(即已经检查过它的所有邻接顶点,看是否能够标号)
(2) 调整过程
a. 采用“倒向追踪”法,以 α \alpha α分量按照第一个分量向前推荐,改进每一条弧上的流量。如下:
f ( u , v ) = { f ( u , v ) + α , < u , v > ∈ P + f ( u , v ) − α , < u , v > ∈ P − f ( u , v ) , < u , v > ∉ P f(u,v) = \begin{cases} f(u,v)+\alpha, & \text{$<u,v>\in P^+$} \\ f(u,v)-\alpha, & \text{$<u,v>\in P^-$} \\ f(u,v), & \text{$<u,v>\notin P $} \end{cases} f(u,v)=⎩ ⎨ ⎧f(u,v)+α,f(u,v)−α,f(u,v),<u,v>∈P+<u,v>∈P−<u,v>∈/P
b. 调整后去掉所有标号,并对新的可行流进行重新标号过程和调整过程。 -
标号法程序实现
(1) 图的定义格式:
输入:顶点个数n, 弧数m
每条弧的数据格式: u v c f (u: 起点 v:终点 c: 容量 f: 流量), 顶点序号0开始
存储格式:邻接矩阵
(2) 中间变量:
f
l
a
g
[
n
]
flag[n]
flag[n]: 顶点状态
-1: 未标记
0 : 已标记,未检查
1: 已标记,已检查
p
r
e
v
[
n
]
prev[n]
prev[n]: 标号的第一个分量,标号来源节点
a
l
p
h
a
[
n
]
alpha[n]
alpha[n]: 标号的第二个分量,改进量
q
u
e
u
e
[
n
]
queue[n]
queue[n]: 广度优先搜索使用的队列,qs和qe表示队头和队尾
(3) 标记策略: 广度优先搜索
- Ford-Fulkerson算法复杂度分析