1. 程式人生 > >最短路徑(Dijkstra算法)

最短路徑(Dijkstra算法)

結構 virtual red 不同 truct 成本 頂點 pre status

當用圖結構來表示通信、交通等網絡,權重代表距離或者成本,尋找最短路徑就成為了一個重要的任務。

給定帶權網絡G=(V;E),源點s,對於其他所有頂點v,尋找s到v的最短路徑,連接成一顆最短路徑樹。可以證明,最短路徑的任一前綴也是最短路徑

這一性質,可以理解為,對於一顆最短路徑樹,按到起點的距離排序,刪除後面k個頂點以及關聯邊後,殘存的子樹T‘依然是最短路徑樹。因此,只需要找到一個新的距離源點s最近的頂點,即可擴充子樹,最終成為全圖的最短路徑樹。

考慮優先級搜索的框架,當前頂點尚未發現的鄰接頂點,其優先級可以定義為其父親的優先級加上聯邊的權重,即priority(u)=priority(parent(u))+weight(v,u)。與Prim算法類似,每次只需要將優先級最高的頂點以及聯邊加入子樹,最終即可得到最短路徑樹。

 1 template<typename Tv, typename Te> struct Dijkstra
 2 {
 3     virtual void operator()(Graph<Tv, Te>* g, int uk, int v)
 4     {
 5         if (g->status(v) == UNDISCOVERED)//對於uk每個尚未被發現的鄰接頂點v
 6             if (g->priority(v) > g->priority(uk) + g->weight(uk, v))//u到Vk的距離看做u的優先級
7 { 8 g->priority(v) = g->priority(uk) + g->weight(uk, v);//更新優先級數 9 g->parent(v) = uk;//更新父節點 10 } 11 }//每次都是尋找離開始節點s最近的節點,僅當新節點才更新,每個已發現節點的priority都是到s的最短距離 12 };

與Prim算法不同之處在於,Prim算法僅考慮子樹到鄰接頂點的聯邊權重;Dijkstra算法需要考慮的是到源點s的最短路徑,基於前綴仍然是最短路徑這一前提,只需要簡化為,distance(s,u)=distance(s,v)+distance(v,u)。對應優先級,將邊的權重作為優先級,即可實現。最後,沿著樹邊即可得到一顆最短路徑樹。

最短路徑(Dijkstra算法)