信息学奥赛 网络流算法介绍与分析
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
例2.一个直观的想法
s (4,4) (2,2) v1 v2 (3,3)
(0,4)
t
(2,2)
如果多推了一些流量, 我们可以再把它推回 来. (如e(v2)=3,但这3 个单位的赢余已经没 地方去了,只能推回 来.)(沿着后向弧)这副 图是原网络而不是残 量网络,因此没把后项 弧画出来)
程序没有全局观?!
k的上界
如果要让一条曾经的临界边(u,v)再次成为临界边, 则必须有一条增广路径包含边(v,u).因为每次增广 之后临界边就消失,要让他再次成为临界边至少要 让他再次在残量网络中出现,即(v,u)要被增广. 结合上面的结论可以证明,当算法取的增广路总是 残量网络中的最短路,任意一条边成为临界边的次 数至多为n/2-1. 因此,增广路算法的效率为O(f*m) = O(km^2) = O(nm^2). (这只是个上界,一般情况是达不到的) 备注中为增广路算法我的代码实现。数组u是残量 网络的容量。
为什么要建立后向弧
当然,可以把上面说的情况当成特殊情况 来处理。但使用后向弧可以使编程简单 许多. 注意,后向弧只是概念上的,在程序中后向 弧与前向弧并无区别.
增广路
增广路定义:在残 量网络中的一条从 s通往t的路径,其 中任意一条弧 (u,v),都有 r[u,v]>0。 绿色的即为一条增 广路。
例1
s 3 4 2 2
v1 2
t
v2
2
从残量网络中可以 清楚地看到: 因为存在边(s,v2) = 3,我们知道从S到 v2还可以再增加2 单位的流量; 因为存在边(v1,t) = 2,我们知道从v1到t 还可以再增加2单 位的流量。
后向弧
s 3 4 2 2
v1 2
t
v2
2
其中像(v1,s)这样的边 称为后向弧,它表示从v1 到s还可以增加4单位的 流量。 但是从v1到s不是和原 网络中的弧的方向相反 吗?显然“从v1到s还 可以增加4单位流量” 这条信息毫无意义。那 么,有必要建立这些后 向弧吗?
引导机制
把流推错可能导致产生的流不是最大流.
我们需要有一个能引导流的推进方向的 机制,当它发现我们先前的推进是错误的 时候,能沿着正确的后向弧回推回来. 由于建立了后向弧,正推与回推在程序中 并无却别,都是在推残量网络中的一条 边.
高度标号的引导作用
高度标号就是这样的一个引导机制. 我们规定,如果一个结点溢出了,那么他的 多余的流量只能流向高度标号比自己低 的结点.(“水往低处流”) 当然,高度标号不可能事先知道往哪些方 向推才是正确的.它将按情况动态改变自 己的值,从而正确地引导流向.
s 3 4 v1 2 2 v2
2
t
2
增广路算法
增广路算法:每次用BFS找一条最 短的增广路径,然后沿着这条路径 修改流量值(实际修改的是残量网 络的边权)。当没有增广路时,算 法停止,此时的流就是最大流。 下面证明增广路算法的正确性.
将f,c,r的定义域扩展为点集
(在以后的叙述中,大写字母X,Y,S,T一般均表示 点集) f ( x, y) 点集间的流量和: f(X,Y) =
xX yY
即:X中的任意一点与Y中的任意一点组成的所 有边上的流量之和.(边的方向为从X中的结点到 Y中的结点) c,r等函数都有类似的定义.(点集间的容量和、 点集间的残量网络容量和)
结论1
1.f(X,X) = 0 (由流量反对称性) 2. f(X,Y) = -f(Y,X) (有流量反对称性) 3.f(X ∪ Y,Z) = f(X,Z) + f(Y,Z) (显然) 4.f(X,Y ∪ Z) = f(X,Y) + f(X,Z) (显然)
割的定义
一个割(S,T)由两个点集S,T组成. S+T = V s 属于 S. t 属于 T. 提出割的定义,是为后面的证明作铺垫.
结论2(点集总流量为零)
不包含s和t的点集,于它相关联的边上的流量之 和为0. [ f ( x, y)] 证明: f(X,V) =
xX yY
=
xX
[0]
f*
对于随机数据,f*的值与n比较接近.当m不 太大也不太小时,f*的值较大. (我出随机数据的方法是:固定地为源点和 汇点连上一些边,然后随机生成中间的边. 中间的边保证边的两个端点的编号相差 不太大.这与不少题目转成网络流后形成 的图相似)
f*的理论上界
考虑每一次增广,至少有一条边的r(u,v) 值等于增广路径的流量.称这些边为临界 边.增广之后,这条临界边就在残量网络中 消失. 假设一条临界边对应一次增广(事实上很 难达到这样),令每条边成为临界边的次数 为k(u,v),则有f* = O(m*k). k的上界?
为什么要建立后向弧
显然,例1中的画出来的不是一个最大流。 但是,如果我们把s -> v2 -> v1 -> t这条路径 经过的弧的流量都增加2,就得到了该网络的最 大流。 注意到这条路径经过了一条后向弧:(v2,v1)。 如果不设立后向弧,算法就不能发现这条路径。 从本质上说,后向弧为算法纠正自己所犯的错 误提供了可能性,它允许算法取消先前的错误 的行为(让2单位的流从v1流到v2)
1、f是最大流 2、残量网络中找不到增广路径 3、|f| = c(S,T)
3 -> 1证明: |f| <= c(S,T) (辅助定理4) 因为我们已经有|f| = c(S,T),如果最大流的 流量是|f|+d (d>0),那么|f|+d肯定不能满 足上面的条件.
增广路算法的正确性
如果 最大流最小割定理不能从2推出3,那
重标号操作
当一个结点有赢余(溢出了), 周围却没有 高度比它低的结点时候,我们就用重标号 操作使它的标号上升到比周围最低的结 点略高一点,使他的赢余能流出去. 赢余千万不能困在某个结点里.对于任意 一个非源非汇的结点,有赢余就意味着 它不满足流量平衡,也就意味着整个网 络流不是一个真正合法的网络流。
最大流最小割定理
网络流中这三个条件等价(在同一个时 刻): 1、f是最大流 2、残量网络中找不到增广路径 3、|f| = c(S,T)
1、f是最大流 2、残量网络中找不到增广路径 3、|f| = c(S,T)
1 -> 2证明: 显然.假设有增广路径, 由于增广路径的容量至少为1,所以 用这个增广路径增广过后的流的流 量肯定要比f的大,这与f是最大流矛 盾.
重标号操作
对于例2的这种情况,v2中过多的赢余最 终会沿着(v2,v1)、(v2,s)流回去(虽然他 们一开始流错了方向,但后来又被回推,等 于说是被改正了)。
只有当非源非汇的结点中的赢余全部流 到汇点或流回源点后,这个流才重新合 法。
高度函数
高度函数h(v)返回一个v的高度标号。 高度函数有三个基本条件:
uV
只要满足这三个性质,就是一个合法的网络 流.
最大流问题
定义一个网络的流量(记为|f|)=
f ( s, v )
vV
最大流问题,就是求在满足网络流性质 的情况下,|f|的最大值。
残量网络
为了更方便算法的实现,一般根据原网 络定义一个残量网络。其中r(u,v)为残量 网络的容量。 r(u,v) = c(u,v) – f(u,v) 通俗地讲:就是对于某一条边(也称 弧),还能再有多少流量经过。 Gf残量网络,Ef表示残量网络的边集.
(0,4)
t
(0,2)
大致的思路:从源点出发, 逐步推进。 称当前状态下不满足流量 平衡的结点为“溢出的结 点”.(对于结点u,f(V,u) > 0) 令e(u) = f(V,u),称为u点的 赢余,直观地描述,就是 “流入的比流出的多多 少”。e(v1)=4,e(v2)=3。 不断将溢出的结点中的赢 余往后继点推进,直到赢余 都聚集在t.
网络的流量小于等于任意一个割的容量.(注意 这个与辅助定理3的区别.这里是容量) 即|f| <= c(S,T) f ( x, y) xS yT 证明: |f| = f(S,T) = (由定义)
c( x, y)
<=
xS yT
(由流量限制)
= c(S,T)
1、f是最大流 2、残量网络中找不到增广路径 3、|f| = c(S,T)
s
(4,4) (0,3)
(2,2) v1 v2
(2,4) (2,2) t
一个简单的 例子.网络可 以被想象成 一些输水的 管道.括号内 右边的数字 表示管道的 容量,左边的 数字表示这 条管道的当 前流量.
网络流的三个性质
1、容量限制: f[u,v]<=c[u,v] 2、反对称性:f[u,v] = - f[v,u] 3、流量平衡: 对于不是源点也不是汇点的 任意结点,流入该结点的流量和等于流出该 结点的流量和。 结合反对称性,流量平衡也可以写成: f (v, u) 0
h(s) = |V| h(t) = 0 对于Ef(残量网络)中的每一条边(u,v),(r(u,v)>0) h(u) <= h(v) + 1
这第三个条件看上去有些奇怪.既然r(u,v)>0,那就表示 从u到v还可以增加流量,那h(u)就应该比h(v)高才对.的 确,我们后面还将规定,只有在h(u)>h(v)的时候才能应 用推进操作(将一个结点的盈余推进到另一个结点的操 作).而高度函数为了满足其合法性,还要满足上述的这 三个条件.后面我们将利用这三个条件证明预流推进算 法的正确性。
(由流量平衡)
=0
结论3
任意割的流量等于整个网络的流量. 证明: f(S,T) = f(S,V) – f(S,S) (由辅助定理1) = f(S,V) (由辅助定理1) = f(S,V) + f(S – s,V) (同上) = f(s,V) (由辅助定理2) = |f| (由|f|的定义)
结论4
网络流
杭州学军中学 魏越闽
一些符号和定义
V表示整个图中的所有结点的集合. E表示整个图中所有边的集合. G = (V,E) ,表示整个图. s表示网络的源点,t表示网络的汇点. 对于每条边(u,v),有一个容量c(u,v) (c(u,v)>=0) 如果c(u,v)=0,则表示(u,v)不存在在网络中。 如果原网络中不存在边(u,v),则令c(u,v)=0 对于每条边(u,v),有一个流量f(u,v).
s (4,4) (2,2) v1 v2 (3,3)
(0,4)
t
(2,2)
此时e(v2)=3.正确的回 推法是往(v2,s)推1,往 (v2,v1)推2,然后使得这 2个单位的赢余可以从 (v1,t)推到t上。 但程序没有全局观,它 万一往(v2,s)推了3个单 位怎么办?我们总不能 尝试所有的可能性吧, 那样就变成搜索了.
预流推进算法
下面将介绍一个更直观且时间效率 更优的算法.
一个直观的想法
如果给你一个网络流,让你手算出它的最 大流,你会怎么算? 一般人都会尝试着从源点出发,让每条边 的流量尽可能得大,然后一点点往汇点推, 直到遇到一条比较窄的弧,原先的流量过 不去了,这才减少原先的流量.
例2.一个直观的想法
s Biblioteka Baidu4,4) (0,2) v1 v2 (3,3)
原网络 (a,b)表 示(流量f,容量c)
图1 s (4,4) v1 (2, 2) (0,3)
例1
图2
s
3 4 v2
v1
2
2 2
2
v2
(2,4)
t
(2,2)
t 残量网络(如果网络中一条边的容量为0,则 认为这条边不在残量网络中。r(s,v1)=0,所以 就不画出来了。另外举个例子:r(v1,s) = c(v1,s) – f(v1,s) = 0 – (-f(s,v1)) = f(s,v1) = 4.
么存在这样一种可能性: 尽管找不到增广路径了,但由于前面的错 误决策,导致f还没有到达最大流,却不能 通过修改当前流来得到最大流. 但由于最大流最小割定理的三个条件互 相等价(1->2,2->3,3->1), 一个流是最大 流当且仅当它没有增广路径.
增广路算法的效率
设n = |V|, m = |E| 每次增广都是一次BFS,效率为O(m) 所以,总共的时间复杂度为O(m*f*) 其中f*为增广次数. 怎么求f*?
2 -> 3证明: 定义S = s ∪ {v | 在残量网络中s 到v有一条路径} ; T = V- S. 则 (S,T) 是一个割. |f| = f(S,T) (由辅助定理3) 而且,r(S,T) = 0. 假设不为0,则在残量网络中, 两个集合间必定有边相连,设在S的一端为v,在 T的一端为u. 那么,s就可以通过v到达u,那么根 据S的定义,u就应该在S中.矛盾. 所以,|f| = f(S,T) = c(S,T) – r(S,T) = c(S,T)