最小费用最大流问题
最小费用最大流问题是经济学和管理学中的一类典型问题。在一个网络中每段路径都有"容量"和"费用"两个限制条件下,此类问题的研究试图寻找出:流量从A到B,如何选择路径、分配经过路径的流量,可以达到所用的费用最小的要求。
最小费用最大流建立在最大流和网络流问题的基础之上。
最大流
在优化理论中,最大流问题涉及到在一个单源点、单汇点的网络流中找到一条最大的流。
每个边缘都标有容量,即可以携带的最大物品数量。 最大流问题是找出可以从顶点source到顶点sink总的物品数量(最大的那个)。
如上图所示,当0->1和2->1汇聚的时候不能超出1->3的值12(1的输出最大为12)。最后可以到达5的最大物品个数就是19+4=23。也就是每条边和每个顶点要满足:
- 每条边上的流量不超过每条边的给定容量。
- 除
source和sink之外,每个顶点的流入流等于流出流。
相关概念:可行流与增广链
-
有向连通图 V是顶点集,E是边集。
-
边的容量: (每条边的权值)
-
发点: 收点: 其他的点叫中间点。(或者说源点和汇点)
-
边有流量,集合 为G的一个流。(边上已经实际有流量了)
-
重点:为可行流满足:第一点:容量限制条件:对于任意一条边来说,实际的流量一点更要小于容量,即;
第二点:流量平衡条件:对于所有的中间节点来说,流入它的流量和从它流出的流量是相等的。即
-
对于收点和发点,有 ,W为总流量(源头流出的等于终点流入的,在中间节点流量没有损失)
-
为G上从到的链,规定到为链的方向,链上与方向一致的边叫前向边,与 方向相反的边成为后向边。
例:
前向边:
后向边:
-
若链中的前向边必有,后向边上必有,称是关于可行流的一条增广链。(前向边:流量<容量,后向边非零流)
构造一个可行流
括号前面的哪个是容量,后面哪个是实际流量。
以为例,流进3,流出总量也是3;发点流出4,收点流进4,所以当前网络图总流量W=4。当前的流是可行流。
再检查一下:
前向边: 流量小于容量
后向边: 后向边流量>0
此时链 是一条可增广链,也叫增广链,代表在这条链上,我们是可以增加流量的。
对增广链可做如下调整:
取
把流改成
前向边增加流量,后向边减少流量
由题意,上只能调整一个流量,此时对增广链做调整,调整后的可行流如图所示:
那么新的可行流是不是最大流呢?
最小割集
我们使用最小割集检验:
- 容量网络,顶点集V满足,且, 令:
称为分离的一个割集。
把V分成两半,一个是S一个是T,发点在集合S里,收点在集合T中。
例:;
和
所有边的起点都在集合S中,所有边得终点都在集合T中,这个(S,T)就是一个割集。
要想从起点走到终点的话,割集里的三条边是必经之路。
割集并不唯一。
- 割集(S,T)中所有边的容量之和成为该割集的最小容量;
在G的所有割集中,割集容量最小者称为G的最小割。(也就是网络图中能通过的最小的瓶颈部分,也就是漏桶中的那块最短板,要想让整个网络图的流量增加的话,一定要解决瓶颈部位的流量问题)
最大流,最小割定理
定义:在任意一个网络G中,从发点的最大流流量等于最小割的容量。
求最大流的标号算法:
设已有一个可行流,标号法分为两步:
- 标号过程(通过标号寻找增广链)
- 调整过程(沿增广链调整增加流量)
整个过程:
1.找可行流 2.找增广链(如果能找到增广链,执行第三步。如果找不到增广链,当前已经是最优解)3.调整
解最大流问题的Ford-Fulkerson解法
本文主要讲解最大流问题的Ford-Fulkerson解法。可以说这是一种方法,而不是算法,因为它包含具有不同运行时间的几种实现。该方法依赖于三种重要思想:残留网络,增广路径和割。
在介绍着三种概念之前,我们先简单介绍下Ford-Fulkerson方法的基本思想。首先需要了解的是Ford-Fulkerson是一种迭代的方法。
开始时,对所有的u,v属于V,f(u,v)=0(这里f(u,v)代表u到v的边当前流量),即初始状态时流的值为0。
在每次迭代中,可以通过寻找一个“增广路径”来增加流值。增广路径可以看做是从源点s到汇点t之间的一条路径,沿该路径可以压入更多的流,从而增加流的值。反复进行这一过程,直到增广路径都被找出为止。
残留网络
顾名思义,残留网络是指给定网络和一个流,其对应还可以容纳的流组成的网络。具体说来,就是假定一个网络G=(V,E),其源点s,汇点t。设f为G中的一个流,对应顶点u到顶点v的流。在不超过C(u,v)的条件下(C代表边容量),从u到v之间可以压入的额外网络流量,就是边(u,v)的残余容量(residual capacity),定义如下:
r(u,v)=c(u,v)-f(u,v)
举个例子,假设(u,v)当前流量为3/4,那么就是说c(u,v)=4,f(u,v)=3,那么r(u,v)=1。
我们知道,在网络流中还有这么一条规律。从u到v已经有了3个单位流量,那么从反方向上看,也就是从v到u就有了3个单位的残留网络,这时r(v,u)=3。可以这样理解,从u到v有3个单位流量,那么从v到u就有了将这3个单位流量的压回去的能力。
所以后向边可以把流量压回去给前向边
我们来具体看一个例子,如下图所示一个流网络
其对应的残留网络为:
增广路径
在了解了残留网络后,我们来介绍增广路径。已知一个流网络G和流f,增广路径p是其残留网络Gf中从s到t的一条简单路径。形象的理解为从s到t存在一条不违反边容量的路径,向这条路径压入流量,可以增加整个网络的流值。上面的残留网络中,存在这样一条增广路径:
其可以压入4个单位的流量,压入后,我们得到一个新的流网络,其流量比原来的流网络要多4。这时我们继续在新的流网络上用同样的方法寻找增广路径,直到找不到为止。这时我们就得到了一个最大的网络流。
流网络的割
上面仅仅是介绍了方法,可是怎么证明当无法再寻找到增广路径时,就证明当前网络是最大流网络呢?这就需要用到最大流最小割定理。
首先介绍下,割的概念。流网络G(V,E)的割(S,T)将V划分为S和T=V-S两部分,使得s属于S,t属于T。割(S,T)的容量是指从集合S到集合T的所有边(有方向)的容量之和(不算反方向的,必须是S-àT)。如果f是一个流,则穿过割(S,T)的净流量被定义为f(S,T)(包括反向的,SàT的为正值,T—>S的负值)。将上面举的例子继续拿来,随便画一个割,如下图所示:
割的容量就是c(u,w)+c(v,x)=26
当前流网络的穿过割的净流量为f(u,w)+f(v,x)-f(w,v)=12+11-4=19
显然,我们有对任意一个割,穿过该割的净流量上界就是该割的容量,即不可能超过割的容量。所以网络的最大流必然无法超过网络的最小割。
首先,我们必须了解一个特性,根据上一篇文章中讲到的最大流问题的线性规划表示时,提到,流网络的流量守恒的原则,根据这个原则我们可以知道,对网络的任意割,其净流量的都是相等的。具体证明是不难的,可以通过下图形象的理解下,
现在来证明当残留网络Gf中不包含增广路径时,f是G的最大流。
假设Gf中不包含增广路径,即Gf不包含从s到v的路径,定义S={v:Gf中从s到v存在一条通路},也就是G**f中s能够有通路到达的点的集合,显然这个集合不包括t,因为s到t没有通路。这时,我们令T=V-S。那么(S,T)就是一个割。**如下图所示:
么,对于顶点u属于S,v属于T,有f(u,v)=c(u,v)。否则(u,v)就存在残余流量,因而s到u加上u到v就构成了一条s到v的通路,所以v就必须属于S,矛盾。因此这时就表明当前流f是等于当前的割的容量的,因此f就是最大流。
Ford-Fulkerson方法
Ford-Fulkerson方法的正确性依赖于这个定理:当残存网络中不存在一条从s到t的增广路径,那么该图已经达到最大流。这个定理的证明及一些与其等同的定理可以参考《算法导论》。
Ford-Fulkerson方法的伪代码如下。其中<u,v>代表顶点u到顶点v的一条边,<u,v>.f表示该边的流量,c是边容量矩阵,c(i,j)表示边<i,j>的容量,当边<i,j>不存在时,c(i,j)=0。e为残存网络矩阵,e(i,j)表示边<i,j>的值,当边<i,j>不存在时,e(i,j)=0。E表示边的集合。f表示流网络。
Ford-Fulkerson伪代码
for <u,v> ∈ E
<u,v>.f = 0//初始化流量为0
while find a route from s to t in e
m = min(<u,v>.f, <u,v> ∈ route)
for <u,v> ∈ route
if <u,v> ∈ f
<u,v>.f = <u,v>.f + m
else
<v,u>.f = <v,u>.f - m
Ford-Fulkerson方法首先对图中的所有边的流量初始化为零值,然后开始进入循环:如果在残存网络中可以找到一条从s到t的增广路径,那么要找到这条这条路径上值最小的边,然后根据该值来更新流网络。
Ford-Fulkerson有很多种实现,主要不同点在于如何寻找增广路径。最开始提出该方法的Ford和Fulkerson同学在其论文中都是使用广度优先搜索实现的,其时间复杂度为O(VE),整个算法的时间复杂度为O(VE^2)。
-
find an augmenting path
-
compute the bottleneck capacity
-
augment each edge and total flow
-
我们需要输入点数和边数构造网络。
-
边包括起点、终点、流量和最大容量
-
我们需要构造残留网络,增广路径
-
残留网络的边包括起点终点和流量