一、單源點最短路徑問題 :
問題描述:給定帶權有向圖G=(V, E)和源點v∈V,求從v到G中其余各頂點的最短路徑。
迪傑斯特拉(Dijkstra)提出了一個按路徑長度遞增的次序產生最短路徑的算法。
Dijkstra算法:
基本思想:設置一個集合S存放已經找到最短路徑的頂點,S的初始狀態只包含源點v,對vi∈V-S,假設從源點v到vi的有向邊為最短路徑。以后每求得一條最短路徑v, …, vk,就將vk加入集合S中,並將路徑v, …, vk , vi與原來的假設相比較,取路徑長度較小者為最短路徑。重復上述過程,直到集合V中全部頂點加入到集合S中。
下一條最短路徑(設其終點為vi)或者是弧(v0,vi),或者是中間經過S中的頂點而最后到達頂點vi的路徑。
示例:
算法步驟:
① 令S={Vs} ,用帶權的鄰接矩陣表示有向圖,對圖中每個頂點Vi按以下原則置初值:
② 選擇一個頂點Vj ,使得:dist[j]=Min{ dist[k]| Vk∈V-S },Vj就是求得的下一條最短路徑終點,將Vj 並入到S中,即S=S∪{Vj} 。
③ 對V-S中的每個頂點Vk ,修改dist[k],方法是:
若dist[j]+Wjk<dist[k],則修改為:dist[k]=dist[j]+Wjk ("Vk∈V-S )
④ 重復②,③,直到S=V為止。
算法實現:
二、每一對頂點之間的最短路徑
問題描述:給定帶權有向圖G=(V, E),對任意頂點vi,vj∈V(i≠j),求頂點vi到頂點vj的最短路徑。
解決辦法1:每次以一個頂點為源點,調用Dijkstra算法n次。顯然,時間復雜度為O(n3)。
解決辦法2:弗洛伊德提出的求每一對頂點之間的最短路徑算法——Floyd算法,其時間復雜度也是O(n3),但形式上要簡單些。
Floyd算法:
基本思想:對於從vi到vj的弧,進行n次試探:首先考慮路徑vi,v0,vj是否存在,如果存在,則比較vi,vj和vi,v0,vj的路徑長度,取較短者為從vi到vj的中間頂點的序號不大於0的最短路徑。在路徑上再增加一個頂點v1,依此類推,在經過n次比較后,最后求得的必是從頂點vi到頂點vj的最短路徑。
示例:
數據結構:
圖的存儲結構:帶權的鄰接矩陣存儲結構
數組dist[n][n]:存放在迭代過程中求得的最短路徑長度。迭代公式:
數組path[n][n]:存放從vi到vj的最短路徑,初始為path[i][j]="vivj"。
算法實現:
|
|