运筹学—最大流模型
上兩篇文章,我介紹了最短路徑中的兩種算法:
最短路徑算法——清晰簡單的弗洛伊德算法(Floyd)
最短路徑算法——簡單明了的迪杰斯特拉算法(Dijkstra)
這篇文章,我來簡單介紹一下最大流模型!
最大流模型
\qquad很多的數(shù)學(xué)模型往往來源于生活問題,本文介紹其中一個(gè)問題借此引出最大流模型,讓讀者能夠更好地了解模型的背景以及應(yīng)用。
\qquad現(xiàn)有一管道網(wǎng)絡(luò)用于運(yùn)輸原油,將原油從油井運(yùn)輸?shù)教釤拸S,為了在網(wǎng)絡(luò)中順暢地輸運(yùn)原油,需要在中間合適的距離安裝增壓泵站,每一段管道有一個(gè)有限的最大原油流量(容量),每段管道可以是單向,也可以是雙向,取決于它的原始設(shè)計(jì)。那么如何確定從油井到提煉廠原油的最大流量?
\qquad下面給定雙向弧的相關(guān)概念:
\qquad給定弧(i,j)(i,j)(i,j),其中i<ji<ji<j,用符號(hào)(C ̄ij,C ̄ji)(\overline{C}_{ij},\overline{C}_{ji})(Cij?,Cji?)表示兩個(gè)方向i→j,j→ii→j,j→ii→j,j→i弧上的容量。為了更清晰地描述,把C ̄ij\overline{C}_{ij}Cij?放在靠近節(jié)點(diǎn)iii的一邊,把C ̄ji\overline{C}_{ji}Cji?放在靠近節(jié)點(diǎn)jjj的一邊,如下圖所示。
C ̄ij表示從i→j的弧上的容量,C ̄ji表示從j→i的弧上的容量\overline{C}_{ij}表示從i→j的弧上的容量,\overline{C}_{ji}表示從j→i的弧上的容量 Cij?表示從i→j的弧上的容量,Cji?表示從j→i的弧上的容量
1 枚舉割
\qquad割(cut) 是一部分弧的集合,如果將這些弧從網(wǎng)絡(luò)中刪除,就會(huì)斷開源點(diǎn)和匯點(diǎn)之間所有的流。割的容量等于這個(gè)割中所有弧上容量的和。在網(wǎng)絡(luò)中所有可能的割中,最小容量的割就對(duì)應(yīng)了這個(gè)網(wǎng)絡(luò)的最大流。
例子
如下圖網(wǎng)絡(luò),按照上述表示方法對(duì)每一條雙向弧都標(biāo)上了容量。例如,對(duì)于弧(3,4),從節(jié)點(diǎn)3到節(jié)點(diǎn)4的流量限制為10單位,從節(jié)點(diǎn)4到節(jié)點(diǎn)3為5單位。我直接在圖中,標(biāo)出了該網(wǎng)絡(luò)的3個(gè)割:
圖中3個(gè)割的容量如下表:
| 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 |
從表中可以看出,該網(wǎng)絡(luò)最大流不超過60個(gè)單位。枚舉所有割,對(duì)于小型網(wǎng)絡(luò)是可行的,但是對(duì)于比較復(fù)雜的網(wǎng)絡(luò),效率就很低了,所以需要尋找其他算法。
2 最大流算法
2.1 原理
\qquad最大流算法的核心思想是:從網(wǎng)絡(luò)中尋找從源點(diǎn)到匯點(diǎn)具有正的流的突破路徑。
\qquad弧(i,j)(i,j)(i,j)上的初始容量(C ̄ij,C ̄ji)(\overline{C}_{ij},\overline{C}_{ji})(Cij?,Cji?),當(dāng)給定一個(gè)流并找到突破路徑后,需要對(duì)每條弧上的容量進(jìn)行修改,修改后的容量稱為剩余容量(cij,cji)(c_{ij}, c_{ji})(cij?,cji?)。 如果節(jié)點(diǎn)jjj從節(jié)點(diǎn)iii接收到一個(gè)流,那么給節(jié)點(diǎn)jjj標(biāo)號(hào)為[aj,i][a_j,i][aj?,i](節(jié)點(diǎn)jjj的表示)。其中aja_jaj?表示從節(jié)點(diǎn)iii流到節(jié)點(diǎn)jjj的量,iii表示流的來源是節(jié)點(diǎn)iii。
2.2 步驟
第1步: 首先將所有弧(i,j)(i,j)(i,j)的剩余容量設(shè)為初始容量,即(cij,cji)=(C ̄ij,C ̄ji)(c_{ij}, c_{ji}) = (\overline{C}_{ij},\overline{C}_{ji})(cij?,cji?)=(Cij?,Cji?).取a1=∞a_1=\inftya1?=∞,則源點(diǎn)1標(biāo)號(hào)為[∞,?][\infty,-][∞,?]. 令i=1i=1i=1,進(jìn)入第2步。
第2步: 確定集合SiS_iSi?,它是節(jié)點(diǎn)iii通過剩余容量為正的弧能夠直接到達(dá)的所有未標(biāo)號(hào)的節(jié)點(diǎn)jjj的集合。如果Si=?S_i=\emptysetSi?=?,進(jìn)入第3步;否則,進(jìn)入第4步。
第3步: 確定k∈Sik\in S_ik∈Si?,使之滿足cik=maxj∈Si{cij}c_{ik}= \mathop{max}\limits_{j\in S_i}\{c_{ij}\}cik?=j∈Si?max?{cij?}. 令ak=cika_k=c_{ik}ak?=cik?,并且給節(jié)點(diǎn)kkk標(biāo)號(hào)[ak,i][a_k, i][ak?,i].如果k=nk=nk=n,此時(shí)匯點(diǎn)(終點(diǎn))得到了標(biāo)號(hào),也找到了一條突破路徑,進(jìn)入第5步;否則令i=ki=ki=k,轉(zhuǎn)回第2步。
第4步(回溯): 如果i=1i=1i=1,那么不存在突破路徑,進(jìn)入第6步;否則,令rrr是緊鄰在當(dāng)前節(jié)點(diǎn)iii之前得到標(biāo)號(hào)的節(jié)點(diǎn),并將節(jié)點(diǎn)iii從節(jié)點(diǎn)rrr的相鄰節(jié)點(diǎn)集合中刪除,令i=ri=ri=r,轉(zhuǎn)回第2步。
第5步(剩余容量的確定): 令Np=(1,k1,k2,...,n)N_p=(1,k_1, k_2,...,n)Np?=(1,k1?,k2?,...,n)是從源點(diǎn)1到匯點(diǎn)nnn的第ppp條突破路徑,則這條路徑上最大流量為:
fp=min(a1,ak1,ak2,...,an)f_p=min(a_1,a_{k1},a_{k2},...,a_n) fp?=min(a1?,ak1?,ak2?,...,an?)
\qquad這條路徑上每條弧的剩余容量在順著流的方向上fpf_pfp?是減少的,在逆著流的方向上fpf_pfp?是增加的。
\qquad例如,對(duì)于該路徑上的節(jié)點(diǎn)iii與節(jié)點(diǎn)jjj,當(dāng)前剩余容量為(cij,cji)(c_{ij}, c_{ji})(cij?,cji?)變?yōu)?#xff1a;
\qquad<\a> 如果流是從節(jié)點(diǎn)iii流向節(jié)點(diǎn)jjj,則弧上的剩余容量為(cij?fp,cji+fp)(c_{ij}-f_p, c_{ji}+f_p)(cij??fp?,cji?+fp?);
\qquad<\b> 如果流是從節(jié)點(diǎn)jjj流向節(jié)點(diǎn)iii,則弧上的剩余容量為(cij+fp,cji?fp)(c_{ij}+f_p, c_{ji}-f_p)(cij?+fp?,cji??fp?);
\qquad恢復(fù)第4步刪除掉的節(jié)點(diǎn),然后令i=1i=1i=1,轉(zhuǎn)回第2步接著尋找新的突破路徑。
第6步(最優(yōu)解):
\qquad<\a> 給出已經(jīng)找到的mmm條突破路徑,那么網(wǎng)絡(luò)的最大流為:
F=f1+f2+...+fmF=f_1 + f_2 + ...+ f_m F=f1?+f2?+...+fm?
\qquad<\b> 根據(jù)每條弧(i,j)(i,j)(i,j)上的初始的和最終的剩余容量,(cij,cji)和(C ̄ij,C ̄ji)(c_{ij}, c_{ji})和 (\overline{C}_{ij},\overline{C}_{ji})(cij?,cji?)和(Cij?,Cji?)按照下面的方法確定該弧上的最優(yōu)流:令(x,y)=(C ̄ij?cij,C ̄ji?cji)(x,y)=(\overline{C}_{ij}-c_{ij},\overline{C}_{ji}-c_{ji})(x,y)=(Cij??cij?,Cji??cji?),如果x>0x>0x>0,那么從節(jié)點(diǎn)iii流向節(jié)點(diǎn)jjj的最優(yōu)流是xxx個(gè)單位;如果y>0y>0y>0,那么從節(jié)點(diǎn)jjj流向節(jié)點(diǎn)iii的最優(yōu)流是yyy個(gè)單位.(注意x,yx,yx,y不能同時(shí)為正數(shù)).
3 總結(jié)
\qquad由于例子過于繁雜,這里就不做具體展示,有興趣的讀者可以參考運(yùn)籌學(xué)相關(guān)書籍,這里推薦2本我覺得不錯(cuò)的,分別是:
《運(yùn)籌學(xué)導(dǎo)論》 作者:[美]Hamdy A·Taha 出版社:人民郵電出版社;
《運(yùn)籌學(xué)》 作者:運(yùn)籌學(xué)教程編寫組 出版社:清華大學(xué)出版社
| 運(yùn)籌學(xué)導(dǎo)論 | 運(yùn)籌學(xué) |
總結(jié)
- 上一篇: 【Go】sync.RWMutex源码分析
- 下一篇: 最大流的四种常用算法