图与网络
网络最大流基本概念
可行流需要满足的条件:
- 容量约束条件: 0 <= fij <= cij
- 流量约束条件:
- 每个中间点:接收的流量之和 = 发出的流量值和
- 发点和收点:发点发出流量之和 = 收点接收流量之和
若 μ \mu μ是网络中联结发点和收点的一条链,链的方向是发点到收点,链上的弧为:
- 前向弧:弧的方向与链的方向一致
- 后向弧:弧的方向与链的方向相反
设f是一个可行流, μ \mu μ是从发点到收点的一条链, μ \mu μ是增广链需要满足:
- 弧(Vi,Vj)是前向弧,则 0<= fij < cij, 即前向弧每一条弧是非饱和弧
- 弧(Vi,Vj)是后向弧,则 0< fij <= cij,则后向弧每一条弧是非零流弧
可行性流f*是最大流的充分必要条件是不存在发点到收点的增广链。
割集:将网络中的点集V分为两个非空的集合 V 1 V_1 V1 和 V 1 ‾ \overline{V_1} V1, 使得发点 V s ∈ V 1 , 收 点 V t ∈ V 1 ‾ V_s \in V_1,收点V_t \in \overline{V_1} Vs∈V1,收点Vt∈V1。则把弧集( V 1 , V 1 ‾ V_1,\overline{V_1} V1,V1)称之为是分离发点和收点的割集。
割集( V 1 . V 1 ‾ V_1.\overline{V_1} V1.V1)中所有的弧的容量之和成为割量,割量最小的割集称之为最小割集。
定理:网络的最大流量等于它的最小割量
割集容量:
算法内容:
流网络的定义:
容量限制: f ( u , v ) ≤ c ( u , v ) f(u,v)\leq c(u,v) f(u,v)≤c(u,v)
对称性: f ( u , v ) = − f ( v , u ) f(u,v) = -f(v,u) f(u,v)=−f(v,u)
流量限制:对于所有点除了源点和汇点, ∑ v ∈ V f ( u , v ) = 0 \sum_{v \in V} f(u,v) = 0 ∑v∈Vf(u,v)=0
==如何理解?==其实就是流入的等于流出的,这里的v指的是所有的点,结合第二条性质,原来从v到u的点(流入)被改成了-f(u,v)。
网络流的值: ∣ f ∣ = ∑ v ∈ V f ( s , v ) |f| = \sum_{v \in V}f(s,v) ∣f∣=∑v∈Vf(s,v),s是源点
网络流的性质:
-
f(X,X) = 0
证明: ∑ x ∈ X ∑ y ∈ X f ( x , y ) + ∑ y ∈ X ∑ x ∈ X f ( y , x ) = 0 \sum_{x\in X}\sum_{y\in X} f(x,y) + \sum_{y\in X}\sum_{x\in X}f(y,x) = 0 ∑x∈X∑y∈Xf(x,y)+∑y∈X∑x∈Xf(y,x)=0
-
f(X,Y) = -f(Y,X)
证明: ∑ x ∈ X ∑ y ∈ X ( f ( x , y ) + f ( y , x ) ) = 0 \sum_{x\in X}\sum_{y \in X}(f(x,y)+f(y,x))=0 ∑x∈X∑y∈X(f(x,y)+f(y,x))=0
-
f ( X ⋃ Y , Z ) = f ( X , Z ) + f ( Y , Z ) i f X ⋂ Y = ϕ f(X\bigcup Y,Z)=f(X,Z)+f(Y,Z) \quad if X \bigcap Y = \phi f(X⋃Y,Z)=f(X,Z)+f(Y,Z)ifX⋂Y=ϕ
f ( X ⋃ Y , Z ) = ∑ s ∈ X ⋃ Y ∑ t ∈ Z f ( s , t ) = ( ∑ s ∈ X + ∑ s ∈ Y ) ∑ t ∈ Z f ( s , t ) ∵ X ⋂ Y = ϕ = ∑ s ∈ X ∑ t ∈ Z f ( s , t ) + ∑ s ∈ Y ∑ t ∈ Z f ( s , t ) = f ( X , Z ) + f ( Y , Z ) f(X \bigcup Y,Z) = \sum_{s\in X \bigcup Y}\sum_{t\in Z} f(s,t) \\ =(\sum_{s\in X}+\sum_{s \in Y})\sum_{t \in Z} f(s,t) \\ \because X\bigcap Y = \phi \\ =\sum_{s \in X}\sum_{t \in Z}f(s,t) + \sum_{s \in Y}\sum_{t \in Z}f(s,t) \\ = f(X,Z)+f(Y,Z) f(X⋃Y,Z)=s∈X⋃Y∑t∈Z∑f(s,t)=(s∈X∑+s∈Y∑)t∈Z∑f(s,t)∵X⋂Y=ϕ=s∈X∑t∈Z∑f(s,t)+s∈Y∑t∈Z∑f(s,t)=f(X,Z)+f(Y,Z) -
∣ f ∣ = f ( V , t ) |f| = f(V,t) ∣f∣=f(V,t)
∣ f ∣ = f ( s , V ) = f ( V , V ) − f ( V − s , V ) = − f ( V − s , V ) = f ( V , V − s ) = f ( V , t ) + f ( V , V − s − t ) ∵ f ( V , V − s − t ) = ∑ s ∈ V ∑ t ∈ V − s − t f ( s , t ) = ∑ s ∈ V 0 = 0 ∴ ∣ f ∣ = f ( V , t ) |f| = f(s,V) \\ =f(V,V) - f(V-s,V) \\ =-f(V-s,V) \\ =f(V,V-s) \\ =f(V,t) + f(V,V-s-t) \\ \because f(V,V-s-t) = \sum_{s \in V}\sum_{t \in V-s-t} f(s,t) \\ =\sum_{s \in V} 0 \\ =0 \\ \therefore |f| = f(V,t) ∣f∣=f(s,V)=f(V,V)−f(V−s,V)=−f(V−s,V)=f(V,V−s)=f(V,t)+f(V,V−s−t)∵f(V,V−s−t)=s∈V∑t∈V−s−t∑f(s,t)=s∈V∑0=0∴∣f∣=f(V,t)
如果流量图有节点v,从源节点s到达该节点的路径不存在,则有最大流,从节点v流向其他节点的流为0,从其他节点流向v的流也为0.
任 意 u ∈ V : p ( u , v ) = 0 a n d p ( v , u ) = 0 任意u \in V: p(u,v) =0 \quad and \quad p(v,u) = 0 任意u∈V:p(u,v)=0andp(v,u)=0
设s能够到达的节点集合为
V
s
,
显
然
v
∉
V
s
V_s,显然v \notin V_s
Vs,显然v∈/Vs,
对
于
任
意
v
′
∈
V
−
V
s
,
s
无
法
到
达
v
′
对于任意v' \in V-V_s,s无法到达v'
对于任意v′∈V−Vs,s无法到达v′
f
(
V
−
V
s
,
V
)
=
0
f
(
V
−
V
s
,
V
s
)
=
0
任
意
x
∈
V
−
V
s
,
y
∈
V
s
:
p
(
x
,
y
)
=
0
f
(
V
−
V
s
,
V
−
V
s
)
=
0
任
意
w
,
z
∈
V
−
V
s
:
p
(
w
,
z
)
=
0
f(V-V_s,V) = 0 \\ f(V-V_s,V_s)=0\\ 任意 x\in V-V_s,y\in V_s: p(x,y) = 0 \\ f(V-V_s,V-V_s) = 0 \\ 任意 w,z \in V-V_s: p(w,z) = 0
f(V−Vs,V)=0f(V−Vs,Vs)=0任意x∈V−Vs,y∈Vs:p(x,y)=0f(V−Vs,V−Vs)=0任意w,z∈V−Vs:p(w,z)=0
残余网络
原图的容量变为严格为正的残余容量
c
f
(
u
,
v
)
=
c
(
u
,
v
)
−
f
(
u
,
v
)
>
0
E
f
≤
2
E
c_f(u,v) = c(u,v) - f(u,v) >0 \\ E_f \leq 2 E
cf(u,v)=c(u,v)−f(u,v)>0Ef≤2E
画法:
例子:
增广路径
增广路径是在增广网络 G f G_f Gf中的从源点到汇点的一条简单路径。
增广路径的容量是增广路径中的流的最小值。最大流能够增大通过提升p中的每一条边。
当流中不存在增广路径时,得到最大流。
这三个定理等价:
- 流的大小等于割量大小
- f时最大流
- f不包含增广路径
Ford&Fuklerson算法
首先初始化流量为0,找增广路径。
时间复杂度 O ( F ( n + m ) ) O(F(n+m)) O(F(n+m)),F是最大流,n是点的数量,m是边的数量。F要是很大,效率会很低。
主要就是画图,DFS原则,没啥好说的
Edmonds & Karp算法
BFS原理部分跳过
BFS(G,s)
for each vertex u in V[G]-{s}
color[u] <- white
d[u] <- +inf
front[u] <- null
color[s] <- gray
d[s] <- 0
front[s] <- null //初始化根节点
Q <- null
enqueue(Q,s) //入队
while Q != null
u <- dequeue(Q)
for each v in Adj[u] //u的邻接点
if color[v]=white
color[v]<-gray
d[v]<-d[u]+1 //父节点深度+1
front[v]<-u //记录父节点
enqueue(Q,v)
color[u] <- black //访问完毕
时间复杂度 O ( ∣ V ∣ + ∣ E ∣ ) O(|V|+|E|) O(∣V∣+∣E∣)
EK算法就是用BFS去找增广路径。时间复杂度 O ( ∣ V ∣ ∣ E ∣ 2 ) O(|V||E|^2) O(∣V∣∣E∣2)
EK算法的证明:你以为我会吗?
标号法寻找网络最大流(运筹学)
选择可用,方便些。
步骤:
- 找出一个可行流(若没有初始可行流,可设所有弧的流量fij=0)
- 标号以寻增广链
- 发点标号(0,+ ∞ \infty ∞)
- 选一个点
V
i
V_i
Vi已标号,并且另一端点
V
j
V_j
Vj没有标号的弧沿着某条链向收点检查。
- 若弧为前向弧,并且fij<cij,则Vj标号(Vj, θ j \theta_j θj), θ j = c i j − f i j \theta_j=c_{ij}-f_{ij} θj=cij−fij
- 若弧为后向弧,并且fji>0,则Vj标号(Vj, θ j \theta_j θj), θ j = f j i \theta_j = fji θj=fji
- 重复(2),当收点已经得到标号,说明找到一条增广链,依据标号点的第一个标号进行反向追踪得到增广链 μ \mu μ;若收点不能得到标号,说明不存在增广链,算法结束。
- 调整流量
- 求增广链上所有标号点第二个标号的最小值,得到调整量 θ = m i n ( θ j ) \theta = min (\theta_j) θ=min(θj)
- 调整流量:增广链上前向弧 f i j ′ = f i j + θ f_{ij}' = f_{ij} + \theta fij′=fij+θ;增广链的后向弧 f j i ′ = f j i − θ f_{ji}' = f_{ji} - \theta fji′=fji−θ
- 得到新的可行流之后,去掉所有标号,重复步骤二三,直到收点不能标号为止。
具体参考https://www.bilibili.com/video/BV1ir4y1S7SA?p=2