最短路徑(Dijkstra算法)


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

給定帶權網絡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)。對應優先級,將邊的權重作為優先級,即可實現。最后,沿着樹邊即可得到一顆最短路徑樹。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM