运筹学—最大流模型

上两篇文章,我介绍了最短路径中的两种算法:
最短路径算法——清晰简单的弗洛伊德算法(Floyd)
最短路径算法——简单明了的迪杰斯特拉算法(Dijkstra)
这篇文章,我来简单介绍一下最大流模型!

最大流模型

\qquad 很多的数学模型往往来源于生活问题,本文介绍其中一个问题借此引出最大流模型,让读者能够更好地了解模型的背景以及应用。
\qquad 现有一管道网络用于运输原油,将原油从油井运输到提炼厂,为了在网络中顺畅地输运原油,需要在中间合适的距离安装增压泵站,每一段管道有一个有限的最大原油流量(容量),每段管道可以是单向,也可以是双向,取决于它的原始设计。那么如何确定从油井到提炼厂原油的最大流量?
\qquad 下面给定双向弧的相关概念:
\qquad 给定弧 ( i , j ) (i,j) (i,j),其中 i < j i<j i<j,用符号 ( C ‾ i j , C ‾ j i ) (\overline{C}_{ij},\overline{C}_{ji}) (Cij,Cji)表示两个方向 i → j , j → i i→j,j→i ijji弧上的容量。为了更清晰地描述,把 C ‾ i j \overline{C}_{ij} Cij放在靠近节点 i i i的一边,把 C ‾ j i \overline{C}_{ji} Cji放在靠近节点 j j j的一边,如下图所示。
C ‾ i j 表 示 从 i → j 的 弧 上 的 容 量 , C ‾ j i 表 示 从 j → i 的 弧 上 的 容 量 \overline{C}_{ij}表示从i→j的弧上的容量,\overline{C}_{ji}表示从j→i的弧上的容量 CijijCjiji

1 枚举割

\qquad 割(cut) 是一部分弧的集合,如果将这些弧从网络中删除,就会断开源点和汇点之间所有的流。割的容量等于这个割中所有弧上容量的和。在网络中所有可能的割中,最小容量的割就对应了这个网络的最大流

例子

如下图网络,按照上述表示方法对每一条双向弧都标上了容量。例如,对于弧(3,4),从节点3到节点4的流量限制为10单位,从节点4到节点3为5单位。我直接在图中,标出了该网络的3个割:
在这里插入图片描述

图中3个割的容量如下表:

相应的弧
容量
1
(1,2),(1,3),(1,4)
20+30+10=60
2
(1,3),(1,4),(2,3),(2,5)
30+10+40+30=110
3
(2,3),(3,5),(4,5)
30+20+20=70

从表中可以看出,该网络最大流不超过60个单位。枚举所有割,对于小型网络是可行的,但是对于比较复杂的网络,效率就很低了,所以需要寻找其他算法。

2 最大流算法

2.1 原理

\qquad 最大流算法的核心思想是:从网络中寻找从源点到汇点具有的流的突破路径
\qquad ( i , j ) (i,j) (i,j)上的初始容量 ( C ‾ i j , C ‾ j i ) (\overline{C}_{ij},\overline{C}_{ji}) (Cij,Cji),当给定一个流并找到突破路径后,需要对每条弧上的容量进行修改,修改后的容量称为剩余容量 ( c i j , c j i ) (c_{ij}, c_{ji}) (cij,cji)。 如果节点 j j j从节点 i i i接收到一个流,那么给节点 j j j标号为 [ a j , i ] [a_j,i] [aj,i](节点 j j j的表示)。其中 a j a_j aj表示从节点 i i i流到节点 j j j的量, i i i表示流的来源是节点 i i i

2.2 步骤

第1步: 首先将所有弧 ( i , j ) (i,j) (i,j)的剩余容量设为初始容量,即 ( c i j , c j i ) = ( C ‾ i j , C ‾ j i ) (c_{ij}, c_{ji}) = (\overline{C}_{ij},\overline{C}_{ji}) (cij,cji)=(Cij,Cji).取 a 1 = ∞ a_1=\infty a1=,则源点1标号为 [ ∞ , − ] [\infty,-] [,]. 令 i = 1 i=1 i=1,进入第2步。

第2步: 确定集合 S i S_i Si,它是节点 i i i通过剩余容量为正的弧能够直接到达的所有未标号的节点 j j j的集合。如果 S i = ∅ S_i=\emptyset Si=,进入第3步;否则,进入第4步。

第3步: 确定 k ∈ S i k\in S_i kSi,使之满足 c i k = m a x j ∈ S i { c i j } c_{ik}= \mathop{max}\limits_{j\in S_i}\{c_{ij}\} cik=jSimax{cij}. 令 a k = c i k a_k=c_{ik} ak=cik,并且给节点 k k k标号 [ a k , i ] [a_k, i] [ak,i].如果 k = n k=n k=n,此时汇点(终点)得到了标号,也找到了一条突破路径,进入第5步;否则令 i = k i=k i=k,转回第2步。

第4步(回溯): 如果 i = 1 i=1 i=1,那么不存在突破路径,进入第6步;否则,令 r r r是紧邻在当前节点 i i i之前得到标号的节点,并将节点 i i i从节点 r r r的相邻节点集合中删除,令 i = r i=r i=r,转回第2步。

第5步(剩余容量的确定): N p = ( 1 , k 1 , k 2 , . . . , n ) N_p=(1,k_1, k_2,...,n) Np=(1,k1,k2,...,n)是从源点1到汇点 n n n的第 p p p条突破路径,则这条路径上最大流量为:
f p = m i n ( a 1 , a k 1 , a k 2 , . . . , a n ) f_p=min(a_1,a_{k1},a_{k2},...,a_n) fp=min(a1,ak1,ak2,...,an)
\qquad 这条路径上每条弧的剩余容量在顺着流的方向上 f p f_p fp是减少的,在逆着流的方向上 f p f_p fp是增加的。
\qquad 例如,对于该路径上的节点 i i i与节点 j j j,当前剩余容量为 ( c i j , c j i ) (c_{ij}, c_{ji}) (cij,cji)变为:
\qquad <\a> 如果流是从节点 i i i流向节点 j j j,则弧上的剩余容量为 ( c i j − f p , c j i + f p ) (c_{ij}-f_p, c_{ji}+f_p) (cijfp,cji+fp);
\qquad <\b> 如果流是从节点 j j j流向节点 i i i,则弧上的剩余容量为 ( c i j + f p , c j i − f p ) (c_{ij}+f_p, c_{ji}-f_p) (cij+fp,cjifp);
\qquad 恢复第4步删除掉的节点,然后令 i = 1 i=1 i=1,转回第2步接着寻找新的突破路径。

第6步(最优解)
\qquad <\a> 给出已经找到的 m m m条突破路径,那么网络的最大流为:
F = f 1 + f 2 + . . . + f m F=f_1 + f_2 + ...+ f_m F=f1+f2+...+fm
\qquad <\b> 根据每条弧 ( i , j ) (i,j) (ij)上的初始的和最终的剩余容量, ( c i j , c j i ) 和 ( C ‾ i j , C ‾ j i ) (c_{ij}, c_{ji})和 (\overline{C}_{ij},\overline{C}_{ji}) (cij,cji)(Cij,Cji)按照下面的方法确定该弧上的最优流:令 ( x , y ) = ( C ‾ i j − c i j , C ‾ j i − c j i ) (x,y)=(\overline{C}_{ij}-c_{ij},\overline{C}_{ji}-c_{ji}) (x,y)=(Cijcij,Cjicji),如果 x > 0 x>0 x>0,那么从节点 i i i流向节点 j j j的最优流是 x x x个单位;如果 y > 0 y>0 y>0,那么从节点 j j j流向节点 i i i的最优流是 y y y个单位.(注意 x , y x,y x,y不能同时为正数).

3 总结

\qquad 由于例子过于繁杂,这里就不做具体展示,有兴趣的读者可以参考运筹学相关书籍,这里推荐2本我觉得不错的,分别是:
《运筹学导论》 作者:[美]Hamdy A·Taha 出版社:人民邮电出版社;
《运筹学》 作者:运筹学教程编写组 出版社:清华大学出版社

运筹学导论
运筹学
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值