算法设计技巧与分析(九):网络流(Network Flow)


网络流(Network Flow)

网络是一个四元组(G,s,t,c),其中G=(V,E)是一个有向图,s和t是两个分别称为源和汇的不同顶点,c(u,v)是一个容量函数,如果(u,v)属于E,则c(u,v)>0,否则c(u,v)=0,|V|=n,|E|=m。

网络流的性质

G中的流是顶点对上的实值函数f,具有以下四个条件:
对于任意一个时刻,设f(u,v)实际流量,则整个图G的流网络满足3个性质:

  1. 容量限制:对任意u,v∈V,f(u,v)≤c(u,v)。

  2. 反对称性:对任意u,v∈V,f(u,v) = -f(v,u)。从u到v的流量一定是从v到u的流量的相反值。

  3. 流守恒性:对任意u,若u不为S或T,一定有∑f(u,v)=0,(u,v)∈E。即u到相邻节点的流量之和为0,因为流入u的流量和u点流出的流量相等,u点本身不会"制造"和"消耗"流量。

  4. 在这里插入图片描述

割(cut)与流(flow)

割(cut){S,T}是顶点集V分成两个子集S和T的划分,当s属于S和t属于T。用c(S,T)表示的割{S,T}的容量为:
在这里插入图片描述
通过割{S,T}的流(flow),用f(S,T)表示:
在这里插入图片描述
因此,通过割{S,T}的流量是从S到T的边上的正流量之和减去从T到S的边上的正流量之和。

用|f|表示的流f的值:
在这里插入图片描述
故对于任何割{S,T}和流f,|f|=f(S,T)。最大流问题即为网络(G,s,t,c)设计一个函数f,使|f|为最大值。

余量函数(Residual Capacity Function)与余量图(Residual Graph)

给定具有容量函数c的G上的流f,f在顶点对集上的余量函数定义如下:
对于每对顶点u,v属于V,余量r(u,v)=c(u,v)-f(u,v)。流f的剩余图是有向图R=(V,Ef):
在这里插入图片描述
如果f(u,v)<c(u,v),则(u,v)和(v,u)都存在于R中。如果G中u和v之间没有边,则(u,v)和(v,u)都不存在于Ef中。因此|Ef|小于等于2|E|。

余量图的示例如下:

在这里插入图片描述

利用反向边,使程序有了一个后悔和改正的机会。

增广路径(Augmenting Path)

给定在G中的流f,增广路径p是残差图R中从s到t的有向路径。p的瓶颈容量(bottleneck capacity)是沿p的最小残差容量。p中的边数用|p|表示。

最大流最小割定理(max-flow-min-cut定理):设(G,s,t,c)为网络,f为G中的流。以下三种说法是等价的:

  • 有一个c(S,T)=|f|的割{S,T}。

  • f是G中的最大流量。

  • f没有增广路径。

下面给出求解最大流的两种算法:

一、The Ford-Fulkerson Method

前面的定理提出了一种通过迭代改进构造最大流的方法,不断地寻找一条任意扩张路径,并通过其瓶颈容量增加流量。

算法伪代码如下:

Input: 网络(G, s, t, c)
Output: 网络流
初始化余量图R
for (u,v) in E:
	f(u,v) = 0
while 在R中存在增广路径p:
	c = p的瓶颈容量
	for (u,v) in p:
		f(u,v) = f(u,v) + c
	更新余量图R

Ford-Fulkerson方法的时间复杂度为O(m |f*|),其中m是边数,|f*|是最大流的值,它是一个整数。当容量为整数时,该方法每次添加增广路径时最大流f都至少增加1,故总是能在最多|f|的步数下计算出最大流f*。且每一条增广路径都能在O(m)的时间内被找到,如利用DFS

但该算法在某些情况下表现不佳:

在这里插入图片描述

二、EK算法(Minimum path length augmentation)

在这里,我们考虑另一个启发式,增加了一些选择的路径。定义顶点v的级别(level),用level(v)表示,它是从s到v的路径中最少的边数。

给定有向图G=(V,E),级别图(level graph)L是(V,E’),其中V是可以从s到达的顶点集:
在这里插入图片描述
给定一个有向图G和一个源顶点s,它的级别图L可以很容易地用广度优先搜索来构造。

最小增广路径长度(MPLA)

MPLA选择最小长度的增广路径,并将当前流量增加等于路径瓶颈容量的量。该算法首先将流初始化为零流,然后将残差图R设置为原始网络。然后分阶段进行。每个阶段包括以下两个步骤:

(1) 根据残差图R计算级别图L。如果t不在L中,则停止;否则继续。

(2) 只要L中有一条从s到t的路径p,将现在的流增广p,从L和R中移除饱和边并相应地更新它们。

算法伪代码如下:

Input: 网络(G, s, t, c)
Output: 网络中的最大流
初始化余量图R
初始化级别图L
for (u,v) in E:
	f(u,v) = 0
while 在R中存在增广路径p://或是t在L中
	while 在L中存在增广路径p:
		c = p的瓶颈容量
		for (u,v) in p:
			f(u,v) = f(u,v) + c
		更新级别图L
	更新余量图R
	更新级别图L

对于n点m边的网络图,算法的时间复杂度为O(nm^2)

EK算法过程如下图所示:

在这里插入图片描述

  • 2
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值