十年網(wǎng)站開發(fā)經(jīng)驗 + 多家企業(yè)客戶 + 靠譜的建站團隊
量身定制 + 運營維護(hù)+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
算法介紹

迪科斯徹算法使用了廣度優(yōu)先搜索解決賦權(quán)有向圖或者無向圖的單源最短路徑問題,算法最終得到一個最短路徑樹。該算法常用于路由算法或者作為其他圖算法的一個子模塊。
當(dāng)然目前也有人將它用來處理物流方面,以獲取代價最小的運送方案。
算法思路
Dijkstra算法采用的是一種貪心的策略。
1.首先,聲明一個數(shù)組dis來保存源點到各個頂點的最短距離和一個保存已經(jīng)找到了最短路徑的頂點的集合T。
2.其次,原點 s 的路徑權(quán)重被賦為 0 (dis[s] = 0)。若對于頂點 s 存在能直接到達(dá)的邊(s,m),則把dis[m]設(shè)為w(s, m),同時把所有其他(s不能直接到達(dá)的)頂點的路徑長度設(shè)為無窮大。初始時,集合T只有頂點s。
3.從dis數(shù)組選擇最小值,則該值就是源點s到該值對應(yīng)的頂點的最短路徑,并且把該點加入到T中,此時完成一個頂點。
4.再次,看看新加入的頂點是否可以到達(dá)其他頂點并且看看通過該頂點到達(dá)其他點的路徑長度是否比源點直接到達(dá)短,如果是,那么就替換這些頂點在dis中的值。
5.最后,從dis中找出最小值,重復(fù)上述動作,直到T中包含了圖的所有頂點(可以到達(dá)的)。
算法圖形演示
現(xiàn)在有圖如下:
每個線的權(quán)重以及標(biāo)識如圖所示。
第一步:
建立dis數(shù)組和T數(shù)組。
首先從起點A 開始,將A可以直接到達(dá)的頂點的權(quán)重記錄在dis數(shù)組中,無法直達(dá)的記錄無窮大(當(dāng)前使用FFFF表示無窮大)。
將當(dāng)前選擇的頂點加入數(shù)組T:
第二步:
從dis數(shù)組中選擇一個不在T數(shù)組中的頂點的最小權(quán)重值的頂點,當(dāng)前選擇為B頂點,并將B可以直接到達(dá)的頂點的相關(guān)權(quán)重和當(dāng)前dis中的權(quán)重值比較,如果當(dāng)前dis權(quán)重值大,則替換:
將B加入數(shù)組T:
第三步:
依次選擇頂點C:
將C加入數(shù)組T:
第四步:
依次選擇頂點D:
將D加入數(shù)組T:
第五步:
依次選擇頂點E:
將E加入數(shù)組T:
第六步:
依次選擇頂點F:
將F加入數(shù)組T:
因為所有的頂點都已經(jīng)在T數(shù)組中了,算法結(jié)束。
這樣就求得了從A點到各個頂點的最優(yōu)解。
可以看到A頂點無法直達(dá)F頂點。
代碼表示:
(代碼中使用999代表FFF)
#encoding:utf-8 import copy """ 圖的表示方式 鄰接矩陣 999代表無限遠(yuǎn) """ tuG=[[0, 10, 20, 999, 999, 999], [999, 0, 999, 20, 70, 999], [999, 999, 0, 50, 30, 999], [999, 999, 999, 0, 999, 999], [999, 999, 999, 10, 0, 999], [999, 999, 999, 20, 20, 0]]; tuX = 6; # 設(shè)置原點到其他定點的各個距離 dis = copy.deepcopy(tuG[0]); def Dijkstra(G,v0): """ 使用 Dijkstra 算法計算指定點 v0 到圖 G 中任意點的最短路徑的距離 INF 為設(shè)定的無限遠(yuǎn)距離值 """ t = []; minv = v0; while len(t) <= tuX: t.append(minv); #以當(dāng)前點的中心向外擴散 for w in range(0, tuX): if dis[minv] + G[minv][w] < dis[w]: dis[w] = dis[minv] + G[minv][w] tmp = 1000; for i in range(0, tuX): tmpFlag = False; for j in range(0, len(t)): if i == t[j]: tmpFlag = True; break; if tmpFlag == True: continue; if tmp > dis[i]: tmp = dis[i]; minv = i; if __name__ == '__main__': Dijkstra(tuG,0); print dis;