dijkstra邻接表_掌握算法-图论-最短路径算法-Dijkstra算法
如果圖是賦權圖,那么問題就變得更困難了不過我們仍然可以使用來自無權情形時的想法。
我們保留所有與前面相同的信息。因此,每個頂點或者標記為Known的,或者標記為Unknown的。像之前一樣,對每一個頂點保留一個臨時距離dv。這個距離實際上是使用已知頂點作為中間頂點從s到v的最短路徑的長。以前一樣,我們記錄pv,它是引起dv變化的最后的頂點。
解決單源最短路徑問題的一般方法叫做Dijkstra算法。這個有30年歷史的解法是貪婪算法(greddy algorithm)最好的例子。
Dijkstra像無權最短路徑一樣,按階段進行。在每個階段,Dijkstra算法選擇一個頂點v,它在所有未知頂點中具有最小的dv,同時算法聲明從s到v的最短路徑是已知的。階段的其余部分由dw的值更新完成。
在無權的情況下,若dw = x則置dw = dv+1,因此,若頂點v能提供一條更短路徑,則我們本質上降低了dw的值。如果我們對賦權的情形應用同樣的邏輯,那么當dw的新值dv+Cv,w是一個改進的值時,我們就置dw = dv + Cv,w。
簡單來說,使用通向w路徑上的定點v是不是一個好主意由算法決定。
有向圖G
剛開始假設節點s是v1。第一個選擇的定點是v1,路徑的長為0。
該頂點標記為已知。既然v1已知,那么表項就需要調整。鄰接到v1的頂點是v2和v4。這兩個頂點的項得到調整。
下一步選取v4并標記為已知。頂點v3,v5,v6,v7是鄰接的頂點,而它們實際上都需要調整。
接著選擇v2。v4鄰接的點,但已經是已知的,因此對它沒有工作要做。v5是鄰接的點,但不做調整,因為經過v2的值是2+10=12,而長為3的路徑已經是已知的了。
下一個選取的頂點是v5,其值為3。v7是唯一的鄰接頂點,但是它不用做調整,因此3+6>5。
然后選取v3,對v6的距離下調為3+5=8。
在選取下一個頂點v7。v6下調到5+1=6。
最后我們選擇v6。
下面給出Dijkstra算法的為代碼。這里我們假設,這些頂點從0到NumVertex-1標號,并通過ReadGraph我們的圖可以被讀入到一個鄰接表中。
/*Dijkstra算法的聲明*/typedef int Vertex;struct TableEntry{ List Header; /*adjacency list*/ int Known; DistType Dist; Vertex Path;}/*Vertices are numbered from 0*/#define NotAVertex -1typedef struct TableEntry Table[NumVertex];/*表初始化*/void InitTable(Vertex start, Graph G, Table T){ int i; ReadGraph(G, T); for(i = 0; i < NumVertex; ++i){ T[i].Known = False; T[i].Dist = Infinity; T[i].Path = NotAVertex; } T[start].Dist = 0;}/*顯示實際最短路徑的例程*/void PrintPath(Vertex V, Table T){ if(T[V].Path != NotAVertex){ PrintPath(T[V].PATH, T); printf(" to"); } printf("%v", V); /*%v is pseudocode*/}/*Dijkstra算法的偽代碼*/void Dijkstra(Table T){ Vertex V, W; for(;;){ V = smallest unknown distance vertex; if(V == NotAVertex) break; T[V].Known = True; for each W adjancent to V if(!T[W].known){ if(T[V].Dist + Cvw < T[W].Dist){ /*update W*/ Decreae(T[W].Dist to T[V].Dist + Cvw); T[W].Path = V; } } }}總結
以上是生活随笔為你收集整理的dijkstra邻接表_掌握算法-图论-最短路径算法-Dijkstra算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php编写六十甲子纳音表_六十甲子纳音表
- 下一篇: 为什么线程池里的方法会执行两次_新手一看