1. 程式人生 > >圖論經典演算法(通俗易懂):最短路徑和最小生成樹

圖論經典演算法(通俗易懂):最短路徑和最小生成樹

一、最短路問題

求圖的最短路問題,幾乎是圖論的必學內容,而且在演算法分析與設計中也會涉及。很多書上內容,
實在沒法看,我們的圖論教材,更是編的非常糟糕,吐槽,為啥要用自己學校編的破教材,不過據說
下一屆終於要換書了。

言歸正傳,開始說明最短路問題。

1.問題描述:

對一幅圖G,我們對每一條邊賦權w(e),成為一個賦權圖。H是G的一個子圖,則W(H) = sigma(w(e)),
也就是對每條邊的權求和。尋找從一個點a到另一個b的一個子圖,使得權和最小,即為最短路問題。

2.演算法描述:

Dijkstra(迪傑斯特拉演算法演算法):

image.png
我表示看到後,是懵逼的,接下來詳細分析下。

演算法圖解:

其實就是不斷求一個點集合中的每個點,和與他相鄰點最短路的最小值。我們還是從例項出發,更
容易講解。我會把上述步驟,拆解為多步。
我們求下面這個圖從A到L的最短路。
image.png

  • 第一步:
    令a1 = A(便於標記),t(a1) = 0(表示點a1到a的最短路),S={a1}(被選擇的點的集合),T = 0
    (空集 表示被選擇的最短路的邊集)。
    image.png
  • 第二步:
    求與S中的點a1與他相鄰的點的距離d,取點a2 = C使得距離最小。令S={a1,a2},T={AC}。
    image.png
  • 第三步:
    重複第二步,求S中的點a1,a2的相鄰點中(去除已選擇點),距離最小的那個,則為AB,CE。
    再取AB,CE中權和最小的一個,B,所以a3=B,令S={a1,a2,a3},T={AC,AB}。
  • ……
    持續下去,不斷尋找,S集合中的每個點與他相鄰點的最小距離,然後再這些最小距離中找到最小的
    那個加入到S中,同時加入相應的邊。
    image.png
    image.png
    直到到達終點L為止。最後得到的最短路為:
    image.png
此演算法是多項式時間可求解的,

關於演算法的實現可以在參考資料中找到。

二、最小生成樹

問題描述

同樣在一個連通賦權圖中,尋找一顆生成樹使得權和最小。
此演算法比較簡單,很容易理解。

演算法描述:

Kruskal演算法:
image.png
不斷尋找最小權的邊即可。

比如,尋找下圖的最小生成樹。
image.png
結果如下
image.png

參考資料