国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

數(shù)學(xué)建模十大算法04—圖論算法(最短路徑、最小生成樹(shù)、最大流問(wèn)題、二分圖)

這篇具有很好參考價(jià)值的文章主要介紹了數(shù)學(xué)建模十大算法04—圖論算法(最短路徑、最小生成樹(shù)、最大流問(wèn)題、二分圖)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

一、最短路徑問(wèn)題

從圖中的某個(gè)頂點(diǎn)出發(fā),到達(dá)另一個(gè)頂點(diǎn)的所經(jīng)過(guò)的邊的權(quán)重之和最小的一條路徑。

1.1 兩個(gè)指定頂點(diǎn)之間的最短路徑

問(wèn)題如下:給出了一個(gè)連接若干個(gè)城鎮(zhèn)的鐵路網(wǎng)絡(luò),在這個(gè)網(wǎng)絡(luò)的兩個(gè)指定城鎮(zhèn)間,求一條最短鐵路線。
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

1.1.1 Dijkstra算法

迪杰斯特拉(Dijkstra)算法是由荷蘭計(jì)算機(jī)科學(xué)家狄克斯特拉于1959年提出的。是尋找從一個(gè)頂點(diǎn)到其余各頂點(diǎn)的最短路徑算法,可用來(lái)解決最短路徑問(wèn)題。詳細(xì)的講解可參考:數(shù)據(jù)結(jié)構(gòu)–Dijkstra算法最清楚的講解

更正:第2、3步中,B(23)應(yīng)為B(13)。
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

迪杰斯特拉算法采用貪心算法的策略,將所有頂點(diǎn)分為已標(biāo)記點(diǎn)和未標(biāo)記點(diǎn)兩個(gè)集合,從起始點(diǎn)開(kāi)始,不斷在未標(biāo)記點(diǎn)中尋找距離起始點(diǎn)路徑最短的頂點(diǎn),并將其標(biāo)記,直到所有頂點(diǎn)都被標(biāo)記為止。 需要注意的一點(diǎn)是該方法不能處理帶有負(fù)權(quán)邊的圖,下面我們舉出一個(gè)實(shí)例并通過(guò)迪杰斯特拉方法對(duì)其進(jìn)行求解。

【例】 某公司在六個(gè)城市 c 1 , c 2 , c 3 , . . . , c 6 c_1,c_2,c_3,...,c_6 c1?,c2?,c3?,...,c6? 中有分公司,從 c i c_i ci? c j c_j cj? 的直接航程票價(jià)記在下述矩陣的 ( i , j ) (i,j) (i,j) 位置上(∞表示無(wú)直接航路)。請(qǐng)幫助該公司設(shè)計(jì)一張城市 c 1 c_1 c1? 到其他城市間的票價(jià)最便宜的路線圖。
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
用矩陣 a n × n a_{n×n} an×n? (n為頂點(diǎn)個(gè)數(shù)) 存放各邊權(quán)的鄰接矩陣,行向量 p d 、 i n d e x 1 、 i n d e x 2 、 d pd、index_1、index_2、d pd、index1?index2?、d 分別用來(lái)存放 P P P 標(biāo)號(hào)信息、標(biāo)號(hào)頂點(diǎn)順序、標(biāo)號(hào)頂點(diǎn)索引、最短通路的值。其中分量
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
i n d e x 2 ( i ) index_2(i) index2?(i) 存放始點(diǎn)到第 i i i 頂點(diǎn)最短通路中第 i i i 頂點(diǎn)的序號(hào); d ( i ) d(i) d(i) 存放由始點(diǎn)到第 i i i 頂點(diǎn)最短通路的值。

求第一個(gè)城市到其他城市的最短路徑的Matlab程序如下:

clc,clear
a=zeros(6); %鄰接矩陣初始化
a(1,2)=50;a(1,4)=40;a(1,5)=25;a(1,6)=10;
a(2,3)=15;a(2,4)=20;a(2,6)=25;
a(3,4)=10;a(3,5)=20;
a(4,5)=10;a(4,6)=25;
a(5,6)=55;
a=a+a';  % 兩點(diǎn)之間的距離是一樣的→對(duì)稱矩陣
a(a==0)=inf;
pb(1:length(a))=0;pb(1)=1;index1=1;index2=ones(1,length(a));
d(1:length(a))=inf;d(1)=0;
temp=1; %最新的P標(biāo)號(hào)的頂點(diǎn)
while sum(pb)<length(a)
   tb=find(pb==0);
   d(tb)=min(d(tb),d(temp)+a(temp,tb));
   tmpb=find(d(tb)==min(d(tb)));
   temp=tb(tmpb(1)); %可能有多個(gè)點(diǎn)同時(shí)達(dá)到最小值,只取其中的一個(gè)
   pb(temp)=1;
   index1=[index1,temp];
   temp2=find(d(index1)==d(temp)-a(temp,index1));
   index2(temp)=index1(temp2(1));
end
d, index1, index2

運(yùn)行結(jié)果為:
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
結(jié)果表示,最終求得的 c 1 c_1 c1? c 2 , . . . , c 6 c_2,...,c_6 c2?,...,c6? 的最便宜票價(jià)分別為35,45,35,25,10。

1.1.2 Matlab函數(shù)

【例】 在下圖中,用點(diǎn)表示城市,現(xiàn)有 v 1 , v 2 , . . . , v 5 v_1,v_2,...,v_5 v1?,v2?,...,v5? 共5個(gè)城市。點(diǎn)與點(diǎn)之間的連線表示城市間有道路相連。連線旁的數(shù)字表示道路的長(zhǎng)度?,F(xiàn)計(jì)劃從城市 v 1 v_1 v1? 到城市 v 3 v_3 v3? 鋪設(shè)一條天然氣管道,請(qǐng)?jiān)O(shè)計(jì)出最小長(zhǎng)度管道鋪設(shè)方案。
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
除了上面提到的迪杰斯特拉求兩點(diǎn)之間最短路徑外,我們還可以使用MATLAB自帶的graphshortestpath函數(shù)。

W = [10,5,1,2,4,7,6,3,9,2];
% sparse生成稀疏矩陣,除了標(biāo)注的元素外,其余都是0
DG = sparse([1,1,2,2,3,4,4,5,5,5],...  % sparse第一個(gè)矩陣,三個(gè).代表沒(méi)寫(xiě)完,下一行接著
            [2,5,3,5,4,1,3,2,3,4],W)  % sparse第二個(gè)矩陣
% sparse里第一個(gè)和第二個(gè)矩陣相同位置的元素值就是非零元素的值,W是每條邊的權(quán)值
% dist是最短路徑的值,path是最短路徑的節(jié)點(diǎn)順序,pred是每一個(gè)節(jié)點(diǎn)的最短路徑的終點(diǎn)前一個(gè)節(jié)點(diǎn)
[dist,path,pred] = graphshortestpath(DG,1,3)  % 節(jié)點(diǎn)13的最短路徑
point_name = ["city1","city2","city3","city4","city5"];
p = biograph(DG,point_name,'ShowWeights','on')
h = view(p)  % biograph生成圖對(duì)象,view顯示該圖

我們可以查看一下sparse生成的稀疏矩陣DG:
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

從矩陣的角度看:
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

view顯示此時(shí)生成的圖對(duì)象:
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
然后,我們將通過(guò)該函數(shù)計(jì)算得到的最短路徑節(jié)點(diǎn)以紅色顯示:

% 將最短路徑的結(jié)點(diǎn)以紅色顯示
set(h.Nodes(path),'Color',[1 0.4 0.4]);
% 將最短路徑的弧以紅色顯示
edges = getedgesbynodeid(h,get(h.Nodes(path),'ID'));  % getedgesbynodeid得到圖h指定便的句柄,第一個(gè)參數(shù)是圖,第二個(gè)是邊的出點(diǎn),第三個(gè)是邊的入點(diǎn)  
% get查詢圖的屬性   set用來(lái)設(shè)置圖形屬性
set(edges,'LineColor',[1 0 0]);  % RGB數(shù)值
set(edges,'LineWidth',2.0);

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
注意:這里的ID是Matlab自帶的。

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

1.2 每對(duì)頂點(diǎn)之間的最短路徑
1.2.1 Dijkstra算法

計(jì)算賦權(quán)圖中各對(duì)頂點(diǎn)之間最短路徑,顯然可以調(diào)用Dijkstra算法。具體方法是:每
次以不同的頂點(diǎn)作為起點(diǎn),用Dijkstra算法求出從該起點(diǎn)到其余頂點(diǎn)的最短路徑, 反復(fù)執(zhí)行n-1次這樣的操作,就可得到從每一個(gè)頂點(diǎn)到其他頂點(diǎn)的最短路徑。這種算法的時(shí)間復(fù)雜度 O ( n 3 ) O(n^3) O(n3) 為。

1.2.2 Floyd算法

第二種解決這一問(wèn)題的方法是由R. W. Floyd提出的算法,稱為Floyd算法。其時(shí)間復(fù)雜度也是 O ( n 3 ) O(n^3) O(n3) ,但形式上要簡(jiǎn)單些。

對(duì)于賦權(quán)圖 G = ( V , E , A 0 ) G=(V,E,A_0) G=(V,E,A0?) ,其中,頂點(diǎn)集 V V V = { v 1 , . . . , v n v_1,...,v_n v1?,...,vn?},鄰接矩陣
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
其中,
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
Floyd算法的基本思想是遞推產(chǎn)生一個(gè)矩陣序列 A 1 , . . . A k , . . . A n A_1,...A_k,...A_n A1?,...Ak?,...An?, 其中矩陣A的第 i i i 行第 j j j 列元素 A k ( i , j ) A_k(i,j) Ak?(i,j) 表示從頂點(diǎn) v i v_i vi? 到頂點(diǎn) v j v_j vj? 的路徑上所經(jīng)過(guò)的頂點(diǎn)序號(hào)不大于 k k k 的最短路徑長(zhǎng)度。

計(jì)算時(shí)利用迭代公式:
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
舉一個(gè)簡(jiǎn)單的例子幫助大家理解:
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
對(duì)上述信息初始化:
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
第一次迭代時(shí),以 a 為起點(diǎn)判斷矩陣是否需要更新:

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
第二次迭代,加入頂點(diǎn) b,即k=1時(shí)判斷矩陣是否需要更新:
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
第三次迭代,加入頂點(diǎn) c,即k=2時(shí)判斷矩陣是否需要更新:
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
上述案例來(lái)自B站:數(shù)據(jù)結(jié)構(gòu)

【例】用Floyd算法求解和之前同樣的問(wèn)題。

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
Matlab代碼如下:

clear;clc;
n=6; a=zeros(n);
a(1,2)=50;a(1,4)=40;a(1,5)=25;a(1,6)=10;
a(2,3)=15;a(2,4)=20;a(2,6)=25; a(3,4)=10;a(3,5)=20;
a(4,5)=10;a(4,6)=25; a(5,6)=55;
a=a+a'; 
a(a==0)=inf;  % 把所有零元素替換成無(wú)窮
a([1:n+1:n^2])=0;  % 對(duì)角線元素替換成零,Matlab中數(shù)據(jù)是逐列存儲(chǔ)的★
path=zeros(n);
for k=1:n
   for i=1:n
      for j=1:n
         if a(i,j)>a(i,k)+a(k,j)
            a(i,j)=a(i,k)+a(k,j);
            path(i,j)=k;
         end 
      end
   end
end
a, path

求出來(lái)的結(jié)果為:
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
矩陣 a a a 的第一行求得 c 1 c_1 c1? c 2 , . . . , c 6 c_2,...,c_6 c2?,...,c6? 的最便宜票價(jià)分別為35,45,35,25,10。

1.2.3 Matlab函數(shù)

利用graphallshortestpaths函數(shù),可以求出所有結(jié)點(diǎn)之間的最短路徑。

Dists = graphallshortestpaths(DG)  %求所有最短路徑

以1.1.2中的為例,我們可以看到求得的矩陣中城市 v 1 v_1 v1? 到城市 v 3 v_3 v3? 的最小路徑為9。
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

二、最小生成樹(shù)問(wèn)題

欲修筑連接 n 個(gè)城市的鐵路,已知 i i i 城與 j j j 城之間的鐵路造價(jià)為 c i j c_{ij} cij? 設(shè)計(jì)一個(gè)線路圖,使總造價(jià)最低。上述問(wèn)題的數(shù)學(xué)模型是在連通賦權(quán)圖上求權(quán)最小的生成樹(shù)。賦權(quán)圖的具有最小權(quán)的生成樹(shù)叫做最小生成樹(shù)。 下面介紹構(gòu)造最小生成樹(shù)的兩種常用算法。

2.1 Kruskal算法

1、把圖 G G G 中的所有邊全部去掉,得到所有單獨(dú)的頂點(diǎn) V V V 構(gòu)成圖 T = ( V , T=(V, T=(V, { } ) ) ),其中 V V V 是頂點(diǎn)集合;
2、從 G G G 中取出當(dāng)前權(quán)值最小的邊,如果該邊加入 T T T 的邊的集合后 T T T 不形成回路,則加入 T T T ;否則舍棄;
3、重復(fù)第2步,直到 T T T 中有 n ? 1 n-1 n?1 條邊 ( n n n 是頂點(diǎn)數(shù));
4、若第2步中遇到兩條權(quán)值相同的最小權(quán)值邊,任選一條即可,所以最小生成樹(shù)可能不唯一,但權(quán)值之和相同。

Kruskal簡(jiǎn)單理解就是每次都選一條權(quán)值最小的邊。適合邊少點(diǎn)多的圖。

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
用Kruskal算法求解上圖的Matlab代碼為:

clc;clear; 
% 輸入鄰接矩陣
a(1,2)=50; a(1,3)=60; a(2,4)=65; a(2,5)=40; 
a(3,4)=52;a(3,7)=45; a(4,5)=50; a(4,6)=30; 
a(4,7)=42; a(5,6)=70;  
[i,j,b]=find(a);

[i,j,b]=find(a)這一步的含義是求出有權(quán)值邊的索引。
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
構(gòu)建弧表表示矩陣data,及所有邊的索引矩陣index

data=[i';j';b']
index=data(1:2,:)

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

loop=max(size(a))-1;
result=[];
while length(result)<loop 
   temp=min(data(3,:));  % 30
   flag=find(data(3,:)==temp);  % 7-->在第七個(gè)位置上
   flag=flag(1);
   v1=data(1,flag);  %7個(gè)位置上對(duì)應(yīng)的第一行數(shù)據(jù)為4
   v2=data(2,flag);  %7個(gè)位置上對(duì)應(yīng)的第二行數(shù)據(jù)為6
   if index(1,flag)~=index(2,flag) 
      result=[result,data(:,flag)]; % 4 6 30
   end 
   index(find(index==v2))=v1; % 把index里面的6全部改成4
   data(:,flag)=[]; % 刪除第七個(gè)位置的三個(gè)值 4 6 30
   index(:,flag)=[]; % 刪除第七個(gè)位置的索引
end 
result 

求得的結(jié)果為:

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

在圖上標(biāo)注出最小生成樹(shù)如下:
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

2.2 Prim算法

1、設(shè)置一個(gè)圖 U U U ,將原圖 G G G 中任意一頂點(diǎn)取出加入 U U U 中;
2、在所有 u ∈ U u∈U uU v ∈ ( V ? U ) v∈(V-U) v(V?U) 的邊 ( u , v ) (u,v) (u,v) 中找到一條權(quán)值最小的邊,并入圖 U U U 中;
3、重復(fù)步驟2,直到 U U U 中包含了所有頂點(diǎn);
4、若第2步中遇到兩條權(quán)值相同的最小權(quán)值邊,任選一條即可,所以最小生成樹(shù)可能不唯一,但權(quán)值之和相同。

Prim算法簡(jiǎn)單理解就是選頂點(diǎn)。適合邊多點(diǎn)少的圖。

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
使用Prim算法求解的Matlab代碼如下:

a=zeros(7);
a(1,2)=50; 
a(1,3)=60; 
a(2,4)=65; 
a(2,5)=40; 
a(3,4)=52;
a(3,7)=45; 
a(4,5)=50; 
a(4,6)=30;
a(4,7)=42; 
a(5,6)=70;  
a=a+a';
a(find(a==0))=inf;

初始化之后的矩陣 a a a 為:
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

result=[]  % 存儲(chǔ)最小生成樹(shù)
p=1;  % 選取頂點(diǎn)1
tb=2:length(a)  % 剩余頂點(diǎn)
while length(result)~=length(a)-1  % 當(dāng)邊的個(gè)數(shù)=n-1時(shí),退出循環(huán)
   temp=a(p,tb);  % tb中存儲(chǔ)著其他未處理的頂點(diǎn),temp存儲(chǔ)著未處理的邊的權(quán)重
   temp=temp(:); 
   d=min(temp); 
   [jb,kb]=find(a(p,tb)==d);  % 找到最小權(quán)的橫縱坐標(biāo)
   j=p(jb(1));  % j存儲(chǔ)找到的邊的起始位置,可能有多最小權(quán),但我們只取一個(gè)
   k=tb(kb(1));  % k存儲(chǔ)找到的邊的末位置,可能有多最小權(quán),但我們只取一個(gè)
   result=[result,[j;k;d]];  % 存儲(chǔ)找到的此條邊的信息
   p=[p,k];  % 包含新加入的頂點(diǎn)
   tb(find(tb==k))=[];  % 在tb中刪除與剛加入的邊相連接的點(diǎn) 
end 
result

最終得到的結(jié)果為:
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

求得的最小生成樹(shù)在圖上標(biāo)注為:

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
我們可以看到,當(dāng)邊的權(quán)值無(wú)重復(fù)值時(shí),用Kruskal和Prim求得的最小生成樹(shù)是一致的。

三、網(wǎng)絡(luò)最大流問(wèn)題

網(wǎng)絡(luò)流優(yōu)化問(wèn)題一般是指在有向圖中分配流量,使每條邊的流量不會(huì)超過(guò)它的容量約束(Capacity),同時(shí)達(dá)到路徑長(zhǎng)度最小或者花費(fèi)最小等目標(biāo)函數(shù)的優(yōu)化問(wèn)題。因?yàn)樵谶\(yùn)籌學(xué)中,我們經(jīng)常把有向圖稱為網(wǎng)絡(luò)。所以這類基于有向圖流量分配的優(yōu)化問(wèn)題也被稱之為網(wǎng)絡(luò)流優(yōu)化問(wèn)題。網(wǎng)絡(luò)流優(yōu)化屬于組合優(yōu)化問(wèn)題的一種。

3.1 網(wǎng)絡(luò)流問(wèn)題基礎(chǔ)

本小節(jié)內(nèi)容參考B站(強(qiáng)推?。。。?3-1: 網(wǎng)絡(luò)流問(wèn)題基礎(chǔ) Network Flow Problems

左圖邊的權(quán)重表示水管的容量,允許多少水流入。右圖邊的權(quán)重表示水管的空閑量,初始值是相同的,剛開(kāi)始時(shí)沒(méi)有水流入水管。算法在執(zhí)行時(shí),我們會(huì)用到右邊的圖。
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

第一次迭代: 選取一條從起點(diǎn) s s s t t t 的簡(jiǎn)單路徑(不能有回路)。假設(shè)找到了一條路徑,用紅色標(biāo)注為:
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
路徑上的權(quán)重為3、3、2,由于短板效應(yīng),這條路徑上只能通過(guò)流量為2的水。我們讓容量為2的水通過(guò)該條路徑,那么就要更新Residual的值。
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
注意上面有兩條管道Residual值為0,已經(jīng)飽和,代表它們不能輸送更多的水流了,在圖中我們將這兩條管道刪除。
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
以上就是第一輪循環(huán)。

第二輪迭代: 仍然是找到一條從起點(diǎn) s s s t t t 的簡(jiǎn)單路徑。
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
同樣地,更新Residual的值。
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
刪除飽和的邊:
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

第三輪迭代: 找到一條從起點(diǎn) s s s t t t 的簡(jiǎn)單路徑。
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
更新Residual的值。
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
在圖上刪除已經(jīng)飽和的邊:
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

第四輪迭代: 仍然試圖找到一條從起點(diǎn) s s s t t t 的簡(jiǎn)單路徑。但是此時(shí)不存在這樣的路徑,算法終止。
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

根據(jù) F l o w = C a p a c i t y ? R e s i d u a l Flow = Capacity - Residual Flow=Capacity?Residual 計(jì)算可得 f l o w flow flow(圖中紅色標(biāo)注)。
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

那么,我們可以得到總流量為5。兩個(gè)角度可以計(jì)算總流量:有兩份水從起點(diǎn)流出,流量分別為3和2。此外,有兩份水流入終點(diǎn),流量分別為2和3。

以上是一種簡(jiǎn)單的找網(wǎng)絡(luò)流的算法,但是該算法不能保證最優(yōu)性(結(jié)果不一定是最大流),舉一個(gè)簡(jiǎn)單的例子。

假設(shè)第一輪循環(huán)找的路徑為: S ? v 1 ? v 4 ? t S-v_1-v_4-t S?v1??v4??t,更新Residual的值。
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
第二輪找到的路徑為: S ? v 1 ? v 3 ? t S-v_1-v_3-t S?v1??v3??t,更新Residual的值。
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
第三輪循環(huán),找不到一條能從起點(diǎn)到重點(diǎn)的路徑,算法結(jié)束。但是此時(shí) f l o w = 4 flow=4 flow=4 并不是網(wǎng)絡(luò)的最大流。
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

f l o w = 4 flow=4 flow=4 稱為 B l o c k i n g Blocking Blocking F l o w Flow Flow,它雖然不是最大流,但是它將管道堵住了不能讓更多的水流通過(guò),所以稱為阻塞流。顯而易見(jiàn),最大流也是一種阻塞流。

我們可以看到,尋找路徑的先后順序變了之后,就有可能找不到最大流。所以,之后我們需要學(xué)習(xí)一些優(yōu)化算法。

3.2 Ford-Fulkerson算法

3.1小節(jié)中的簡(jiǎn)單算法有個(gè)缺陷:一旦找到一條不是最大流的路徑,就不能更正。這節(jié)課所學(xué)的算法,可以反悔,將不好的路徑撤銷。該節(jié)內(nèi)容依舊是參考:13-2: Ford-Fulkerson Algorithm 尋找網(wǎng)絡(luò)最大流
該算法比之前講的簡(jiǎn)單算法多了一步:增加反向路徑。

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
仍然是之前那個(gè)例子。第一次循環(huán) 找到路徑 S ? v 1 ? v 4 ? t S-v_1-v_4-t S?v1??v4??t (允許讓容量為3 的水通過(guò)),更新Residual的值。

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
然后,增加一個(gè)反向路徑,允許讓容量為3的水原路流回去,這樣的話,選擇的路徑不是最好的,我們就可以選擇撤銷。

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
第二輪循環(huán),找到路徑 S ? v 1 ? v 3 ? t S-v_1-v_3-t S?v1??v3??t ,并添加反向路徑:

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
合并方向相同的路徑:

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
第三輪循環(huán),假如沒(méi)有反向路徑的化,算法就會(huì)終止。但是添加了反向路徑之后,有下面這樣的結(jié)果:

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
合并方向相同邊的權(quán)重:

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
第四輪循環(huán),沒(méi)有任何水流能流入 v 3 v_3 v3? t t t。找不到路徑,算法終止。

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
算法結(jié)束后,不再需要反向流,將其去除。

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)


最壞情況下的時(shí)間復(fù)雜度
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
如果每次找的都是100→1→100這樣的路徑,那么要200次才能找到最大流。圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

更多細(xì)節(jié)可參考:最大流問(wèn)題與Ford-Fulkerson算法介紹

3.3 Edmonds-Karp算法

Edmonds-Karp算法與Ford-Fulkerson算法唯一的區(qū)別就在于,前者在尋找路徑時(shí)使用最短路徑算法(將Residual圖所有邊的權(quán)重都視為1,找到步長(zhǎng)最短的那一條路徑)。而后者允許使用任意方法尋找路徑,因此可以將Edmonds-Karp算法看作是后者的一種特殊情況。

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

這個(gè)算法的貢獻(xiàn)在于提升了時(shí)間復(fù)雜度,不依賴于網(wǎng)絡(luò)流的大小,之和邊和結(jié)點(diǎn)有關(guān)。

Edmonds-Karp算法時(shí)間復(fù)雜度分析:

  • m m m 為圖中邊的數(shù)量, n n n 為圖中頂點(diǎn)的數(shù)量,每一輪循環(huán)都是要找到一條最短路徑,所以每一輪循環(huán)的時(shí)間復(fù)雜度為 O ( m ) O(m) O(m)
  • 原圖中有 m m m 條邊,那么最多會(huì)有 m m m 條反向邊,所以Residual graph最多含有 2 m 2m 2m 條邊。
  • 算法證明最多循環(huán) m × n m×n m×n 輪。(證明過(guò)程略復(fù)雜,省略)
  • 每一輪需要 O ( m ) O(m) O(m),最多循環(huán) m × n m×n m×n 輪,所以最壞時(shí)間復(fù)雜度為 O ( m 2 ? n ) O(m^2·n) O(m2?n)。
  • 這個(gè)時(shí)間復(fù)雜度與最大流大小無(wú)關(guān),實(shí)際應(yīng)用中即使最大流很大,也不會(huì)有影響,因此該算法要優(yōu)于Ford-Fulkerson算法。
3.4 Dinic’s算法

該算法引入了一個(gè)新的概念:Level Graph。下面簡(jiǎn)單演示一下如何構(gòu)建Level Graph。

從起點(diǎn) s s s 開(kāi)始,將一步能到達(dá)的節(jié)點(diǎn) v 1 v_1 v1? v 2 v_2 v2? 記作第一層節(jié)點(diǎn),并保留其權(quán)重邊。

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

再?gòu)牡谝粚拥墓?jié)點(diǎn) v 1 v_1 v1? v 2 v_2 v2? 出發(fā),走一步能到達(dá)的節(jié)點(diǎn)有 v 3 v_3 v3? v 4 v_4 v4? ,將這兩個(gè)節(jié)點(diǎn)加入到Level Graph中的第二層節(jié)點(diǎn),并保留權(quán)值邊。

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
再?gòu)牡诙拥墓?jié)點(diǎn) v 3 v_3 v3? v 4 v_4 v4? 出發(fā),走一步能到達(dá)終點(diǎn) t t t。將終點(diǎn) t t t 當(dāng)作第三層節(jié)點(diǎn)。
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
Level Graph中只允許從上一層節(jié)點(diǎn)到下一層節(jié)點(diǎn)邊的存在,不允許其他邊(同層之間或從下層到上層)的存在。

一個(gè)更復(fù)雜的例子,大家可以先自行畫(huà)出Level Graph,看看是否與左邊的結(jié)果一致:
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)


下面正式以一個(gè)簡(jiǎn)單的例子來(lái)講解Dinic’s算法。

初始化:
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

第一輪循環(huán): 把Residual Graph作為輸入,構(gòu)建其Level Graph。
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
然后在左邊構(gòu)造好的Level Graph中尋找阻塞流(blocking flow)。 (注意:阻塞流未必是最大流),下圖中用紅色標(biāo)識(shí)阻塞流。

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

讓阻塞流通過(guò)Residual Graph,那么就要相應(yīng)更新Residual Graph的值。

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
然后增加反向流。刪除此輪構(gòu)造的Level Graph。
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

第二輪循環(huán): Residual Graph沿用第一輪更新后的樣子。構(gòu)造其Level Graph。

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
找到該Level Graph中的阻塞流,并更新Residual Graph。

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

然后增加反向流(注意有相同方向的邊需要合并權(quán)重值)。刪除此輪構(gòu)造的Level Graph。

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

第三輪循環(huán): Residual Graph沿用第二輪更新后的樣子。構(gòu)造其Level Graph。注意這里與之前不同的是,該輪中從起點(diǎn)走一步只能到達(dá)一個(gè)節(jié)點(diǎn),并且后續(xù)無(wú)法到達(dá)其他節(jié)點(diǎn),所以將其他節(jié)點(diǎn)設(shè)為∞。
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
此時(shí),我們就要終止程序,并將最后得到的Residual Graph中反向邊刪去。

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
仍然用 F l o w = C a p a c i t y ? R e s i d u a l Flow=Capacity-Residual Flow=Capacity?Residual 計(jì)算流量,最終算出最大流為19。

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

時(shí)間復(fù)雜度:
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

3.5 最小割問(wèn)題(Min-Cut)
3.5.1 S-T Cut

將頂點(diǎn)集合 V V V 切割為兩個(gè)集合 S S S T T T 之后, S ∪ T = V S∪T=V ST=V S ∩ T = ? S∩T=? ST=?,其中起點(diǎn) s ∈ S s∈S sS,終點(diǎn) t ∈ T t∈T tT。那么 ( S , T ) (S,T) (S,T)稱為 S-T Cut。
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
S-T Cut 容量(Capacity) 的定義為離開(kāi)集合 S S S 的邊的權(quán)重之和。上圖中 C a p a c i t y ( S , T ) = 6 Capacity(S,T)=6 Capacity(S,T)=6。S-T Cut 并不唯一,下圖中容量為3。
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

Min-cut簡(jiǎn)單來(lái)說(shuō),就是所有S-T Cut中容量最小的。意味著我們想要割斷少數(shù)的細(xì)的管道就能阻斷水流(花的代價(jià)?。?。

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

最小割可能并不唯一。

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

3.5.2 ★最大流-最小割定理(Max-Flow Min-Cut Theorem)

網(wǎng)絡(luò)的最大流等于最小割容量。
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)

3.5.3 尋找最小割的方法

只要找到最小割就可以找到最大流。

1、首先用任意的最大流算法得到最終的Residual graph,并忽略其中的反向邊。
2、在Residual graph中,將從起點(diǎn) s s s 一步能到達(dá)的節(jié)點(diǎn)歸入集合 S S S。將無(wú)法到達(dá)的節(jié)點(diǎn)歸入集合 T T T。這樣,我們就得到了最小割 ( S , T ) (S,T) (S,T)

舉一個(gè)簡(jiǎn)單的例子,首先用最大流算法得到Residual graph。
圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
然后從Residual graph中得到最小割。

圖論算法,數(shù)學(xué)建模十大算法,算法,圖論,數(shù)據(jù)結(jié)構(gòu)
上述內(nèi)容來(lái)自B站:13-5: 最小割 Min-Cut

四、二分圖

挖坑------------------------------未完待續(xù)-----------------------------------文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-784008.html

到了這里,關(guān)于數(shù)學(xué)建模十大算法04—圖論算法(最短路徑、最小生成樹(shù)、最大流問(wèn)題、二分圖)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 數(shù)學(xué)建模十大經(jīng)典算法和常用算法

    1、蒙特卡羅算法: 該算法又稱隨機(jī)性模擬算法,是通過(guò)計(jì)算機(jī)仿真來(lái)解決問(wèn)題的算法,同時(shí)通過(guò)模擬可以來(lái)檢驗(yàn)自己模型的正確性。 2、數(shù)據(jù)擬合、參數(shù)估計(jì)、插值等數(shù)據(jù)處理算法: 比賽中通常會(huì)遇到大量的數(shù)據(jù)需要處理,而處理數(shù)據(jù)的關(guān)鍵就在于算法,通常使用Matlab作為

    2024年02月07日
    瀏覽(20)
  • 數(shù)學(xué)建模的三大模型和十大常用算法

    預(yù)測(cè)模型 神經(jīng)網(wǎng)絡(luò)預(yù)測(cè)、灰色預(yù)測(cè)、擬合插值預(yù)測(cè)(線性回歸)、時(shí)間序列預(yù)測(cè)、馬爾科夫鏈預(yù)測(cè)、微分方程預(yù)測(cè)、Logistic模型等等。 應(yīng)用領(lǐng)域:人口預(yù)測(cè)、水資源污染增長(zhǎng)預(yù)測(cè)、病毒蔓延預(yù)測(cè)、競(jìng)賽獲勝概率預(yù)測(cè)、月收入預(yù)測(cè)、銷量預(yù)測(cè)、經(jīng)濟(jì)發(fā)展情況預(yù)測(cè)等在工業(yè)、農(nóng)業(yè)、

    2024年02月04日
    瀏覽(32)
  • 數(shù)學(xué)建模十大算法03—線性規(guī)劃、整數(shù)規(guī)劃、非線性規(guī)劃、多目標(biāo)規(guī)劃

    數(shù)學(xué)建模十大算法03—線性規(guī)劃、整數(shù)規(guī)劃、非線性規(guī)劃、多目標(biāo)規(guī)劃

    一、線性規(guī)劃(Linear Programming,LP) 1.1 引例 在人們的生產(chǎn)實(shí)踐中,經(jīng)常會(huì)遇到 如何利用現(xiàn)有資源來(lái)安排生產(chǎn),以取得最大經(jīng)濟(jì)效益的問(wèn)題。 此類問(wèn)題構(gòu)成了運(yùn)籌學(xué)的一個(gè)重要分支一數(shù)學(xué)規(guī)劃,而 線性規(guī)劃(Linear Programming, LP) 則是數(shù)學(xué)規(guī)劃的一個(gè)重要分支。 簡(jiǎn)而言之,線

    2024年02月13日
    瀏覽(27)
  • 【數(shù)學(xué)建模筆記】【第四講(1)】擬合算法之最小二乘算法及其MATLAB實(shí)現(xiàn)

    【數(shù)學(xué)建模筆記】【第四講(1)】擬合算法之最小二乘算法及其MATLAB實(shí)現(xiàn)

    與插值問(wèn)題不同,在擬合問(wèn)題中不需要曲線一定經(jīng)過(guò)給定的點(diǎn)。擬合問(wèn)題的目標(biāo)是尋求一個(gè)函數(shù)(曲線),使得該曲線在某種準(zhǔn)則下與所 有的數(shù)據(jù)點(diǎn)最為接近,即曲線擬合的最好(最小化損失函數(shù)) 【插值和擬合的區(qū)別】 插值算法中,得到的多項(xiàng)式f(x)要經(jīng)過(guò)所有樣本點(diǎn)。但

    2024年02月09日
    瀏覽(24)
  • 集貨運(yùn)輸優(yōu)化:數(shù)學(xué)建模步驟,Python實(shí)現(xiàn)蟻群算法(解決最短路徑問(wèn)題), 蟻群算法解決旅行商問(wèn)題(最優(yōu)路徑問(wèn)題),節(jié)約里程算法

    目錄 數(shù)學(xué)建模步驟 Python實(shí)現(xiàn)蟻群算法(解決最短路徑問(wèn)題) ?蟻群算法解決旅行商問(wèn)題(最優(yōu)路徑問(wèn)題)

    2024年02月09日
    瀏覽(93)
  • Lingo軟件入門(mén)【數(shù)學(xué)建模】,面試Python開(kāi)發(fā)十大問(wèn)題

    Lingo軟件入門(mén)【數(shù)學(xué)建?!?,面試Python開(kāi)發(fā)十大問(wèn)題

    II.III 變量賦值區(qū)域 賦值模塊顧名思義是涉及到給變量賦值,但這里的變量特指是集合變量,因?yàn)槠渌膯蝹€(gè)的決策變量,可以直接在定義時(shí)賦值,只有集合變量涉及到定義和賦值分開(kāi)。 該模塊以data:開(kāi)頭,以enddata結(jié)尾,因此所有對(duì)集合的賦值操作都要在這個(gè)區(qū)域內(nèi)完成。

    2024年04月26日
    瀏覽(29)
  • 【數(shù)學(xué)建模】圖論模型

    【數(shù)學(xué)建?!繄D論模型

    無(wú)向圖和有向圖 簡(jiǎn)單圖和完全圖:重邊、環(huán)、孤立點(diǎn) 賦權(quán)圖/網(wǎng)絡(luò) 頂點(diǎn)的度 子圖與生成子圖 路與回路、跡、path、圈 連通圖與非連通圖 圖的表示 考慮簡(jiǎn)單圖 關(guān)聯(lián)矩陣表示 鄰接矩陣表示 對(duì)于賦權(quán)圖而言,鄰接矩陣中的數(shù)值改為對(duì)應(yīng)邊的權(quán)值就得到對(duì)應(yīng)的無(wú)向/有向賦權(quán)圖

    2024年01月17日
    瀏覽(19)
  • 數(shù)學(xué)建?!獔D論學(xué)習(xí)

    數(shù)學(xué)建?!獔D論學(xué)習(xí)

    一、圖論基礎(chǔ) 圖分為有限圖與無(wú)限圖兩類,本課只涉及有限圖,即頂點(diǎn)和邊都是有限集合 (2)有向圖:每一條邊都是有向的 無(wú)向圖:每一條邊都是無(wú)向的 除外都是混合圖 ?注意:有向圖邊的描述{1.每一條邊都需要描述到? ?2.始點(diǎn),終點(diǎn) (3)鄰接點(diǎn):兩個(gè)結(jié)點(diǎn)之間有一條邊

    2024年02月04日
    瀏覽(20)
  • 【數(shù)學(xué)建模常用模型】圖論專題

    ? ? ? ? 圖論是研究點(diǎn)、線間關(guān)系的一門(mén)學(xué)科?,F(xiàn)實(shí)生活中,凡是涉及到事物間的關(guān)系,都可以抽象為圖論模型。圖論模型也是各大數(shù)學(xué)建模中常見(jiàn)的一種模型,主要用于計(jì)算、規(guī)劃最短距離、路線等問(wèn)題。下面介紹幾個(gè)基本概念和算法。 ? 單源最短路 ? ? ? ? 單源最短路

    2024年02月06日
    瀏覽(25)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包