最大流問題Ford Fulkerson演算法

2021-08-03 16:39:59 字數 1613 閱讀 4304

最大傳輸量

網路中有兩台計算機s和t,現在想從s傳輸資料到t。該網路中一共有n臺計算機,其中一些計算機之間連有一條單向的通訊電纜,每條通訊電纜都有對應的1秒鐘內所能傳輸的最大資料量。當其他計算機之間沒有資料傳輸時,在1秒鐘內s最多可以傳送多少資料到t?

將上述網路當做乙個有向圖。圖中每條邊e都有對應的最大可能的資料傳輸量。這樣就可以把問題轉為如下形式:

(1)記每條邊對應的實際資料傳輸量為f(e)。

(2)傳輸量應該滿足如下限制:

0<=f(e)<=c(e)

(3)資料在傳輸過程中既不會增加也不會減少,收到的資料量和發出的資料量應該相等。

目標是:最大化從s發出的資料量。

我們稱使得傳輸量最大的f為最大流,而求解最大流的問題為最大流問題。此外,我們稱c為邊的容量,f為邊的流量,s為源點,t為匯點。

(一)貪心演算法

(1)找一條s到t 的只經過f(e)(2)如果不存在滿足條件的路徑,則結束演算法。否則,沿著該路徑盡可能地增加,返回第(1)步。

但是得到的結果並非最優的。將最優結果和貪心演算法結果的流量求差,得到差值圖,可以發現,如果將差值為-1的流給推回去,而得到新的流。

於是將貪心演算法做如下改進:

(1)只利用滿足f(e)0的e對應的反向邊rev(e),尋找一條s到t的路徑。

(2)如果不存在滿足條件的路徑,則結束。否則,沿著該路徑盡可能地增加流,返回第(1)步。

注:我的理解:可以先按照貪心演算法,把結果求出來,然後把結果中流量不為0的邊加一條反向邊,繼續使用演算法,看還是否能求出一條新的路徑。

殘餘網路:考慮的f(e)0的e對應的反向邊rev((e)所組成的圖

下面是乙個ford-fulkerson演算法的鄰接表實現的例子,這裡沒有儲存f(e)的值,取而代之的是直接改變c(e)的值

//用於表示邊的結構體(終點,容量,反向邊)

struct edge;

vectorg[max_v];//圖的鄰接表表示

bool used[max_v];//dfs中用到的訪問標記

//向圖中增加一條從s到t容量為cap的邊

void add_edge(int from,int to,int cap)};

g[to].push_back};

//通過dfs尋找增廣路

int dfs(int v,int t,int f){

if(v==t) return f;

used[v]=true;

for(int i=0;iedge &e=g[v][i];

if(!used[g.to]&&e.cap>0){

int d=dfs(e.to,t,min(f,e.cap));

if (d>0){

e.cap=e.cap-d;

g[e.to][e.rev].cap+=d;

return d;

return 0;

//求解從s到t的最大流

int max_flow(int s,int t){

int flow=0;

for(; ;){

memset(used,0,sizeof(used));

int f=dfs(s,t,inf);

int(f==0) return flow;

flow+=f;

最大流問題

暫時最大流問題我就先掌握這一種演算法吧 基本的最大流問題 ek演算法 基於bfs 每一次bfs更新一條路徑,雖然都會入佇列,但是由於以下條件保證點不會交叉,所以只有一條到終點的路徑會更新流量。if res v map u v flow u v 注意更新flow矩陣的時候是這樣的 while u st...

最大流問題

具體的最大流問題定義 術語以及特性,前人已經描述的很詳細了 我們需要注意以及幾個方面 增益路徑的生成次序如果不恰當,會對方法的效率有巨大的影響。如下 其中u代表某個大正整數。如果沿著路徑1 2 3 4對流量0進行增益,得到 b 中值為1的流量 接著沿著路徑1 3 2 4對流量0進行增益,得到 c 中...

最大流問題

對最大流問題比較感性的認識,要看證明還是要看演算法導論的相關章節。最大流問題 給定乙個有向圖,一般情況下邊的值為整數,定義不直接相連的節點間的邊值為0,如果有節點i和j直接由多條邊,則將這些邊合併為一條,值取和。則若i到j有邊,則j到i的邊為0,這些邊稱為反向邊。定義其中的兩個點位源點和匯點,則這個...