1. 程式人生 > >圖演算法 單源最短路徑問題 無權最短路徑

圖演算法 單源最短路徑問題 無權最短路徑

單源最短路徑問題

給定一個賦權圖 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的頂點都被處理之後才處理。

//無權最短路徑問題的虛擬碼
		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 );
					}
			}
		}
下圖演示演算法執行(該圖還包括是否known的變化,程式碼中是不需要的)

以v3為開始頂點