狄克斯特拉算法
- 加权图——提高/降低某些边的权重
- 加权图:“边”上有了权重(例如:时间)
- 狄克斯特拉算法:找到总权重最小的路径
计算非加权图的最短路径——广度优先算法
计算加权图的最小权重——狄克斯特拉算法
**注意:**当图中存在负权重时,无法使用狄克斯特拉算法
实现算法
节点
"""狄克斯特拉算法"""
# ------------整个图的散列表(字典)--------
graph = {}
# 起点
graph["start"] = {} # 起点是一个散列表(字典)
graph["start"]["A"] = 6 # 存储权重,start-A
graph["start"]["B"] = 2 # 存储权重,start-B
print(graph["start"].keys())
# 其他节点
graph["A"] = {} # A节点也是一个字典
graph["A"]["destination"] = 1 # A-终点
graph["B"] = {}
graph["B"]["A"] = 3 # B-A
graph["B"]["destination"] = 5 # B - 终点
# 终点
graph["destination"] = {} # 终点没有任何邻居
print(graph["B"])
利用字典的键——实现节点
利用字典的键值——实现权重
实时计算消耗的权重
# ---------实时计算消耗权重的散列表(字典)------------
infinity = float("inf") # python中表示无穷大,因为此刻的开销还不知搭配
costs = {}
costs["A"] = 6
costs["B"] = 2
# costs["destination"] = infinity # 表示路径还没选择,此时到达终点所消耗权重未知
存储父节点
# -----------存储父节点的散列表----------------
parents = {}
parents["A"] = "start"
parents["B"] = "start"
parents["destination"] = None
记录遍历过的节点
# ----------记录存储过的节点-----------------
processed = []
找到最小权重的节点
# -------------找到开销最低的节点-------------
def find_lowest_cost_node(costs):
lowest_cost = float("inf")
lowest_cost_node = None
for node in costs: # 遍历所有节点
cost = costs[node] # 对应为键值
if cost < lowest_cost and node not in processed:
lowest_cost = cost
lowest_cost_node = node
return lowest_cost_node
狄克斯特拉算法
"""狄克斯特拉算法"""
node = find_lowest_cost_node(costs) # 在未处理的节点中找到权重开销最小的节点
while node:
cost = costs[node]
neighbors = graph[node]
for i in neighbors.keys(): # 遍历当前节点的所有邻居
new_cost = cost + neighbors[i] # neighbors[i]相当于neighbors.value键值,即对应的权重值
if costs[i] > new_cost: # 原先直接前往i节点的开销和现在路劲进行比较
costs[i] = new_cost
parents[i] = node
processed.append(node)
node = find_lowest_cost_node(costs)
print(costs["destination"])
6