网络最大流问题之Ford-Fulkerson算法原理详解
前言
最大流問題是網(wǎng)絡(luò)優(yōu)化中典型的問題,用形象的語言來描述就是在滿足容量約束的前提下將盡可能多的流從源節(jié)點(diǎn)(始點(diǎn))到匯節(jié)點(diǎn)(終點(diǎn))。解決此問題的經(jīng)典方法很多,本文介紹廣為人熟知的Ford-Fulkerson算法,來解決最大流問題。盡管網(wǎng)上關(guān)于此問題的文章多如牛毛,但筆者希望結(jié)合自己學(xué)習(xí)過程中對(duì)算法的理解,給予算法最清晰的介紹,希望對(duì)大家有幫助。(筆者曾嘗試使用java來實(shí)現(xiàn),但最終因用java實(shí)現(xiàn)和使用圖太麻煩了,又不想重新用python來實(shí)現(xiàn),故放棄,以后的實(shí)現(xiàn)估計(jì)會(huì)采用python而不是java,java畢竟不適合寫圖相關(guān)算法)。
一、知識(shí)準(zhǔn)備
學(xué)習(xí)此算法前建議讀者學(xué)習(xí)網(wǎng)絡(luò)流相關(guān)知識(shí)和基本概念,一些需要了解的概念和知識(shí)先羅列如下
1、可增廣路
2、最大流最小割定理
3、圖的割集
4、飽和割集
5、可行流向量
6、節(jié)點(diǎn)的散度
7、前向后向邊
二、可增廣路搜索算法
對(duì)于k=0,1,..., 給定Tk,若Tk為空集或者t∈Tk則算法終止。否則,令
Tk+1 = { Tk | 存在節(jié)點(diǎn)m∈Tk, 以及邊(m, n) 滿足xmn < cmn, 或者邊(n, m) 滿足 bnm<xnm},
(其中節(jié)點(diǎn)數(shù)為n,bnm和cnm為邊mn容量的最小和最大值,xmn為邊的流量, Tk+1集合的節(jié)點(diǎn)不能屬于T其他集合節(jié)點(diǎn))
上式的含義即為Tk+1為在集合Tk中所有節(jié)點(diǎn)滿足可增廣路條件的相鄰的節(jié)點(diǎn)組成的集合,當(dāng)然,這些節(jié)點(diǎn)不能包括已經(jīng)存在其他T集合中的節(jié)點(diǎn)。
當(dāng)算法終止時(shí),最后一個(gè)集合Tk有兩種情況(假設(shè)s為起點(diǎn), t為終點(diǎn)):
(1) 最后一個(gè)集合Tk包含t,此時(shí)從t向前標(biāo)記即可構(gòu)造從s到t的簡(jiǎn)單可增廣路。即從T1,T2,T3,....,Tk中每個(gè)取一個(gè)節(jié)點(diǎn)的路
(2)最后一個(gè)集合Tk為空集,此時(shí)得到一個(gè)分離s和t的飽和割集
現(xiàn)舉例說明,如下圖(容量下限(最小值),流量,容量上限(最大值))標(biāo)在每條邊旁
1為源點(diǎn),6為匯點(diǎn)。開始T0只有1個(gè)節(jié)點(diǎn),就是節(jié)點(diǎn)1。接下來從和T0中節(jié)點(diǎn),也就是節(jié)點(diǎn)1相鄰的節(jié)點(diǎn)2和3開始。邊12,流量為0,為前向邊,滿足流量小于容量上限;邊13也為前向邊,滿足流量小于上限(0 < 1)。所以節(jié)點(diǎn)2和節(jié)點(diǎn)3組成T1。然后考慮以節(jié)點(diǎn)2和節(jié)點(diǎn)3來尋找T2,原理和前面一致,其中邊35,為后向邊,流量為2,大于容量下限1,所以節(jié)點(diǎn)5添加到T2,。到最后T3,集合包含6,終止。此時(shí)增廣路為(1,3,5,6)。
現(xiàn)在看另一圖,只是把邊56的流量改為了0,此時(shí)后向邊56不滿足流量大于下限,所以T3為空集。此時(shí)存在飽和割集{S, N-S}分離1和6,其中S = {1,2,3,4,5},是所有集合Tk的并集
三、Ford-Fulkerson算法
在了解了可增廣路搜索算法后,現(xiàn)在正式進(jìn)入本文的主題,F(xiàn)ord-Fulkerson算法。該算法在每次迭代中改進(jìn)原費(fèi)用(s的散度),因此是原費(fèi)用改進(jìn)型算法。算法思想是,給定可行流向量x(即滿足容量可行且除了s和t之外節(jié)點(diǎn)的散度為零,即節(jié)點(diǎn)流入和流出相等,的流向量),以及對(duì)于x可增廣的從s到t的路P,就可以增進(jìn)P的前向邊(i,j)的流量并減小P的后向邊(i,j)的流量。流量增量的最大值為
δ = min{ {cij - xij | (i, j) ∈ P+}, {xij - bij | (i, j) ∈ P-} }, 其中P+是P的前向邊的集合, P-是P的后向邊的集合。
由此得到的流向量y由
yij = :xij +δ 如果(i, j)∈ P+,
xij -δ 如果(i,j) ∈P-,
算法的迭代步驟
使用可增廣路搜索算法實(shí)現(xiàn)下述兩種情況之一:
(1)、得到將s和t分離的飽和割集
(2)、得到從s到t的x的可增廣路P。
在情況1下,算法終止;此時(shí)的流向量即為所求。在情況2下,沿著P進(jìn)行增廣,并進(jìn)行下一次迭代。每次增廣時(shí),算法通過增廣增量δ改進(jìn)原費(fèi)用(s的散度)。現(xiàn)在以例子說明
初始圖,如圖1。搜索到增廣路(1, 2, 5),路12和路25為正向邊,求δ=min{ c12- x12, c25- x25}為1。如圖2
圖1
圖2
對(duì)增廣路中的所有邊x12和x25使用δ改進(jìn)費(fèi)用,因?yàn)榫鶠檎蜻叄行碌牧髁繛閤12=0 + 1 = 1, x25= 0 + 1 = 1。費(fèi)用改進(jìn)后如圖3。費(fèi)用改進(jìn)后繼續(xù)尋找增廣路,如圖4。
圖3
圖4
迭代
圖5
圖6
迭代
圖7
圖8
在最后一次費(fèi)用改進(jìn)后,已找不到增廣路。其中T0包含節(jié)點(diǎn)1,T1包含節(jié)點(diǎn)2,T3包含節(jié)點(diǎn)3,因此飽和割集為[{1, 2, 3}, {4, 5}]。割集容量即為最大容量,即5=c24 + c34 + c25 = 5
圖9
四、
在學(xué)習(xí)此算法時(shí),筆者已經(jīng)盡力描述算法的主要內(nèi)容了。由于需要有一些圖論的知識(shí)作為輔助,加上算法有些復(fù)雜,所以結(jié)合文中例子效果會(huì)更好。
五、知識(shí)相關(guān)
最短路徑算法之Dijkstra算法(java實(shí)現(xiàn))
總結(jié)
以上是生活随笔為你收集整理的网络最大流问题之Ford-Fulkerson算法原理详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 蜗牛星际网卡驱动_矿渣“蜗牛星际“折腾N
- 下一篇: 惠普星 Book 15 笔记本发布:搭载