數學建模之圖論——圖與網絡模型(一)(基本概念和最短路問題,附MATLAB源碼)

圖與網絡的基本概念與數據結構

一.圖與網絡的基本概念

圖論中圖是由點和邊構成的,可以反映一些對象之間的關係。
在這裏插入圖片描述

無向圖

無向圖(簡稱圖):沒有方向,由點和邊構成的圖,記做G =(V , E),點是V,邊是E。
:圖論的圖與幾何圖、工程圖不一樣。
因爲一般情況下的圖中點的相對位置及點間連線長短,對於反映對象之間的關係並不是重要的。

聯結vi1v_i{_1}vikv_{ik} 的鏈:在無向圖G中,若存在一個點邊的交錯序列(vi1,ei1,vi2,ei2,...vik1,eik1,cikv_{i1},e_{i1},v_{i2},e_{i2},...v_{i_{k-1}},e_{i_{k-1}},c_{ik})其中vikv_{ik}屬於V(G),eije_{ij}屬於E(G)

聯結 v_{i1} 和 v_{ik} 的圈:在上述的鏈中,若 v_{i1} = v_{ik},也就是首尾相連。

連通圖:對於一個無向圖,若任何兩個不同的點之間,至少存在一條鏈。

簡單圖:一個圖如果它既沒有環也沒有平行邊(兩條邊連接同一對頂點),稱爲簡單圖(simple graph)。
在這裏插入圖片描述
完全圖:其中每對不同的頂點之間都恰連有一條邊相連
在這裏插入圖片描述
賦權圖:對無向圖的每一條邊(vi,vjv_i,v_j) ,都有一個數(稱爲權重) wijw_{ij}對應。

二分圖又稱作二部圖,是圖論中的一種特殊模型。 設G=(V,E)是一個無向圖,如果頂點V可分割爲兩個互不相交的子集(A,B),並且圖中的每條邊(i,j)所關聯的兩個頂點i和j分別屬於這兩個不同的頂點集(i in A,j in B),則稱圖G爲一個二分圖
在這裏插入圖片描述
頂點的度:與頂點v關聯的邊的個數稱爲頂點v 的
度(degree) (環計兩度),記作 d(v) .
度爲零的點稱爲弧立點,度爲1的點稱爲懸掛點。懸掛點的關聯邊稱爲懸掛邊。度爲奇數的點稱爲奇點(odd point) ,度爲偶數的點稱爲偶點(even point) 。

有向圖

有向圖:由點和弧構成的圖,記做D =(V , A),其中V是圖D的點集,A是圖D的弧集。
:無向圖是一種特殊的有向圖,無向圖的邊實際上就是等 價於兩條方向相反的弧。
聯結vi1v_i{_1}vikv_{ik} 的路:在無向圖G中,若存在一個點邊的交錯序列(vi1,ei1,vi2,ei2,...vik1,eik1,cikv_{i1},e_{i1},v_{i2},e_{i2},...v_{i_{k-1}},e_{i_{k-1}},c_{ik})其中vikv_{ik}屬於V(D),eije_{ij}屬於V(D)
*聯結 v_{i1} 和 v_{ik} 的迴路:在上述的鏈中,若 v_{i1} = v_{ik},也就是首尾相連。
賦權圖:對無向圖的每一條弧(vi,vjv_i,v_j) ,都有一個數(稱爲權重) cijc_{ij}對應。
網絡:在賦權的有向圖D中指定一點爲發點(記爲 vsv_s ),指定另一點爲收點(記爲vtv_t),其餘的點爲中間點,並把 D 中的每一條弧的賦權數cijc_ij 稱爲弧 (vi,vj)(v_i,v_j) 的容量 ,這樣的賦權有向圖 D 就稱爲網絡。

二.圖與網絡的數據結構

描述圖與網絡的3種常用表示方法:鄰接矩陣表示法、關聯矩陣表示法、弧表表示法

鄰接矩陣表示法

鄰接矩陣表示法是將圖以鄰接矩陣(adjacency matrix)的形式存儲在計算機中。圖 G=(V,A) 的鄰接矩陣是如下定義的:C是一個nnn*n的0-1矩陣,即
在這裏插入圖片描述在這裏插入圖片描述
也就是說,如果兩節點之間有一條弧,則鄰接矩陣中對應的元素爲1;否則爲0。

例一:對於下圖,可以用鄰接矩陣表示爲
在這裏插入圖片描述
解釋:現在有五個圖,鄰接矩陣a就是555*5的方陣,∵ 1→2,∴a[1][2]=1;
∵1→3所以a[1][3]=1;∵ 4→3,∴a[4][3]=1,其他都是一樣的,所有的都寫出來就是:在這裏插入圖片描述
同樣,對於網絡中的權,也可以用類似鄰接矩陣的矩陣表示。只是此時一條弧所對應的元素不再是1,而是相應的權而已。如果網絡中每條 弧賦有多種權,則可以用多個矩陣表示這些權。

關聯矩陣表示法

關聯矩陣表示法是將圖以關聯矩陣(incidence matrix)的形式存儲在計算機中.
B=(bik)nm(1,0,1)nmB=(b_{ik})_{n*m}\in({-1 ,0 ,1}) ^{n*m} 的關聯矩陣B是如下定義的:B是一個n*m的矩陣,即
在這裏插入圖片描述

如果一個頂點是一條弧的起點,則關聯矩陣中對應的元素爲1;如果一個頂點是一條弧的終點,則關聯矩陣中對應的元素爲-1;如果一個頂點與一條弧不關聯,則關聯矩陣中對應的元素爲0。

例2 對於例1所示的圖,如果關聯矩陣中每列對應弧的順序爲 (1,2),(1,3),(2,4),(3,2),(4,3),(4,5),(5,3)和(5,4),則關聯矩陣表示爲(列單位爲弧)在這裏插入圖片描述
這個圖有4個節點,7條連線,所以是474*7的矩陣,每一列都是隻有一個1,一個 -1。
看e1這條線,頭是v1尾是v2,所以v1=1,v2=-1
e3,頭是v3,尾是v4,所以v3是1,v4是-1;
在這裏插入圖片描述)

弧表表示法

弧表表示法將圖以弧表(arc list)的形式存儲在計算機中。所謂圖的弧表,也就是圖的弧集合中的所有有序對。
假設例1中的弧(1,2),(1,3),(2,4),(3,2),(4,3),(4,5),(5,3)和(5,4)上的權分別爲8,9,6,4,0,3,6和7,則弧表表示如下:
在這裏插入圖片描述

最短路問題 (Shortest Path Problem)

最短路問題:對一個賦權有向圖中指定的兩個點vsv_svtv_t找到條從vsv_svtv_t的路,使得這條路上所有弧的權數總和最小,這條路被稱爲從vsv_svtv_t, 的最短路,這條路_上所有弧的權數的總和被稱爲從vsv_svtv_t 的距離。
在這裏插入圖片描述

Dijkstra算法

如上圖,帶權值的最短路徑長度就是黃線標出來的 爲7
求解最短路的迪克斯特拉Dijkstra算法(雙標號法)
雙標號即:對圖中的點 vjv_j 賦予兩個標號 (lj,kj)(l_j,k_j) ,其中 l_j 表示從起點vsv_svjv_j 的最短路的長度,kjk_j 表示在 vsv_svjv_j 的最短路上前面一個鄰點的下標,從而找到所求的最短路及其距離。

Dijkstra{\mathbb{\color{Red}下面給出Dijkstra算法的基本步驟:}}

  1. 先給起點 vsv_s 標號:(0,s),表示從 vsv_svsv_s 的距離爲0, vsv_s 爲起點。
  2. 找出已標號的點集 I ,未標號的點集 J 以及從 I 到 J 的弧集。
  3. 若上述弧集是空集,則計算結束。此時,如果 vtv_t 已標號 (l_t,k_t) 則 vsv_svtv_t 的距離爲 ltl_t ,而從 vsv_svtv_t 的最短路,可以從 ktk_t 反向追蹤到起點 vsv_s而得到。 如果 vtv_t 未標號,則不存在從 vsv_svtv_t 的有向路。 若上述弧集不是空集,則轉下一步。
  4. 對上述弧集中的每一條弧,計算sij=li+cijs_{ij}=l_i+c_{ij} 在所有的sijs_{ij}中,找值最小的弧,不妨設爲(vc,va)(v_c,v_a)則給此弧的終點 vav_a 標號(scd,c)(s_cd,c) ,返回步驟2.

在這裏插入圖片描述 在這裏插入圖片描述在這裏插入圖片描述

在這裏插入圖片描述1. 先給起點    標號:(0,1),表示從    到     的距離爲0, 爲起點。

標號(m,n)m是權重,n是前一個節點

在這裏插入圖片描述
同時,我們可以從各點的標號得到起點到該點的最短路徑及距離。
在這裏插入圖片描述 在這裏插入圖片描述
在這裏插入圖片描述 在這裏插入圖片描述
在這裏插入圖片描述
用行向量pb表示P標號信息,index1表示標號頂點順序, index2表示標號頂點索引,d表示最短路的值.

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';
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標號的頂點
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)); %可能有多個點同時達到最小值,只取其中的一個
   pb(temp)=1;
   index1=[index1,temp];
   temp2=find(d(index1)==d(temp)-a(temp,index1));
   index2(temp)=index1(temp2(1));
end
d, index1, index2

程序過程就不具體分析了,只看看輸出吧。
d代表距離,在這個題裏代表票價,代表c1分別到c1,c2,c3,c4,c5,c6的距離
index1代表標號順序
index2代表該標號的前一個標號

d =
    0    35    45    35    25    10
index1 =
     1     6     5     2     4     3
index2 =
     1     6     5     6     1     1

第一個標號的是自身c1,不用管,從第二個開始c1→c6,可以看到c6的前一個節點是1,所以c1直接到了c6.距離d=10;
第三個是c5,也是c1直接到的,距離d=25;
第四個c2,可以看到c2的前一個節點是c6,c6的前一個節點是c1,所以c1到c2的最短距離爲c1先到c6再從c6到c2,距離爲40
其他的以此類推
在這裏插入圖片描述

Floyd算法

主要用來計算每對頂點之間的最短路徑。
Dijkstra算法用來計算一對頂點之間的最短路徑。

Floyd算法的基本思想是:遞推產生一個矩陣序列 A0,A1...Ak...AnA_0,A_1...A_k...A_n ,其中 Ak(i,j)A_k(i,j) 表示從頂點viv_i到頂點 vjv_j 的路徑上所經過的頂點序號不大於k的最
短路徑度。迭代公式爲:
在這裏插入圖片描述
k是迭代次數,i,j,k=123...ni,j,k=1 ,2,3,...n最後,當k=n時, 即是各頂點之間的最短通路值。
這個算法要產生兩個矩陣
這個算法就是找一箇中間點,通過判斷兩個頂點的直接距離與通過中間點的簡介距離的遠近比較(近的爲優) 來不斷對兩個矩陣進行更新。

在這裏插入圖片描述
在這裏插入圖片描述
A代表每兩個點之間的距離,path是每兩個點之間的最短路徑經過的中間點,一開始沒有中間點,所以設置爲-1,代表沒有中間點。
在這裏插入圖片描述在這裏插入圖片描述
這個是找一箇中間點,一般是從0開始,再找1 2 3,這樣過一遍。
在這裏插入圖片描述
我們直接用1開始吧,因爲我算了,0沒有更新。
算自身和自身都是0沒啥意思,兩兩連接就是這12對頂點。
{0, 1}, {0, 2}, {0, 3}, {1, 0}, {1, 2}, {1, 3),
{2, 0}, {2, 1}, {2, 3}, {3, 0}, {3, 1}, {3, 2}

  • {0,1}:因爲要經過1,所以可以看成是A[0][1]=A[0][1]+A[1][1]A[0][1]=A[0][1]+A[1][1],左右相等,不更新
  • {0,2}:A[0][2]>A[0][1]+A[1][2]>5+4A[0][2]>A[0][1]+A[1][2] \rightarrow \infin >5+4所以更新,Path矩陣的A[0][2]更新爲1(因爲中間點是1)A矩陣中的A[0][2]更新爲9
  • 這是經過中間點爲1跟新後的兩個新矩陣
    在這裏插入圖片描述
  • {0,3}:A[0][3]>A[0][1]+A[1][3]7=5+2A[0][3]>A[0][1]+A[1][3] \rightarrow 7 =5+2不更新
  • {1,2}{1,3}{1,0}都經過1,不更新,剩下的自己算吧,當然我算了,沒有更新。

再以頂點2爲中間點進行檢測

  • {0,1}:A[0][1]<A[0][2]+A[2][1]5<9+3A[0][1]<A[0][2]+A[2][1] \rightarrow 5<9+3不更新
  • {0,2}{2,0} {2,1}{2,3}有2不用算
  • {0,3}:A[0][3]<A[0][2]+A[2][3]7<9+2A[0][3]<A[0][2]+A[2][3] \rightarrow 7<9+2不更新
  • {1,0}:A[1][0]=A[1][2]+A[2][0]>4+3A[1][0]=A[1][2]+A[2][0] \rightarrow \infin >4+3 更新
  • {3,0}A[3][0]>A[3][2]+A[2][0]4=1+2A[3][0]>A[3][2]+A[2][0] \rightarrow 4 =1+2不更新
  • 兩個矩陣都分別跟新爲如下兩個
    在這裏插入圖片描述
  • 後面也都是一樣,上次更新後直接以上次更新的那個矩陣爲基礎進行計算。這是以2爲中間點進行更新的結果
  • 在這裏插入圖片描述
  • 這是3爲中間點進行更新的結果
    在這裏插入圖片描述
    弗洛伊德算法就是利用矩陣的不斷更新進行運算
    當然FLoyd算法也有MATLAB程序
    以Dijkstra算法那個例題爲例,進行計算
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; %把所有零元素替換成無窮
a([1:n+1:n^2])=0; %對角線元素替換成零,Matlab中數據是逐列存儲的
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

a =

     0    35    45    35    25    10
    35     0    15    20    30    25
    45    15     0    10    20    35
    35    20    10     0    10    25
    25    30    20    10     0    35
    10    25    35    25    35     0


path =

     0     6     5     5     0     0
     6     0     0     0     4     0
     5     0     0     0     0     4
     5     0     0     0     0     0
     0     4     0     0     0     1
     0     0     4     0     1     0

可以看到輸出a是一個對稱矩陣,代表兩個點之間的距離,path代表路徑,如[1,2]的數值是6,也就是經過了6這個中間點。

是不是隻有距離這種題才能用這個模型呢?
在這裏插入圖片描述

設備更新問題。某公司使用一臺設備,在每年年初,公司就要決定是購買新的設備還是繼續使用舊設備。如果購置新設備,就要支付一定的購置費,當然新設備的維修費用就低。如果繼續使用舊設備,這樣可以省去了購置費,但維修費用就高了。現在需要我們制定一個五年之內的更新設備的計劃,使得五年內購置費和維修費總的支付費用最小。

這種設備每年年初的價格如下表
在這裏插入圖片描述
另外,還已知使用不同時間(年)的設備所需要的維修費如下圖
在這裏插入圖片描述
用點vi 表示第 i 年年初購進一臺新設備,i=1, 2, 3, 4, 5, 6.
用弧 (vi,vj) 表示在第 i 年年初購進的設備一直使用到第 j 年年初,其中i<j
化爲最短路問題後,相應的圖示如下:
在這裏插入圖片描述
相應地,把費用轉化爲圖中弧的權數。

對於弧 (vi,vj) ,其權數爲從第 i 年年初購進設備使用到第 j-1 年年底所花費的購置費及維修費的總和。如下:
在這裏插入圖片描述
下面把計算得到的權數賦到圖上,得到賦權圖,則求解五年
內購置費和維修費總費用最小的問題就轉化爲從賦權圖中求解一
條從 v1 到v6 的最短路問題。
在這裏插入圖片描述
最短路徑:
v1v3v6v1→v3→v6 即:第1年初購置的新設備使用到第3年初 (第2年底) ,第3年初再購置新設備使用到第6年初 (第5年底) 。
v1v4v6v1→v4→v6 即:第1年初購置的新設備使用到第4年初 (第3年底) ,第4年初再購置新設備使用到第6年初 (第5年底)
兩個路徑耗費的金錢是一樣的
用MATLAB

clear;clc;
n=6; a=zeros(n);
a(1,2)=16;a(1,3)=22;a(1,4)=30;a(1,5)=41;a(1,6)=59;
a(2,3)=16;a(2,4)=22;a(2,5)=22;a(2,6)=41; 
a(3,4)=17;a(3,5)=23;a(3,6)=31;
a(4,5)=17;a(4,6)=23;
a(5,6)=18;
a=a+a'; 
a(a==0)=inf; %把所有零元素替換成無窮
a([1:n+1:n^2])=0; %對角線元素替換成零,Matlab中數據是逐列存儲的
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

下一篇數學建模之圖論——圖與網絡模型(二)(最小生成樹問題、最大流問題) https://blog.csdn.net/weixin_45755332/article/details/106946149

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