圖之最短路徑
阿新 • • 發佈:2019-02-11
目前求最短路徑的演算法很多,下面2種是基本不再使用,但卻是經典的路徑演算法。其他路徑演算法有啟發式演算法A*,D*,還有樹形的RRT, RRT*等。
1. Dijkstra演算法
a. 基本思想:求帶權有向圖中某個源點到其他各頂點的最短路徑,Dijkstra演算法十分適用。有向圖有N={V, arcs[i][j]}, 而生成單源最短路徑為Nt={Vt,dist[i]}。path[]表示從源點到頂點i之間的最短路徑前趨點(就是追溯點)。
b. 實現過程:
虛擬碼
void Dijkstra(Graph G,point v){
//帶權有向圖,源點v
Vt=v;
dist[i]初始值為arcs[0][i]。 i=1,2,3,..... ,n-1。
while(Vt!=V){
選Vj,滿足<Vi, Vj>邊最小。dist[j] = MIN(dist[i]);
Vt=Vt U Vj;
dist[j] = cost;
}
}
示意圖
c. 效能分析:使用鄰接矩陣表示時,時間複雜度O(|V|^2)。若使用帶權的鄰接表表示,dist修改會相應邊少,但時間複雜度仍然是O(|V|^2)。
2. Floyd演算法(基於矩陣最短路徑求解)
a. 基本思想:對於一個所有權值都大於0的帶權有向圖,對每一對頂點Vi!=Vj,要求求出Vi與Vj之間的最短路徑和最短路徑長度。遞推產生一個n階方陣序列A(-1), A(0), A(1), ….., A(n-1)。其中A(k)[i][j]表示從頂點Vi到頂點Vj的路經長度,k表示第k個頂點的運算步驟。
b. 實現過程:
描述:初始時對於任意2個頂點vi和vj,若有邊則以此邊上的權值作為最短路徑長度,否則使用∞作為最短路徑長度。再向其中逐步在原路徑中引入頂點k(k=0,1,2,…..,n-1)作為中間頂點。如果引入中間頂點後,得到的路徑比原來的路徑長度減少了,則以此新路徑代替原路徑。
其中使用迭代方式,沒迭代一次,在從Vi到Vj的最短路徑上就多考慮一個頂點,經過n次迭代之後所得到的A(n-1)[i][j]就儲存了vi到vj的最短路徑長度。
示意圖
c. 效能分析:時間複雜度為O(|V|^3)。注:允許圖中有帶負權值的邊,但不允許由包含帶負權值的迴路。