K條最短路徑算法(KSP, k-shortest pathes):Yen's Algorithm


參考:

K條最短路徑算法:Yen's Algorithm

算法背景

K 最短路徑問題是最短路徑問題的擴展和變形。1959 年,霍夫曼(Hoffman) 和帕夫雷(Pavley)在論文中第一次提出k 最短路徑問題。 k 最短路徑問題通常包括兩類:有限制的k 最短路問題和無限制的K 最短路問題。 前者要求最短路徑集合不含有回路,而后者對所求得的最短路徑集合無限制。

算法簡介

Yen's算法是Yen 在1971 年提出的以其名字命名 的Yen 算法。Yen's算法采用了遞推法中的偏離路徑算法思想,適用於非負權邊的有向無環圖結構。

算法思想

算法可分為兩部分,算出第1條最短路徑P(1),然后在此基礎上依次依次算出其他的K-1條最短路徑。在求P(i+1) 時,將P(i)上除了終止節點外的所有節點都視為偏離節點,並計算每個偏離節點到終止節點的最短路徑,再與之前的P(i)上起始節點到偏離節點的路徑拼接,構成候選路徑,進而求得最短偏離路徑。

算法實例:

根據個人的理解,我歸納出了以下步驟:

調用K條最短路徑算法,源C,目的H,K為3。B為偏離路徑集合。

1.通過Dijkstra算法計算得到最短路徑A^1C-E-F-H,其中,花費為5,A[1] = C-E-F-H

2.將A[1]作為迭代路徑,進行第一次迭代:

(1)以部分迭代路徑(即A[1])C路徑中,C點為起點,將C-E路徑之間的權值設為無窮大,進行一次Dijkstra,得到路徑A^2-1C-D-F-H,花費為8,將A^2-1路徑加入B;

(2)以部分迭代路徑(即A[1])C-E路徑中,E為起點,將E-F路徑之間的權值設為無窮大,進行一次Dijkstra,得到路徑A^2-2C-E-G-H,花費為7,將A^2-2路徑加入B;

(3)以部分迭代路徑(即A[1])C-E-F路徑中,F為起點,將F-H路徑之間的權值設為無窮大,進行一次Dijkstra,得到路徑A^2-3C-E-F-G-H,花費為8,將A^2-3路徑加入B;

迭代完成,B集合中有三條路徑:C-D-F-HC-E-G-HC-E-F-G-H;選出花費最小的偏離路徑C-E-G-HA[2] = C-E-G-H,移出B集合。

3.將A[2]作為迭代路徑,進行第二次迭代:

(1)以部分迭代路徑(即A[2])C路徑中,C點為起點,將C-E路徑之間的權值設為無窮大,進行一次Dijkstra,得到路徑A^3-1C-D-F-H但B集合已存在該路徑,故不存在偏移路徑;

(2)以部分迭代路徑(即A[2])C-E路徑中,E點為起點,將E-GE-F路徑之間的權值設為無窮大 (注意,這里設置兩條路徑的權值原因是這兩條路徑分別存在於A[1]和A[2]中),進行一次Dijkstra,得到路徑A^3-2C-E-D-F-H,花費為8,將A^3-2加入B;

(3)以部分迭代路徑(即A[2])C-E-G路徑中,G點為起點,將C-H路徑之間的權值設為無窮大,不存在偏移路徑。

迭代完成,B集合中有三條路徑:C-D-F-HC-E-F-G-HC-E-D-F-H;由於三條路徑花費均為8,則根據最小節點數進行判斷,選出偏離路徑C-D-F-HA[3] = C-D-F-H

此時,選出了三條最短路徑,分別是:

A[1] = C-E-F-H

A[2] = C-E-G-H

A[3] = C-D-F-H

算法結束。以上過程均為個人理解,如果出現了偏差,請大家指出,謝謝!

算法實現

可以參考Github中的一個使用python實現KSP算法的repo:Yen's K-Shortest Path Algorithm

2017.8


免責聲明!

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



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