文章目录
网络流(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个性质:
-
容量限制:对任意u,v∈V,f(u,v)≤c(u,v)。
-
反对称性:对任意u,v∈V,f(u,v) = -f(v,u)。从u到v的流量一定是从v到u的流量的相反值。
-
流守恒性:对任意u,若u不为S或T,一定有∑f(u,v)=0,(u,v)∈E。即u到相邻节点的流量之和为0,因为流入u的流量和u点流出的流量相等,u点本身不会"制造"和"消耗"流量。
-
割(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算法过程如下图所示: