最大流問題

2021-09-07 22:07:33 字數 2265 閱讀 8103

對最大流問題比較感性的認識,要看證明還是要看演算法導論的相關章節。

最大流問題:

給定乙個有向圖,一般情況下邊的值為整數,定義不直接相連的節點間的邊值為0,如果有節點i和j直接由多條邊,則將這些邊合併為一條,值取和。則若i到j有邊,則j到i的邊為0,這些邊稱為反向邊。定義其中的兩個點位源點和匯點,則這個有向圖可以視為流網路。網路中的有向邊的值表示可以通過該邊的最大流量,最大流問題就是求從源點出發,流進匯點的最大流量。

為了求最大流,必須了解殘餘網路,增廣路徑,反向弧等概念。

殘餘網路是針對流網路的某個狀態而定義的。

如圖是乙個流網路的狀態,其中1為源點,7為匯點,每天邊的值為v/c的形式表示,v代表當前狀態該邊上的實際流量,c代表該邊的最大流量:

則它的殘餘網路就是從中找到乙個從源點到匯點的路徑(該路徑中不存在值為0的邊),選取這條路徑中v的最小值minflow,也就是該路徑的實際流量,然後將該路徑的所有邊的實際容量都更新為c(i,j)-minflow,並修改其反向邊的值為c(j,i)+minflow(這一步的意義可能是直接的貪心求法無法得到最優解,需要增加方向邊來修正錯誤?)。這樣的一條路徑稱為增廣路徑,修改值後的流網路成為殘留網路。增廣路徑的意義在於能給當前最大流增加多少的值,而殘餘網路的意義在於每個節點從源點的流入量還能增加多少,0表示不能再增加了。當殘留網路中沒有增光路經時,則當前流入匯點的流值為最大流。

下圖是找到兩條增光路經,並修改流網路後的殘餘網路(我感覺此時3到4,5到6和6到7之間應該仍然為0):

以上方法為ford-fulkerson方法,該方法的一種實現是基於bfs的edmonds-karp演算法。

演算法流程如下:

設佇列q:儲存當前未訪問的節點,隊首節點出隊後,成為已檢查的標點;

path陣列:儲存當前已訪問過的節點的增廣路徑;

flow陣列:儲存一次bfs遍歷之後流的可改進量;

repeat:

path清空;

源點s進入path和q,path[s]

while q非空 and 匯點t未訪問 do

begin

隊首頂點u出對;

for每一條從u出發的弧(u,v) do

if v未訪問 and 弧(u,v) 的流量可改進;

then flow[v]

end while

if(匯點t已訪問)

then 從匯點t沿著path構造殘餘網路;

until 匯點t未被訪問

說明:

start:源點

terminal:匯點

map[len][len]:流網路

bfsqueue:每一狀態中,用bfs最增廣路經,每次只求一條增廣路徑

minflow[len]:記錄從源點流入每個點的最大可能值,這個值也將該路徑中的最小值(該路徑的實際流量)一直傳遞到匯點。該值是每次bfs都要保留的

path[len]:記錄增廣路徑,其中path[j] = i表示從節點 i 流向節點 j 。同時也記錄了每次bfs時記錄是否考察了當前節點。

每次bfs完後,檢視path[terminal],如果path[terminal]==-1,則表示沒有從源點到匯點的增廣路徑了。

每次bfs完後,要更新增廣路徑中的容量和方向路徑的容量,因為minflow已經記錄了增光路經中的最小值,用minflow[terminal]更新即可。

#define len 201

int map[len][len];

int minflow[len];

int n,m;

int start;

int terminal;

queue< int> bfsqueue;

int bfs(int path[len]){

memset(path,-1, sizeof (int )*len);

while (!bfsqueue.empty()) bfsqueue.pop();

path[start] = 0;

minflow[start] = maxint;

bfsqueue.push(start);

while (!bfsqueue.empty()){

int node = bfsqueue.front();

bfsqueue.pop();

for (int i=1;i<=m;++i){

if (path[i] == -1 && map[node][i]!=0 && i != start){

minflow[i] = (minflow[node]

最大流問題

暫時最大流問題我就先掌握這一種演算法吧 基本的最大流問題 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 中...

最大流問題

真的,資料好多的,兩個差不多了,但其實,我是讀運籌學教程 演算法競賽入門經典訓練指南讀懂的。比較全面的是輝夜 永遠亭寫的,基本上的流程都介紹了,特別是比較寫得很好。當然上也有人 主要涉及以下 不過演算法具體來講,這篇最大流dinic演算法寫得蠻好,雖然我是看書。另外乙個問題就是最小費用最大流問題,鏈...