網絡流


簡述

網絡流主要可以拿來解決一些跟有向關系相關的問題,例如液體在管道中的流動、貨物的運載、網絡中的信息波動等。
簡單介紹一下它:在一個有向圖上選擇一個源點s、一個匯點t。源點只流出,匯點只流進。同時,一條邊\((u,v)\)經過的流量記為\(f(u,v)\),也有允許通過的最大流量稱為容量,記為\(c(u,v)\)。(若該邊不存在,則\(c(u,v)=0\))。除了源點和匯點以外的每個店入流和出流都相等。一條邊上的剩余流量(沒有用完的)稱為殘量,即 容量-流量
因此網絡流模型可以形象地描述為:在每一條邊都不超過容量限制的前提下,“流”從源點源源不斷地產生,最終全部歸於匯點。

基本性質

  1. \(f(u,v)\le c(u,v)\)(容量限制)
  2. 對於任何一個不是源點或匯點的點\(\text{u}\),總有 \(\sum_{p\in E}f(p,u)=\sum_{q\in E}f(u,q)\)
    因為入流和出流相等(流量平衡)
  3. 對於任何一條有向邊\((u,v)\),總有\(f(u,v)=-f(v,u)\) (斜對稱性)

最大流

先講一下比較簡單的最大流問題
直接從字面意思即可理解,從源點流到匯點的流量最大就是最大流。

算法思想:從零流(所有邊的流量均為0)開始不斷增加流量,保持每次增加流量后都滿足以上性質(增加流量,也就是減去容量時要相應的給反向邊加上等量的容量,便於反悔)。計算每條邊上的殘量,得到殘量網絡,再繼續在殘量網絡中嘗試增加流量。

增廣路算法基於:殘量網絡中任何一條從\(s\)\(t\)的有向道路都對應一條原圖中的增廣路——只要求出該道路中所有容量的最小值\(minf\),把對應的所有邊上的流量減去\(minf\),在答案里加上它即可,這個過程被稱為增廣
顯然只要殘量網絡中存在增廣路,流量就可以增大;反之,如果不存在增廣路,流量就已經最大。(增廣路定理)

順便也講一下最大流最小割定理。

最小割

  • 割:對於一個網絡流圖\(G=(V,E)\),其割的定義為一種點的划分方式:將所有的點划分為\(S\)\(T=V-S\)兩個集合,其中源點\(s\in S\),匯點\(t\in T\)
  • 割的容量:定義割的容量\(c(S,T)\)表示所有從\(S\)\(T\)的邊的容量之和,即\(c(S,T)=\sum_{u\in S,v\in T}c(u,v)\)。當然也可以用\(c(s,t)\)表示割的容量。
  • 最小割:使得容量最小的割\((S,T)\)。也可以理解為使得\(S\)\(T\)不聯通所需要刪去邊權最小的割。

最大流最小割

  • 定理\(f(s,t)_{max}=c(s,t)_{min}\)
  • 證明:對於任意一個可行流\(f(s,t)\)和任意割\((S,T)\),有:\(f(s,t)=S_\text{出邊的總流量}-S_\text{入邊的總流量}\le S_\text{出邊的總流量}=c(s,t)\)。而當達到最大流時,殘量網絡中不存在從\(s\)\(t\)的增廣路,所以\(S\)的出邊都是滿流,上式等號成立。同時,上式的另一表達形式為\(f(s,t)_{max}\le c(s,t)_{min}\)。又因等號可以取到,則\(f(s,t)_{max}=c(s,t)_{min}\),證畢。

問題模型

一般在最小割的問題中,割掉一條邊表示選擇某個條件,而邊權表示的是選擇這個條件的價值。至於該價值的貢獻是好是壞,則根據你如何使用這個價值而定。

舉個例子,對於二分圖,有點集\(U,V\)\(\forall e=(u,v) (u\in U,v\in V)\)表示u、v中至少選擇一個,保證無孤立點,求最小點權覆蓋集
example1
設左邊為點集\(U\),右邊為點集\(V\),如圖所示連邊。割掉紅色邊表示選擇\(U\)中某個點,其點權設為\(val_u\);割掉藍色邊表示選擇該邊兩端的點,其點權設為\(val_u+val_v\);割掉橙色邊表示選擇\(V\)中某個點,邊權設為\(val_v\)。這樣一來,若一條邊不從\(s\)連通到\(t\),則表示至少有一個點被選中,求得的最小割即為最小點權之和,覆蓋集可通過邊的使用情況求得。
事實上,我們都清楚,為了使點權之和最小化,藍色的邊是不會被割掉的。而仍然要設置它的原因,一是為了結合問題背景來建模,二是讓它承擔通道的角色,保證網絡流圖的性質。問題建模是非常值得琢磨的。

如果轉換一下,邊的限制變成u、v中至多選一個,求最大點權獨立集。其本質相同,因為至多選一個等價於至少刪去一個。由此可以看出,最大點權獨立集為最小點權覆蓋集的補集,其解法自然也就不言而喻了。

這里只是提供了一個參考的思路,具體的問題還要具體分析。

最小割的邊數

將邊權設為1重新求一遍最小割即可。

最小割集的求解

由於使用網絡流解決此類問題效率較為低下,普遍使用\(\texttt{Stoer-Wagner}\)算法進行求解,有興趣可自行查閱。

一些小細節

  • 存圖的時候要從偶數開始存,同時存正向邊和反向邊(這樣就可以保證正向邊編號全為偶數,反向邊編號為 i^1(奇偶性相反))

  • 反向邊怎么用?因為找到的增廣路不一定是最優的,反邊給你“反悔”的機會。如果一條邊邊權為0,那么往回走的時候並不會對流量有所影響(走不回去)。所以一開始反邊的邊權應該存0。當正向邊減去流過這條邊的增廣路上容量最小值d(此時這個值已經被加入到了答案)的時候,反向邊應該加上d(因為對於源點和匯點來說中間流量的這些變化都是無差別的,為了保證反向正向相加得原邊權,也就是不改變原本的條件就得這么做)

Edmonds-Karp(EK) 便是不斷用\(\texttt{BFS}\)來尋找增廣路,直到圖中不存在增廣路的算法。

但是如果一條一條地找出增廣路,萬一有一些極(毒)端(瘤)數據(比如幾條相鄰的邊容量相差特別大),這個時間復雜度就是無法承受的。Dinic的高效之處在於它能夠同時找出幾條增廣路.

關於最大流,我還沒有講完!當然,實際上在大部分情況下以上兩個算法已經夠用(我認為)。可以先跳過剩下有關最大流的算法。

(這里應該有ISAP和HLPP)

最大流/最小割 練習題

USACO4.2 草地排水

飛行員配對方案問題

USACO4.4 追查壞牛奶

圓桌問題

最小路徑覆蓋問題

魔術球問題

最長不下降子序列問題

方格取數問題

費用流

假如流經一條邊有對應流量的花費,那么問題就可以有更多的變式了。

  • 定義一條邊的費用\(w(u,v)\)表示單位流量流經所需花費的費用。即,當邊\((u,v)\)的流量為\(f(u,v)\)時,需要花費\(f(u,v)\times w(u,v)\)的費用。

類似的,我們先從最小費用最大流引入。即在最大化流量的基礎上使得總花費最小。
這當然和上面的最大流相關。之前尋找增廣路的方式是\(\texttt{BFS}\),對於\(\texttt{EK}\)來說,就是在邊權為1的圖上找到\(s\rightarrow t\)的一條最短路。那么,將 \(\texttt{BFS}\) 更換為尋找最短路的算法,邊權設為\(w(u,v)\),會產生什么樣的效果呢?

這樣的方式,既保證了最短路的性質,也保證了增廣路的性質。由於每單位流到匯點的流量都要花費途經的邊權之和,則最短路的性質使得了這些每次從最短路流過的流量是最划算的。在這樣的情境下,反向邊相當於退錢,所以要將邊權設為\(-w(u,v)\)

\(\texttt{Dinic}\) 是同時找到多條增廣路的算法,只需將 \(\texttt{BFS}\) 更改為最短路算法的同時,限制流量只能由當前點流向到匯點的最短路上的點即可。

因為有負權邊的存在,所以不能直接采用 \(\texttt{Dijkstra}\) ,應該采用 \(\texttt{SPFA}\) 或經由 \(\texttt{Primal-Dual(原始對偶算法)}\) 處理的 \(\texttt{Dijkstra}\) 。同時,由於向下走的條件發生改變,有可能會往回走,所以需要標記當前鏈上的點,防止陷入無限循環。

上下界網絡流

無源匯上下界可行流

給定一個網絡無源點匯點,且每條邊的流量有上限\(high\)和下限\(low\),問使得該網絡流量平衡的一種流量方案。
沒有源匯點意味着流一定要形成循環,否則不滿足流量平衡的條件。
不妨假設有解,先將所有的下界強制流滿(不考慮流量平衡的情況),然后考慮如何調整使得流量平衡。
設超級源點\(ss\),超級匯點\(st\)。對於每條邊\(e=(u, v, high, low)\),添加\(u\)\(st\)\(ss\)\(v\)容量為\(low\)的邊,將\((u,v)\)的容量設為\(high-low\)
\(low\)\(u\)處導走,並在\(v\)處加回便是一個強制流滿下界的操作,同時不會影響到原本的網絡;\((u,v)\)的流量設為\(high-low\)是為了限制流量的上界。
接下來跑一遍從\(ss\)\(st\)的最大流,若能把所有附加的邊全部跑滿,則說明在滿足上界限制的情況下所有的下界限制均被滿足,合法方案即為每條邊下界流量加上跑完這遍網絡流之后所用的流量;否則無解。
一個小優化是,兩個點之間無下界無費用的流可以合並。

無源匯上下界最小費用流

將后面那個最大流改成最小費用最大流即可。

有源匯上下界可行流

添加一條由匯點\(t\)\(s\)的下界為0,上界為正無窮的邊即可轉化為無源匯上下界可行流。
若有解,\(s\)\(t\)的可行流流量即為該附加邊所流的流量。

有源匯上下界最大流

一種方法是二分\(t\)\(s\)的附加邊的下界,然后跑普通可行流判斷合法性。
另一種方法是先附加一條無下界的正無窮的邊,變成無源匯跑一遍可行流之后若存在合法方案便將其刪去,在剩余的網絡中跑一遍從\(s\)\(t\)的普通最大流,答案為可行流的流量加上最大流得到的流量。這個也很好理解,先跑一遍可行流滿足下界,之后在上界的限制下繼續嘗試增廣得到實際的最大流。
*注意:最大流是在跑完可行流的網絡上跑,不要跑到初始網絡上。

有源匯上下界最小流

一種是二分\(t\)\(s\)的附加邊的上界,然后跑普通可行流判斷合法性。
另一種方法是先附加一條無下界的正無窮的邊,變成無源匯跑一遍可行流之后若存在合法方案便將其刪去,在剩余的網絡中跑一遍從\(t\)\(s\)的普通最大流,答案為可行流的流量減去最大流得到的流量。簡單來說,就是先找到可行的方案,再把能退回去的流都退回去。
注意事項同上。

參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM