圖演算法 單源最短路徑問題 無權最短路徑
阿新 • • 發佈:2019-02-18
單源最短路徑問題
給定一個賦權圖 G = (V, E)和一個特定頂點s作為輸入,找到s到G中每一個其他頂點的最短賦權路徑。
無權最短路徑(解法可被用來做廣度優先遍歷)
一個無權圖G。使用某個頂點s作為輸入引數,要找出從s到所有其他頂點的最短路徑。
這裡給出一個O( | E | + | V | )的解法。O( | V | ^2)的解法不做討論。
對於每個頂點,跟蹤三條資訊,頂點是否被處理(未處理為F,處理過為T,初始為F),s到此頂點的路徑長dv(s初始為0,其他為INFINITY),此頂點之前頂點。
在任意時刻,只存在兩種型別的dv不是INFINITY的Unknown頂點,一些頂點的dv=currDist,另一些dv=currDist+1。 一種抽象是保留兩個盒子,1號盒子裝有dv = currDist的那些未知頂點,而2號盒子裝有dv = currDist +1的那些頂點。找出一個合適頂點的測試可以用查詢1號盒內的任意頂點v代替。在更新v的臨界頂點w後,將w放入2號盒中。
可以使用一個佇列進一步簡化上述模型。迭代開始時,佇列只含有距離為currDist的頂點。當新增距離為currDist+1的那些鄰接頂點時,由於它們自隊尾入隊,因此保證它們直到所有距離為currDist的頂點都被處理之後才處理。
下圖演示演算法執行(該圖還包括是否known的變化,程式碼中是不需要的)//無權最短路徑問題的虛擬碼 void unweighted( Vertex s ){ //一個佇列 Queue<Vertex> q = new Queue<Vertex>( ); //每個頂點初始距離為INFINITY for each Vertex v v.dist = INFINITY; //s初始距離為0 s.dist = 0; q.enqueue( s ); while( !q.isEmpty( ) ){ Vertex v = q.dequeue( ); //遍歷v的鄰接頂點 for each Vertex w adjacent to v //如果dist是INFINITY說明沒有處理過 if( w.dist == INFINITY ){ w.dist = v.dist + 1; w.path = v; q.enqueue( w ); } } }
以v3為開始頂點