淺析Dijkstra單源最短路徑算法

 

單源最短路徑問題

給定 加權有向圖G=(V,E,W),每條邊的權值w爲 非負數,表示兩個頂點間的距離。
源點s∈V。
求:從s出發到其餘各個頂點的最短路徑。
 算法


如上圖所示,以1爲源點,計算到其他各個頂點的最短距離(我已用紅線標出)。下面列出了最終解:

源點:1
1->6->2 : short[2] = 5
1->6->2->3 : short[3] = 12
1->6->4 : short[4] = 9
1->6->5 : short[5] = 4
1->6v : short[6] = 3ide

Dijkstra算法相關概念

S集合:當從s到x(x ∈V )的最短路徑找到時,則x ∈S。當全部頂點都進入S集合時,算法結束。

初始:S={s},當S=V時算法結束。

從s到u相對於S的最短路徑:指從s到u且僅通過S中頂點的最短路徑。

dist[u]:從s到u相對於S的最短路徑長度

short[u]:從s到u最短路徑的長度(算法最終解)

dist[u] ≥ short[u]

Dijkstra算法採用貪心算法模式,算法過程就是經過計算dist[u],不斷擴充S集合,同時dist[u]會不斷優化改善,直到dist[u] = short[u],並將其放到S中,當全部頂點都放入S集合時,算法結束。優化

算法設計思想

輸入:加權有向圖G=(V,E,W)
          V={1,2,…,n}, s=1

輸出:從s到每一個頂點的最短路徑設計

  1. 初始S={1}
  2. 對於u ∈V-S,計算1到u的相對於S的最短路,長度爲dist[u]
  3. 選擇V-S中dist值最小的那個頂點,加入S。
  4. 繼續上述過程,直到S=V爲止。

實例

輸入:G=(V,E,W),源點1

          V={1,2,3,4,5,6}
 blog


初始S集合只有1,計算直接從1能到達的頂點的距離,其餘不能從1號頂點直接到達的頂點都記爲無窮大。此時從dist[u]裏找出最短距離的頂點(6號),並將其放進S集合。

  S={1}
  dist[1] = 0
  dist[2] = 10
  dist[6 ] = 3
  dist[3] = ∞
  dist[4] = ∞
  dist[5] = ∞it


當把6號頂點放進S集合後,經由6號頂點出發到達的頂點的最短距離可能會被優化更新,由於該算法的思想很「貪心」,誰更短我要誰!好比1->6->2要比1->2距離更短,因此dist[2]被更新爲5,從專業術語上講,這個「更新」過程叫作鬆弛,其餘點同理。而後從dist[u]裏找出最短的路徑的那個頂點(5號),並放進S集合裏。

  S={1,6}
  dist[1] = 0
  dist[6] = 3
  dist[2] = 5
  dist[4] = 9
  dist[5] = 4
  dist[3] = ∞class


後面的操做步驟其實就是重複上面的操做。即當S集合裏有個新的頂點後,就可能會更新其餘點的最短距離,更新一遍後,找出當前最短距離的dist[u],並將該頂點放進S集合。後面不重複闡述。

  S={1,6,5}
  dist[1] = 0
  dist[6] = 3
  dist[5] = 4
  dist[2] = 5
  dist[4] = 9
  dist[3] = ∞im


  S={1,6,5,2}
  dist[1] = 0
  dist[6] = 3
  dist[5] = 4
  dist[2] = 5
  dist[4] = 9
  dist[3] = 12db


  S={1,6,5,2,4}
  dist[1] = 0
  dist[6] = 3
  dist[5] = 4
  dist[2] = 5
  dist[4] = 9
  dist[3] = 12img

  S={1,6,5,2,4,3}  dist[1] = 0  dist[6] = 3  dist[5] = 4  dist[2] = 5  dist[4] = 9  dist[3] = 12當有向圖中的全部頂點都進入了S集合後,算法結束,此時的dist[u]的值其實就是最初咱們找出的那個最終解short[u],因此,算法結束時,dist[u]=short[u],獲得最終解。

相關文章
相關標籤/搜索