網路流 增廣路 入門很好的文章

2022-08-14 23:00:23 字數 2813 閱讀 9985

edmonds_karp 演算法 ***

這個牛這裡找到為什麼反向邊要加回流量的原因了,

因為是初學教程,所以我會盡量避免繁雜的數學公式和證明。也盡量給出了較為完整的**。

本文的目標群體是網路流的初學者,尤其是看了各種nb的教程也沒看懂怎麼求最大流的小盆友們。本文的目的是,解釋基本的網路流模型,最基礎的最大流求法,即bfs找增廣路法,也就是ek法,全名是edmond-karp,其實我倒是覺得記一下演算法的全名和來歷可以不時的拿出來裝一裝。

比如說這個,ek演算法首先由俄羅斯科學家dinic在2023年提出,沒錯,就是dinic演算法的創始人,實際上他提出的也正是dinic演算法,在ek的基礎上加入了層次優化,這個我們以後再說,2023年jack edmonds和richard karp發表了沒有層次優化的ek演算法。但實際上他們是比2023年更早的時候就獨立弄出來了。

你看,研究一下歷史也是很有趣的。

扯遠了,首先來看一下基本的網路流最大流模型。

有n個點,有m條有向邊,有乙個點很特殊,只出不進,叫做源點,通常規定為1號點。另乙個點也很特殊,只進不出,叫做匯點,通常規定為n號點。每條有向邊上有兩個量,容量和流量,從i到j的容量通常用c[i,j]表示,流量則通常是f[i,j]。通常可以把這些邊想象成道路,流量就是這條道路的車流量,容量就是道路可承受的最大的車流量。很顯然的,流量<=容量。而對於每個不是源點和匯點的點來說,可以模擬的想象成沒有儲存功能的貨物的中轉站,所有」進入」他們的流量和等於所有從他本身」出去」的流量。

把源點比作工廠的話,問題就是求從工廠最大可以發出多少貨物,是不至於超過道路的容量限制,也就是,最大流。

比如這個圖。每條邊旁邊的數字表示它的容量。

下面我們來考慮如何求最大流。

首先,假如所有邊上的流量都沒有超過容量(不大於容量),那麼就把這一組流量,或者說,這個流,稱為乙個可行流。乙個最簡單的例子就是,零流,即所有的流量都是0的流。

我們就從這個零流開始考慮,假如有這麼一條路,這條路從源點開始一直一段一段的連到了匯點,並且,這條路上的每一段都滿足流量《容量,注意,是嚴格的

這樣我們就得到了乙個更大的流,他的流量是之前的流量+delta,而這條路就叫做增廣路。

我們不斷地從起點開始尋找增廣路,每次都對其進行增廣,直到源點和匯點不連通,也就是找不到增廣路為止。當找不到增廣路的時候,當前的流量就是最大流,這個結論非常重要。

尋找增廣路的時候我們可以簡單的從源點開始做bfs,並不斷修改這條路上的delta量,直到找到源點或者找不到增廣路。

這裡要先補充一點,在程式實現的時候,我們通常只是用乙個c陣列來記錄容量,而不記錄流量,當流量+1的時候,我們可以通過容量-1來實現,以方便程式的實現。

bfs過程的半偽**:下面另給乙個c++版的模板

int bfs()

}if(flow[end]==max_int)return -1;

return flow[end];

}但事實上並沒有這麼簡單,上面所說的增廣路還不完整,比如說下面這個網路流模型。

我們第一次找到了1-2-3-4這條增廣路,這條路上的delta值顯然是1。於是我們修改後得到了下面這個流。(圖中的數字是容量)

這時候(1,2)和(3,4)邊上的流量都等於容量了,我們再也找不到其他的增廣路了,當前的流量是1。

但這個答案明顯不是最大流,因為我們可以同時走1-2-4和1-3-4,這樣可以得到流量為2的流。

那麼我們剛剛的演算法問題在**呢?問題就在於我們沒有給程式乙個」後悔」的機會,應該有乙個不走(2-3-4)而改走(2-4)的機制。那麼如何解決這個問題呢?回溯搜尋嗎?那麼我們的效率就上公升到指數級了。

而這個演算法神奇的利用了乙個叫做反向邊的概念來解決這個問題。即每條邊(i,j)都有一條反向邊(j,i),反向邊也同樣有它的容量。

我們直接來看它是如何解決的:

在第一次找到增廣路之後,在把路上每一段的容量減少delta的同時,也把每一段上的反方向的容量增加delta。即在dec(c[x,y],delta)的同時,inc(c[y,x],delta)

我們來看剛才的例子,在找到1-2-3-4這條增廣路之後,把容量修改成如下

這時再找增廣路的時候,就會找到1-3-2-4這條可增廣量,即delta值為1的可增廣路。將這條路增廣之後,得到了最大流2。

那麼,這麼做為什麼會是對的呢?我來通俗的解釋一下吧。

事實上,當我們第二次的增廣路走3-2這條反向邊的時候,就相當於把2-3這條正向邊已經是用了的流量給」退」了回去,不走2-3這條路,而改走從2點出發的其他的路也就是2-4。(有人問如果這裡沒有2-4怎麼辦,這時假如沒有2-4這條路的話,最終這條增廣路也不會存在,因為他根本不能走到匯點)同時本來在3-4上的流量由1-3-4這條路來」接管」。而最終2-3這條路正向流量1,反向流量1,等於沒有流量。

這就是這個演算法的精華部分,利用反向邊,使程式有了乙個後悔和改正的機會。而這個演算法和我剛才給出的**相比只多了一句話而已。

至此,最大流edmond-karp演算法介紹完畢。接下來會介紹效率更高的dinic演算法,最小割,最小費用最大流等內容。敬請期待。

網路流之增廣路演算法

這部分內容在 演算法競賽入門經典 劉汝佳 裡面講的已經很詳細了。但裡面對於反向流量的作用是沒有說明的。這裡只說一下反向流量的作用。推薦上看下。反向流量能夠讓後面的流自我調整。例如當前狀態下 當前狀態下如何尋找?用a表示殘量,cap表示容量,很明顯,3 4這條路不是最優的.更新流量得到 可以看到,通過...

最大網路流 增廣路演算法

幾句廢話 讀了劉汝佳的書之後,感覺一切都是那麼茫然,於是自己在網上找教程,自己一點點碼的,大概用了三天。網路流基礎 看來我很有必要說一下網路流的基礎 網路流問題就是給你乙個圖,每個圖的邊權叫做這條邊的流量,問你從起始點出發,有多少值能通過這些邊流到重點 我知道你沒看懂,舉個例子 如圖 最大值為 從1...

最大網路流 增廣路演算法

幾句廢話 讀了劉汝佳的書之後,感覺一切都是那麼茫然,於是自己在網上找教程,自己一點點碼的,大概用了三天。網路流基礎 看來我很有必要說一下網路流的基礎 網路流問題就是給你乙個圖,每個圖的邊權叫做這條邊的流量,問你從起始點出發,有多少值能通過這些邊流到重點 我知道你沒看懂,舉個例子 如圖 最大值為 從1...