數學建模之圖論——圖與網絡模型(二)(最小生成樹問題、最大流問題)

建議先看上一篇基本概念篇 https://blog.csdn.net/weixin_45755332/article/details/106899147

最小生成樹

基本概念和方法

樹:沒有圈的連通圖
圖一是,圖二有圈,圖三滅有連通
在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述
生成子圖:對於無向圖 G =(V,E) ,保留G的所有點,而刪掉G的邊或者保留部分 G 的邊,所獲得的圖稱爲 G 的生成子圖。
如左圖去了那兩條邊,剩下的那個圖就是生成子圖
在這裏插入圖片描述在這裏插入圖片描述
生成樹:若圖 G 的一個生成子圖是一個樹,則稱這個生成子圖爲生成樹。上面右圖就是一個最小生成樹

最小生成樹問題:在一個賦權的連通的無向圖 G 中找出一個生成樹,並使得這個生成樹的所有邊的權數之和爲最小。

最小生成樹的常用方法:

  1. 破圈法:任取一圈,去掉圈中最長邊,直到無圈。
  • 把這些圈的權值最大的去掉,剩下的那個生成樹就是最小生成樹
  • 注:當一個圈中有多個相同的最長邊時,不能同時都去掉,只能去掉其中任意一 條邊。最小生成樹有可能不唯一,但最小生成樹的長度相同

在這裏插入圖片描述
在這裏插入圖片描述
2. 加邊法(避圈法):2.加邊法(避圈法) :取圖G的n個孤立點{v1,v2,…, vn}作爲一個支撐圖,從最短邊開始往支撐圖中添加,見圈迴避,直到連通(有n-1條邊)

  • 開始是六個頂點,然後根據那張賦權圖,按權值從小到大的順序來進行連接
    在這裏插入圖片描述

在這裏插入圖片描述
連接完第四條線時,v1→v2和v3→v6權值都是5,但v1→v2連接的話就是圈了,所以只能是v3→v6

在這裏插入圖片描述

  1. prim算法構造最小生成樹:
    設置兩個集合P和Q,其中P用於存放的最小生成樹G中的頂點,集合Q存放的最小生成樹G中的邊。令集合P的初值爲 P=v1P={v_1} (假設構造最小生成樹時從頂點v1v_1 出發),集合Q的初值爲Q=θQ=\theta
    prim算法的思想是,從所有 pP,vVPp\in P,v \in V-P ,的邊中,選取具有最小權值的邊 pv ,將頂點v加入集合P中,將邊pv加入集合Q中,如此不斷重複,直到 P=V 時,最小生成樹構造完畢,這時集合Q中包含了最小生成樹的所有邊。

下面用代碼來解下面最小生成樹
用result 3*n 的第一、二、三行分別表示生成樹邊的起點、終點、權集合。
在這裏插入圖片描述

clc;clear;
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(a==0)=inf;
result=[];p=1;tb=2:length(a);
while size(result,2)~=length(a)-1
   temp=a(p,tb);temp=temp(:);
   d=min(temp);
   [jb,kb]=find(a(p,tb)==d,1); %找第1個最小值
   j=p(jb);k=tb(kb);
  result=[result,[j;k;d]];p=[p,k];tb(find(tb==k))=[];
end
result




result =

     1     2     5     4     4     7
     2     5     4     6     7     3
    50    40    50    30    42    45


下面用避圈算法的MATLAB程序計算上題,結果一樣

clc;clear;
a(1,[2,3])=[50,60]; a(2,[4,5])=[65,40]; %這裏給出鄰接矩陣的另外一種輸入方式
a(3,[4,7])=[52,45]; a(4,[5,6])=[50,30];
a(4,7)=42; a(5,6)=70; 
[i,j,b]=find(a);
data=[i';j';b'];index=data(1:2,:);
loop=length(a)-1;
result=[];
while length(result)<loop
   temp=min(data(3,:));
   flag=find(data(3,:)==temp);
   flag=flag(1);
   v1=index(1,flag);v2=index(2,flag);
   if v1~=v2
      result=[result,data(:,flag)];
   end
   index(find(index==v2))=v1;
   data(:,flag)=[];
   index(:,flag)=[];
end
result

result =

     4     2     4     3     1     4
     6     5     7     7     2     5
    30    40    42    45    50    50

某大學準備對其所屬的7各學院辦公室計算機聯網,這個網絡的可能聯通的途徑如圖11- -14所示,圖中V1,——,V7表示7個學院辦公室,圖中的邊爲可能聯網的途徑,邊上所賦的權數爲這條路線的長度,單位爲百米。請設計一個網絡能聯通7個學院辦公室,並使總的線路長度爲最短。
在這裏插入圖片描述
:這是一個最小生成樹問題,不是最短路問題,因爲他所有的都要連接上。

clc;clear;
a=zeros(7);
a(1,7)=3; a(1,6)=10;
a(2,7)=3; a(2,3)=1;
a(3,4)=7; a(3,5)=2;a(3,7)=4;
a(4,5)=8; 
a(5,6)=4; a(5,7)=5;
a(6,7)=3;
a=a+a';a(a==0)=inf;
result=[];p=1;tb=2:length(a);
while size(result,2)~=length(a)-1
   temp=a(p,tb);temp=temp(:);
   d=min(temp);
   [jb,kb]=find(a(p,tb)==d,1); %找第1個最小值
   j=p(jb);k=tb(kb);
  result=[result,[j;k;d]];p=[p,k];tb(find(tb==k))=[ ];
end
result


result =

     1     7     2     3     7     3
     7     2     3     5     6     4
     3     3     1     2     3     7

最大流問題

基本概念

最大流問題(maximum flow problem),一種組合最優化問題,就是要討論如何充分利用裝置的能力,使得運輸的流量最大,以取得最好的效果。
如圖所示的網絡圖中定義了一個發點v1,定義了一個收點v7,其餘點v2,v3,…,v6爲中間點,稱爲轉運點。如果有多個發點和收點,則虛設發點和收點轉化成一個發點和收點。圖中的權是該弧在單位時間內的最大通過能力,稱爲弧的容量(capacity)。最大流問題是在單位時間內安排一個運送方案,將發點的物質沿着弧的方向運送到收點,使總運輸量最大。
在這裏插入圖片描述
cijc_{ij}爲弧(i,j)的容量,fijf_{ij}爲弧(i,j)的流量。
容量是弧(i,j)單位時間內的最大通過能力,流量是弧(i,j)單位時間內的實際通過量,流量的集合f=fijf={f_{ij}}稱爲網絡的流。發點到收點的總流量記爲v=val(f),v也是網絡的流量。
注意:流量只是發出點的發出量或流入點的流入量,中間點的流入量和流出量是一樣的。
概念區分
:從發點到收點的一條路線(弧的方向不一定都同向)稱爲鏈。從發點到收點的方向規定爲鏈的方向。
前向弧:與鏈的方向相同的弧稱爲前向弧。
後向弧:與鏈的方向相反的弧稱爲後向弧。
增廣鏈: 設 f 是一個可行流,如果存在一條從vs到vt的鏈,滿足:
1.所有前向弧上fij<Cijf_{ij}<C_{ij}
2.所有後向弧上fij>0
在這裏插入圖片描述

Ford-Fulkerson標號算法

  • 第一步: 找出第一個可行流,例如所有弧的流量fij =0;

  • 第二步:對點進行標號找一條增廣鏈。

    • (1)發點標號(∞)
    • (2)選一個點viv_i 已標號並且另一端未標號的弧沿着某條鏈向收點檢查:
      • A.如果弧的方向向前(前向弧)並且有cij<fijc_{ij} < f_{ij},則vj標號:θjcijfijθ_j=c_{ij}-f_{ij}(容量-流量)
      • B.如果弧的方向指向vi(後向弧)並且有fjif_{ji}>0,則vj標號: θjfjiθ_j=f_{ji}
        當收點已得到標號時,說明已找到增廣鏈,依據vi 的標號反向跟蹤得到一條增廣鏈。當收點不能得到標號時,說明不存在增廣鏈,計算結束。
  • 第三步:調整流量

    • (1)求增廣鏈上點vi 的標號的最小值,得到調整量 θ=minjθj\theta=\min_j{\theta_j}
      在這裏插入圖片描述
    • (2)調整流量
      在這裏插入圖片描述
      得到新的可行流f1,去掉所有標號,返回到第二步從發點重新標號尋找增廣鏈,直到收點不能標號爲止.

定理1 可行流f是最大流的充分必要條件是不存在發點到收點的增廣鏈 .

求圖中的發點v1到收點v7的最大流.
在這裏插入圖片描述
先假設已經給定了這個可行流,可以檢查一下,發點和接收點的流量是相同的,都是16;每個點的流入量和流出量也是相同的。

在這裏插入圖片描述
然後進行第一輪標號

  • 先看{121→2}正向弧,8-6=2,圈2上就標號爲2;
  • 242→4}{262→6}都是正向弧,但流量已經到達最大流了,所以不能增加了
  • 252→5}反向弧,所以圈3直接標3-0=3
  • 343→4}正向弧,圈4標3,當然也可以{3→6→4}這樣多一條路徑但結果一樣就不用這個了
  • {4→7}正向弧,圈7標號10-3=7

增廣鏈μ={(1,2),(3,2),(3,4),(4,7) },μ+={(1,2),(3,4),(4,7)},μ-={(3,2)},調整量爲增廣鏈上點標號的最小值 θ=min{∞,2,3,3,7}=2,對其進行調整

在這裏插入圖片描述
這裏有反向弧,調整後是正向弧+2,反向弧-2
在這裏插入圖片描述
第二輪
與第一輪是一樣的,要說的就是{3→2}雖然沒有到最大容量,但圈2往後不能增加了,所以直接不用看
在這裏插入圖片描述
增廣鏈μ=μ+={(1,3),(3,4),(4,7) },調整量爲 θ=min{∞,4,1,5}=1
這裏沒有反向弧,經過的弧流量都加1
在這裏插入圖片描述
第三輪
在這裏插入圖片描述
增廣鏈μ=μ+={(1,3),(3,6),(6,4),(4,7) },調整量爲 θ=min{∞,3,1,2,4}=1
全是正向弧,都加1
在這裏插入圖片描述
經過排查只有這些增廣鏈了,所以可以下結論了
最大流量vf12+f138+12=20=f67+f47+f57=6+2+7+7\color{Blue}v=f12+f13=8+12=20=\color{Red}f67+f47+f57=6+2+7+7
上面是有向圖,無向圖就更簡單了,直接全是加就完了。

截集-截量法

將圖G=(V,E)的點集分割成兩部分V1,V1V_1,\overline{V_1}並且vsV1v_s\in{V_1}以及vtV1v_t\in\overline{V_1},則箭尾在V_1箭頭在 V1\overline{V_1} 的弧集V1,V1V_1,\overline{V_1}稱爲一個截集,截集中所有弧的容量之和稱爲截集的截量。

下圖所示的截集爲V1,V1V_1,\overline{V_1}={(1,2),(3,4),(3,5)},截量C=6+2+2=10;

爲什麼沒有{2,3}呢?是因爲弧內的① ③ 要指向弧外的 ② ④ ⑤ ⑥ ,{2,3}是弧外的指向弧內的了。
在這裏插入圖片描述
又如下圖所示的截集爲V1,V1V_1,\overline{V_1}= {(2,4),(3,(5,4)(5,0)}
截量C(V1,V1)C(V_1,\overline{V_1})=4+2+6+9=21

在這裏插入圖片描述
下圖所示的截集爲V1,V1V_1,\overline{V_1}= {(2,4),(2,5),(3,4),(3,5)}
截量C=4+1+2+2=9
在這裏插入圖片描述
所有截量中此截量最小且等於最大流量,此截集稱爲最小截集。經過計算這個圖最小截量就是9,所以最大流量就是9;
2\color{Red}定理2 最大流量等於最小截集的截量。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章