网络流算法专题ppt课件

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

预流推进算法流程
算法过程prepare(),即首先将与s相连的边设为满流, 并将这时产生的活动结点加入队列Q。这是算法的开 始。
以后便重复以下过程直到Q为空:
(1).选出Q的一个活动顶点u。并依次判断残量网络G'中 每条边(u, v),若h(u) = h(v) + 1,则顺着这里条边推流, 直到Q变成非活动结点(不存在多余流量)。(Push推 流过程)
(2).如果u还是活动结点。则需要对u进行重新标号: h(u) = min{h(v) + 1},其中边(u,v)存在于G' 中。然后再 将u加入队列。(relable过程)
可以证明,通过以上算法得到的结果就是最大流。
预流推进算法示例
顶点u的通过量g(u): 剩余图中,找入边权和与出边权和的较小值 增广时,每次找一个通过量最小的点v,从点v 向源点“推”大小为g(v)的流量 向汇点“拉”大小为g(v)的流量 尽量使剩余图中的边饱和
算法可描述为:
第1步. 令f为零流。 第2步. 若无最小费用可改进路,转第5步;否则找到最小费
用可改进路,设为P。 第3步. 根据P求delta(改进量)。 第4步. 放大f。转第2步。 第5步. 算法结束。此时的f即最小费用最大流。
inc(flow[i, j], delta) else
dec(flow[j, i], delta); until i = 1; {放大网络流} until false; end;
利用找增广路的其他流量算法
增广路的思想在于每次从源点搜索出一条前往汇点的 增广路,并改变路上的边权,直到无法再进行增广:
则称之为网络流图,记为G = (V, E, C)
可行流
可行流 对于网络流图G,每一条弧(i,j)都给定一个非负数fij,这 一组数满足下列三条件时称为这网络的可行流,用f表示 它。
1. 每一条弧(i,j)有fij≤Cij 2. 流量平衡
除源点S和汇点T以外的所有的点vi,恒有: ∑j(fij)= ∑k(fjk) 该等式说明中间点vi的流量守恒,输入与输出量相等。 3.对于源点S和汇点T有 , ∑i(fSi)= ∑j(fjT)= V(f)
剩余图(残余网络)
剩余图G’=(V,E’) 流量网络G=(V,E)中,对于任意一条边(a,b),若 flow(a,b)<capacity(a,b) or flow(b,a)>0 则(a,b)∈ E’
可以大小

有 向
Capacity=5 Flow=2
=8+4+4+1=17
流量算法的基本理论
定理1:对于已知的网络流图,设任意一可行流为f, 任意一割切为(U, W),必有:V(f) ≤ C(U, W)。
定理2:可行流f是最大流的充分必要条件是:f中不 存在可改进路。
定理3:整流定理。 如果网络中所有的弧的容量是整数,则存在整数值 的最大流。
else if flow[j, i] > 0 then last[j] := -i; {反向弧} check[i] := true; until last[n] <> 0;
if last[n] = 0 then break; delta := maxint; i := n; repeat
j := i; i := abs(last[j]); if last[j] > 0 then
设P是流f的可改进路,定义∑<vi,vj>∈P+ Wij - ∑<vi,vj>∈P- Wij 为 P的费用(为什么如此定义?) 如果P是关于f的可改进路中费用最小的,就称P是f的最 小费用可改进路。
费用流算法
求最小费用最大流的基本思想是贪心法。即:对于流f, 每次选择最小费用可改进路进行改进,直到不存在可 改进路为止。这样的得到的最大流必然是费用最小的。
若有向图G=(V,E)满足下列条件:
1. 有且仅有一个顶点S,它的入度为零,即d-(S) = 0,这个 顶点S便称为源点,或称为发点。
2. 有且仅有一个顶点T,它的出度为零,即d+(T) = 0,这个 顶点T便称为汇点,或称为收点。
3. 每一条弧都有非负数,叫做该边的容量。边(vi, vj)的容 量用cij表示。
DINIC算法演示:
3 源点
4
2
3
3 2
1
找到增广路路线, 2 (红色路线)
汇点
2
5
对增广路进行增广, 增广后退回到源点
2 汇点
找到增广路路线, (红色路线)
2 汇点
3
对增广路进行增广, 增广后退回到源点, 再无增广路线
汇点 1
用预流推进办法求网络流
预流推进算法给每一个顶点一个标号h(v),表示该点 到t的最短路(在残量网络中)。
3
7
4
8
5 g(u)=12
用预流推进方法的一些网络流算法
预流推进的算法核心思想是以边为单元进行推流操作:
一般的预流推进算法:在剩余图中,维护一个预流,不断对 活跃点执行push操作,或者relable操作来重新调整这个预流, 直到不能操作。 O(nm2)
先进先出预流推进算法:在剩余图中,以先进先出队列维护 活跃点。 O(n3)
一般增广路方法:在剩余图中,每次任意找一条增广路径 增广。O(nmU)
容量缩放增广路方法:在剩余图中,每次任意找一条最大可 增广容量和的增广路径增广。O(nm*logU)
最短增广路方法(MPLA):在剩余图中,每次任意找一条含 结点数最少的增广路径增广。O(nm2)
连续最短增广路方法(DINIC):在剩余图中,每次BFS找 增广路径增广路径时,记录每个点的距离标号。在距离标 号最短路图上,不断dfs找增广路,即一次标号,多次增广。 O(n2m)
i := 0; repeat
inc(i) until (i > n) or (last[i] <> 0) and not check[i]; {找到一个已检查而未标号的点} if i > n then break; for j := 1 to n do if last[j] = 0 then if flow[i, j] < limit[i, j] then last[j] := i {正向弧}
第4步(构造最小割),这时现行流是最大的,若把所有标号的 集合记为S,所有未标号点的集合记为T,便得到最小割(S,T)。
实例
复杂度分析
设图中弧数为m,每找一条增广轨最多需要进行2m次弧 的检查。如果所有弧的容量为整数,则最多需要v(其 中v为最大流)次增广,因此总的计算量为O(mv)。
procedure maxflow; {最大流} var
费用流定义
设有带费用的网络流图G = (V, E, C, W),每条弧<Vi, Vj> 对应两个非负整数Cij、Wij,表示该弧的容量和费用。 若流f满足:
1. 流量V(f)最大。 2. 满足a的前提下,流的费用Cost(f) =∑<i,j>∈E (fij * Wij)最小。
就称f是网络流图G的最小费用最大流。 最小费用可改进路
最高标号预流推进算法:在剩余图中,每次检查最高标号的 活跃点,需要用到优先队列。 O(n2m1/2)
费用流
流最重要的应用是尽可能多的分流物
资,这也就是我们已经研究过的最大
流问题。然而实际生活中,最大配置
方案肯定不止一种,一旦有了选择的 余地,费用的因素就自然参与到决策
V1 (6,3)
中来。
S
(5,4) T
定理4:最大流最小割定理。 最大流等于最小割,即max V(f) = min C(U, W)。
最大流算法
第1步,令x=(xij)是任意整数可行流,可能是零流,给s一个永 久标号(-, ∞)。
第2步(找增广路),如果所有标号都已经被检查,转到第4步。
找到一个标号但未检查的点i, 并做如下检查,
可增广路
给定一个可行流f={fij}。若fij = Cij,称<vi, vj>为饱和弧;否则 称<vi, vj>为非饱和弧。若fij = 0,称<vi, vj>为零流弧;否则 称<vi, vj>为非零流弧。
定义一条道路P,起点是S、终点是T。把P上所有与P方向一 致的弧定义为正向弧,正向弧的全体记为P+;把P上所有 与P方向相悖的弧定义为反向弧,反向弧的全体记为P-。
对每一个弧(i,j),如果xij<Cij, 且j未标号,则给j一个标号(+i, δ(j) ),其中, δ(j)=min{Cij-xij , δ(i) }
对每一个弧(j, i),如果xji>0,且j未标号,则给j一个标号(-i, δ(j) ),其中, δ(j)=min{xji , δ(i) }
第3步(增广),由点t开始,使用指示标号构造一个增广路,指 示标号的正负则表示通过增加还是减少弧流量来增加还是减 少弧流量来增大流量,抹去s点以外的所有标号,转第二步继 续找增广轨。
对于弧尾在U,弧头在W的弧所构成的集合称之为割切, 用(U,W)表示。把割切(U,W)中所有弧的容量之 和叫做此割切的容量,记为C(U,W),即:
C(U,W) cij iU jW
割切示例
❖ 上例中,令U = {S, V1},则W = {V2, V3, V4, T},那么, ❖ C(U, W) = <S, V2> + <V1, V2> + <V1, V3>+<V1, V4>
第一步hights()过程,就是BFS出初始最短路,计算出每 一个顶点的h(v)。
预流推进算法的特征是运用了预流来加快运算。预流 说明图中的节点(除s, t),仅需要满足流入量 >= 流出量。 其中流入量>流出量的结点,我们称之为活动节点。我 们的算法就是不断地将活动结点,变为非活动结点, 使得预流成为可行流。
x := limit[i, j] - flow[i, j] else
x := flow[j, i]; if x < delta then delta := x; until i = 1; {求改进量} i := n; repeat j := i; i := abs(last[j]); if last[j] > 0 then
Capacity=2 Flow=2
Capacity=6 Flow=2

剩 余
3 2
2
4 2
剩余图中,每条边都可以沿其方向增广
剩余图中,从源点到汇点的每一条路径都对应一条 增广路
割切
G = (V, E, C)是已知的网络流图,设U是V的一个子集,W = V\U,满足S ∈ U,T∈W。即U、W把V分成两个不相交 的集合,且源点和汇点分属不同的集合。
图论算法 ---最大流问题
运输网络
现在想将一些物资从S运抵T,必须经过一些中转站。连接中 转站的是公路,每条公路都有最大运载量。
每条弧代表一条公路,弧上的数表示该公路的最大运载量。 最多能将多少货物从S运抵T?
4
V1
4
V3 7
S
1 4
26
T
8 V2
2
V4 3
公路运输图
基本概念
这是一个典型的网络流模型。为了解答此题,我们先 了解网络流的有关定义和概念。
譬如在图中,P = (S, V1, V2, V3, V4, T),那么
P+ = {<S, V1>, <V1, V2>, <V2, V3>, <V4, T>}
P- = {<V4, V3>}
给定一个可行流f,P是从S到T的一条道路,如果满足:
fij是非饱和流,并且<i,j>∈ P+ , fij是非零流,并且<i,j>∈ P那么就称P是f的一条可增广路。之所以称作“可增广”, 是因为可改进路上弧的流量通过一定的规则修改,可以令 整个流量放大。
右图是一个最简单的例子:弧上标的 两个数字第一个是容量,第二个是费 用。这里的费用是单位流量的花费, 譬如fs1=4,所需花费为3*4=12。
(3,7)
(8,2)
V2
费用流问题
容易看出,此图的最大流(流量是8) 为:fs1 = f1t = 5, fs2 = f2t = 3。所以它的 费用是:3*5+4*5+7*3+2*3 = 62。
i, j, delta, x : integer; last : tline; {可改进路中的前趋} check : array[0 .. maxn] of boolean; {检查数组} begin repeat fillchar(last, sizeof(last), 0); fillchar(check, sizeof(check), false); last[1] := maxint; repeat
相关文档
最新文档