1. 程式人生 > >(教你徹底理解)網路流:基本概念與演算法 最大流最小割

(教你徹底理解)網路流:基本概念與演算法 最大流最小割

一.網路流:流&網路&

1.網路流問題(NetWork Flow Problem):

給定指定的一個有向圖,其中有兩個特殊的點源S(Sources)和匯T(Sinks),每條邊有指定的容量(Capacity),求滿足條件的從S到T的最大流(MaxFlow).

The network flow problem considers a graph G with a set of sources S and sinks T and for which each edge has an assigned capacity (weight), and then asks to find the maximum flow that can be routed from S to T while respecting the given edge capacities.

下面給出一個通俗點的解釋

(下文基本避開形式化的證明 基本都用此類描述敘述)

好比你家是匯 自來水廠(有需要的同學可以把自來水廠當成銀行之類 以下類似)是源

然後自來水廠和你家之間修了很多條水管子接在一起 水管子規格不一 有的容量大 有的容量小

然後問自來水廠開閘放水 你家收到水的最大流量是多少

如果自來水廠停水了 你家那的流量就是0 當然不是最大的流量

但是你給自來水廠交了100w美金 自來水廠拼命水管裡通水 但是你家的流量也就那麼多不變了 這時就達到了最大流

-------------------------------------------------------------------------------------------------------------

2.三個基本的性質:

如果 C代表每條邊的容量 F代表每條邊的流量

一個顯然的實事是F小於等於C 不然水管子就爆了

這就是網路流的第一條性質 容量限制(Capacity Constraints):F<x,y> ≤ C<x,y>

再考慮節點任意一個節點 流入量總是等於流出的量 否則就會蓄水(爆炸危險...)或者平白無故多出水(有地下水湧出?)

這是第二條性質 流量守恆(Flow Conservation):Σ F<v,x> = Σ F<x,u>

當然源和匯不用滿足流量守恆 我們不用去關心自來水廠的水是河裡的 還是江裡的

(插播廣告: 節約水資源 人人有責!)

最後一個不是很顯然的性質 是斜對稱性(Skew Symmetry): F<x,y> = - F<y,x>

這其實是完善的網路流理論不可缺少的 就好比中學物理裡用正負數來定義一維的位移一樣

百米起點到百米終點的位移是100m的話 那麼終點到起點的位移就是-100m

同樣的 x向y流了F的流 y就向x流了-F的流

-------------------------------------------------------------------------------------------------------------

3.容量網路&流量網路&殘留網路:

網路就是有源匯的有向圖 關於什麼就是指邊權的含義是什麼

容量網路就是關於容量的網路 基本是不改變的(極少數問題需要變動)

流量網路就是關於流量的網路 在求解問題的過程中

通常在不斷的改變 但是總是滿足上述三個性質

調整到最後就是最大流網路 同時也可以得到最大流值

殘留網路往往概括了容量網路和流量網路 是最為常用的

殘留網路=容量網路-流量網路

這個等式是始終成立的 殘留值當流量值為負時甚至會大於容量值

流量值為什麼會為負?有正必有負,記住斜對稱性!

-------------------------------------------------------------------------------------------------------------

4.割&割集:

無向圖的割集(Cut Set):C[A,B]是將圖G分為A和B兩個點集 A和B之間的邊的全集

A set of edges of a graph which, if removed (or "cut"), disconnects the graph (i.e., forms a disconnected graph).

網路的割集:C[S,T]是將網路G分為s和t兩部分點集 S屬於s且T屬於t 從S到T的邊的全集

帶權圖的割(Cut)就是割集中邊或者有向邊的權和

Given a weighted, undirected graph G=(V,E) and a graphical partition of V into two sets A and B, the cut of G with respect to A and B is defined as cut(A,B)=sum_(i in A,j in B)W(i,j),where W(i,j) denotes the weight for the edge connecting vertices i and j. The weight of the cut is the sum of weights of edges crossing the cut.

通俗的理解一下:

割集好比是一個恐怖分子 把你家和自來水廠之間的水管網路砍斷了一些

然後自來水廠無論怎麼放水 水都只能從水管斷口嘩嘩流走了 你家就停水了

(插播廣告: 節約水資源 人人有責!)

割的大小應該是恐怖分子應該關心的事 畢竟細管子好割一些

而最小割花的力氣最小

==================================================================================

二.計算最大流的基本演算法

那麼怎麼求出一個網路的最大流呢?

這裡介紹一個最簡單的演算法:Edmonds-Karp演算法 即最短路徑增廣演算法 簡稱EK演算法

EK演算法基於一個基本的方法:Ford-Fulkerson方法 即增廣路方法 簡稱FF方法

增廣路方法是很多網路流演算法的基礎 一般都在殘留網路中實現

其思路是每次找出一條從源到匯的能夠增加流的路徑 調整流值和殘留網路 不斷調整直到沒有增廣路為止

FF方法的基礎是增廣路定理(Augmenting Path Theorem):網路達到最大流當且僅當殘留網路中沒有增廣路

證明略 這個定理應該能夠接受的吧

EK演算法就是不斷的找最短路 找的方法就是每次找一條邊數最少的增廣 也就是最短路徑增廣

這樣就產生了三個問題:

-------------------------------------------------------------------------------------------------------------

1.最多要增廣多少次?

可以證明 最多O(VE)次增廣 可以達到最大流 證明略

2.如何找到一條增廣路?

先明確什麼是增廣路 增廣路是這樣一條從s到t的路徑 路徑上每條邊殘留容量都為正

把殘留容量為正的邊設為可行的邊 那麼我們就可以用簡單的BFS得到邊數最少的增廣路

3.如何增廣?

BFS得到增廣路之後 這條增廣路能夠增廣的流值 是路徑上最小殘留容量邊決定的

把這個最小殘留容量MinCap值加到最大流值Flow上 同時路徑上每條邊的殘留容量值減去MinCap

最後 路徑上每條邊的反向邊殘留容量值要加上MinCap 為什麼? 下面會具體解釋

-------------------------------------------------------------------------------------------------------------

這樣每次增廣的複雜度為O(E) EK演算法的總複雜度就是O(VE^2)

事實上 大多數網路的增廣次數很少 EK演算法能處理絕大多數問題

平均意義下增廣路演算法都是很快的

增廣路演算法好比是自來水公司不斷的往水管網裡一條一條的通水

上面還遺留了一個反向邊的問題: 為什麼增廣路徑上每條邊的反向邊殘留容量值要加上MinCap?

因為斜對稱性! 由於殘留網路=容量網路-流量網路

容量網路不改變的情況下

由於增廣好比給增廣路上通了一條流 路徑說所有邊流量加MinCap

流量網路中路徑上邊的流量加MinCap 反向邊流量減去MinCap

相對應的殘留網路就發生相反的改變

這樣我們就完成了EK演算法 具體實現可以用鄰接表存圖 也可以用鄰接矩陣存圖

鄰接表存圖 由於流量同時存在於邊與反向邊 為了方便求取反向邊 建圖把一對互為反向邊的邊建在一起

程式碼很簡單 最好自己實現一下

EK

看一個具體的增廣路演算法的例子吧

==================================================================================

三.最大流最小割定理

下面介紹網路流理論中一個最為重要的定理

最大流最小割定理(Maximum Flow, Minimum Cut Theorem):網路的最大流等於最小割

The maximum flow between vertices v_i and v_j in a graph G is exactly the weight of the smallest set of edges to disconnect G with v_i and v_j in different components.

具體的證明分三部分

1.任意一個流都小於等於任意一個割

這個很好理解 自來水公司隨便給你家通點水 構成一個流

恐怖分子隨便砍幾刀 砍出一個割

由於容量限制 每一根的被砍的水管子流出的水流量都小於管子的容量

每一根被砍的水管的水本來都要到你家的 現在流到外面 加起來得到的流量還是等於原來的流

管子的容量加起來就是割 所以流小於等於割

由於上面的流和割都是任意構造的 所以任意一個流小於任意一個割

2.構造出一個流等於一個割

當達到最大流時 根據增廣路定理

殘留網路中s到t已經沒有通路了 否則還能繼續增廣

我們把s能到的的點集設為S 不能到的點集為T

構造出一個割集C[S,T] S到T的邊必然滿流 否則就能繼續增廣

這些滿流邊的流量和就是當前的流即最大流

把這些滿流邊作為割 就構造出了一個和最大流相等的割

3.最大流等於最小割

設相等的流和割分別為Fm和Cm

則因為任意一個流小於等於任意一個割

任意F≤Fm=Cm≤任意C

定理說明完成

==================================================================================

四.簡單的應用

Poj 1459是一個很典型的網路流應用

把電流想象成水流

注意把多源多匯轉化為單源單匯即可利用EK演算法解決問題

網路流的應用還有很多 化歸的思想是網路流最具魅力的地方

程式碼如下:

PowerNet
const    maxh=10;
    maxn=100; maxq=110;
    num:set of char=['0'..'9'];
    oo=1000000;
 var    c,f:array[0..maxn+1,0..maxn+1]of longint;
    n,m,k1,k2,tx,hx,head,tail,s,t,x,y,z,i:longint;
    pre,h:array[0..maxn+1]of longint;
    p:array[0..maxn+1]of boolean;
    q:array[1..maxq]of longint;
 procedure getc(var x:longint);
 var    ch:char;
 begin
x:=0;
read(ch);
while not(ch in num) do
    read(ch);
while ch in num do
    begin
    x:=x*10+ord(ch)-48;
    read(ch);
    end;
end;
procedure pop;
begin
p[q[head]]:=false;
inc(head); inc(hx);
if head>maxq then head:=1;
end;
procedure push(x:longint);
begin
inc(tail); inc(tx);
if tail>maxq then tail:=1;
q[tail]:=x; p[x]:=true;
end;
function min(x,y:longint):longint;
begin
min:=x;
if y<x then min:=y;
end;
begin
assign(input,'PowerNet.in'); reset(input);
assign(output,'PowerNet.out'); rewrite(output);
while not seekeof do
    begin
        read(n,k1,k2,m);
    s:=n; t:=n+1;
    fillchar(c,sizeof(c),0);
    for i:=1 to m do
        begin
        getc(x); getc(y); getc(z);
        c[x,y]:=c[x,y]+z;
        end;
    for i:=1 to k1 do
        begin
        getc(x); getc(y);
        c[s,x]:=y;
        end;
    for i:=1 to k2 do
        begin
        getc(x); getc(y);
        c[x,t]:=y;
        end;
    hx:=1; tx:=0;
    head:=1; tail:=0;
    fillchar(p,sizeof(p),false);
    p[s]:=true; p[t]:=true;
    fillchar(f,sizeof(f),0);
    fillchar(pre,sizeof(pre),0);
    fillchar(h,sizeof(h),0);
    h[s]:=maxh; dec(n);
    for i:=0 to n do
        if c[s,i]>0
            then begin
            h[i]:=1; pre[i]:=c[s,i];
            f[s,i]:=c[s,i]; f[i,s]:=-c[s,i];
            push(i);
            end;
    while hx<=tx do
        begin
        x:=q[head];
        for i:=0 to t do
            begin
            y:=c[x,i]-f[x,i];
            if (h[x]=h[i]+1)and(y>0)
                then begin
                if not p[i] then push(i);
                z:=min(pre[x],y);
                f[x,i]:=f[x,i]+z;
                f[i,x]:=f[i,x]-z;
                pre[x]:=pre[x]-z;
                pre[i]:=pre[i]+z;
                end;
            if pre[x]=0 then break;
            end;
        pop;
        if pre[x]>0
            then begin
            y:=oo;
            for i:=0 to t do
                if c[x,i]>f[x,i]
                    then y:=min(y,h[i]);
            h[x]:=y+1;
            push(x);
            end;
        end;
    writeln(pre[t]);
    end;
close(input); close(output);
end.


相關推薦

徹底理解網路基本概念演算法

一.網路流:流&網路&割 1.網路流問題(NetWork Flow Problem): 給定指定的一個有向圖,其中有兩個特殊的點源S(Sources)和匯T(Sinks),每條邊有指定的容量(Capacity),求滿足條件的從S到T的最大流(Max

Oracle知識梳理理論篇基本概念和術語整理

http 知識梳理 屬性集 操作 url 本質 開發 表格 weight 理論篇:基本概念和術語整理 一、關系數據庫 關系數據庫是目前應用最為廣泛的數據庫系統,它采用關系數據模型作為數據的組織方式,關系數據模型由關系的數據結構,關系的操作集合和關系的完整

Druid.io系列基本概念架構

在介紹Druid架構之前,我們先結合有關OLAP的基本原理來理解Druid中的一些基本概念。 1 資料 以圖3.1為例,結合我們在第一章中介紹的OLAP基本概念,按列的型別上述資料可以分成以下三類: 時間序列(Timestamp),Druid既是記憶

iOS/OS X記憶體管理基本概念原理

CSDN移動將持續為您優選移動開發的精華內容,共同探討移動開發的技術熱點話題,涵蓋移動應用、開發工具、移動遊戲及引擎、智慧硬體、物聯網等方方面面。如果您想投稿、尋求《近匠》報道,或給文章挑錯,歡迎傳送郵件至tangxy#csdn.net(請把#改成@)。  在Objective-C的記憶體管理中,其實就

資料結構:資料結構的基本概念演算法的時間和空間複雜度

資料結構討論的範疇 計算機技術的兩大支柱:1是資料結構,2是演算法。在某種程度上講,程式設計等同於資料結構+演算法。 程式設計是為計算機設計一組指令集,演算法是解決問題的策略,資料結構是模型。 問

計算機網路基礎 - 一些基本概念網絡結構

logs 網路 兩個 wdm comment quest 利用 gin 規範 1. 基本概念 計算機網絡 = 通信技術+計算機技術,是兩項技術緊密結合的產物。 通信系統的基礎模型: 計算機網絡,是指將地理位置不同、具有獨立功能的多臺計算機及其外部設備,通過通信線路連接,在

看完讓徹底理解 WebSocket 原理,附完整的實戰代碼包含前端和後端

tcp 協議 learn php 握手 live 雙向 簡單 再次 註意 1、前言 最近有同學問我有沒有做過在線咨詢功能。同時,公司也剛好讓我接手一個 IM 項目。所以今天抽時間記錄一下最近學習的內容。本文主要剖析了 WebSocket 的原理,以及附上一個完整的聊天室實戰

手把手深入理解Spring原始碼-spring開篇

授人以魚不如授人以漁,《手把手教你深入理解Spring原始碼》專欄教你如何學習、思考、閱讀Spring框架,並應對其它開源框架不再畏懼。 接著上篇的文章講,上篇的文章講述了什麼是IOC,這篇講述什麼又是AOP? 一樣的在看這篇文章之前,大家不妨先花點時間思考一下。 1、AOP的設計原理

從 poj 1163 The Triangle 徹底學會動態規劃——入門篇

動態規劃相信大家都知道,動態規劃演算法也是新手在剛接觸演算法設計時很苦惱的問題,有時候覺得難以理解,但是真正理解之後,就會覺得動態規劃其實並沒有想象中那麼難。網上也有很多關於講解動態規劃的文章,大多都是敘述概念,講解原理,讓人覺得晦澀難懂,即使一時間看懂了,發現當自己做題的時

poj-1163徹底學會動態規劃——入門篇

 動態規劃相信大家都知道,動態規劃演算法也是新手在剛接觸演算法設計時很苦惱的問題,有時候覺得難以理解,但是真正理解之後,就會覺得動態規劃其實並沒有想象中那麼難。網上也有很多關於講解動態規劃的文章,大多都是敘述概念,講解原理,讓人覺得晦澀難懂,即使一時間看懂了,發現當自己做

SwiftUI - 一步一步使用UIViewRepresentable封裝網路載入檢視UIActivityIndicatorView

概述 網路載入檢視,在一個聯網的APP上可以講得上是必須要的元件,在SwiftUI中它並沒有提供如 UIKit 中的UIActivityIndicatorView直接提供給我們呼叫,但是我們可以通過 SwiftUI 中的UIViewRepresentable協議封裝UIActivityIndicatorVie

洛谷 P2765 魔術球問題網路24題-

題意:中文題(lrj黑書上好像有這道題) 思路:這個題的建圖還真的是挺有意思的,我們把一個球拆成2個點a,b。 然後讓a點連S點,b點連T點,如果有兩個數的加和為平方數,那我們就用第一個數的a點連向第二個數的b點,這樣就有一條流直接流向匯點T 程式碼:(順便get了怎麼列印路徑,賦學習傳送門) #

RS232線序問題研旭手把手學DSP

在研旭的手把手中,有一張圖很可能會給大家帶來誤導,因為沒有註明這是公頭的線序還是母頭的線序,所以很容易把RXD和TXD接反。 看下圖: 在9芯序列介面排列圖中,我們可以看到5針腳的一排    從左往右是1-5, 再看下圖,我們可以清楚的看出,左邊這個母頭是符合書

家java】Java中的執行緒池,真的用對了嗎?用正確的姿勢使用執行緒池

相關閱讀 【小家java】java5新特性(簡述十大新特性) 重要一躍 【小家java】java6新特性(簡述十大新特性) 雞肋升級 【小家java】java7新特性(簡述八大新特性) 不溫不火 【小家java】java8新特性(簡述十大新特性) 飽受讚譽 【小家java】java9

【Power Network】【POJ - 1459】網路-

題目: A power network consists of nodes (power stations, consumers and dispatchers) connected by power transport lines. A node u may be supplied wit

洛谷 ~ P2604 [ZJOI2010] ~ 網路擴容 費用

第一問:建邊u->v容量為題中容量,花費為0,跑費用流得到的最大流就是答案。 第二問:建邊u->v容量為INF,花費題中花費,跑費用流得到的費用就是答案。 #include<bits/stdc++.h> using namespace std

計蒜客 ICPC焦作網路賽 Modular Production Line區間k覆蓋 + 費用

大致題意:給你N個機器,可以生產M個物品,每個物品i生產出來需要區間[li,ri]內的機器一起工作。可以產生wi的利潤。每個物品只能生產一次,每個機器最多隻能工作k次,現在問你能夠產生的最大利潤。 每個機器只能工作k次,每個物品只能夠生產一次,求最大

網路24題】餐巾計劃費用

題意 一個餐廳在相繼的 nnn 天裡,每天需用的餐巾數不盡相同。假設第 iii 天需要 rir_iri​​​ 塊餐巾。餐廳可以購買新的餐巾,每塊餐巾的費用為 PPP 分;或者把舊餐巾送到快洗部,洗一塊需 MMM天,其費用為 FFF 分;或者送到慢洗部,洗一塊需

網路24題】運輸問題費用

題意 W 公司有 mmm 個倉庫和 nnn 個零售商店。第 iii 個倉庫有 aia_iai​​​ 個單位的貨物;第 jjj 個零售商店需要 bjb_jbj​​​ 個單位的貨物。貨物供需平衡,即∑i=1mai=∑j=1nbj​​\sum\limits_{i =

網路

在一個網路裡   對於S流到T的流量,有很多值。其中這些值的最大值,我們稱為S到T的最大流 (想象成自來水管,S就是水廠,T就是你家,邊就是管子,最大流就是能流到你家水量的最大值)   介紹三個相關的知識點  (1) 容量網路    &nbs