-
迪克斯特拉(Dijkstras)算法,適用於加權圖(weighted graph),找出的是總權重最小的路徑。
-
Dijsktra算法包含四個步驟:
- 找出當前離起點最近的節點;
- 對於該節點的鄰居,檢查是否有前往它們的更短路徑,如果有,就更新其開銷,並更新鄰居的父節點;
- 重複這個過程,直到對所有節點都這樣做了;
- 計算最終路徑(路線和開銷)。
code
#!/bin/python
# -*- coding:utf-8 -*-
def dijkstra(graph, startIndex, path, cost, max):
"""
求解各節點最短路徑,獲取path,和cost數組,
path[i] 表示vi節點的前繼節點索引,一直追溯到起點。
cost[i] 表示vi節點的花費
"""
lenth = len(graph)
v = [0] * lenth
# 初始化 path,cost,V, 獲得start節點同相鄰節點的 權重情況
for i in range(lenth):
if i == startIndex:
v[startIndex] = 1
else:
cost[i] = graph[startIndex][i] # 獲得了第一行的鏈接權重
path[i] = (startIndex if (cost[i] < max) else -1)
print v, cost, path
for i in range(1, lenth):
minCost = max
curNode = -1
# for 獲取最小權值的節點
for w in range(lenth):
if v[w] == 0 and cost[w] < minCost:
minCost = cost[w]
curNode = w
print("curNode: ", curNode)
# 不可通行的節點,跳出循環
if curNode == -1: break
v[curNode] = 1
print "v: ",v
# 更新其他節點的權值(距離)和路徑
for w in range(lenth):
# v[w] == 0 當前節點尚未遍歷,
# cost 總是維護了一個 從start 到其他點的最小距離,所以 Q(a=>c) 可與 Q(a=>b) + Q(b=>c) 比較
if v[w] == 0 and (graph[curNode][w] + cost[curNode] < cost[w]):
print "======> 更新 w: ", w , " graph[curNode][w]:", graph[curNode][w], \
" cost[curNode]:", cost[curNode], " || cost[w]:" , cost[w]
cost[w] = graph[curNode][w] + cost[curNode] # 更新權值
path[w] = curNode # 更新路徑
return path, cost
def show_graph(graph):
for idx in graph:
print idx
if __name__ == '__main__':
max = 2147483647
graph = [
[max, max, 10, max, 30, 100],
[max, max, 5, max, max, max],
[max, max, max, 50, max, max],
[max, max, max, max, max, 10],
[max, max, max, 20, max, 60],
[max, max, max, max, max, max],
]
show_graph(graph)
path = [0] * 6
cost = [0] * 6
path, cost = dijkstra(graph, 0, path, cost, max)
print "path :", path
print "cost :", cost
總結:
1. cost 總是維護了一個 從start 到其他點的最小距離,
參考:
https://blog.csdn.net/weixin_40512497/article/details/82773192
https://blog.csdn.net/yucicheung/article/details/79674334