什么是狄克斯特拉算法
狄克斯特拉算法用于解决有图的最短路径寻找,类似于深度优先算法,每次只走最短距离,走过的不在走,继续寻找最短距离,并不断更新到节点的开销-即是权重,保证开销最小才更新,最后所有节点全部查找完毕即可。
例如下图:
初始开销:A:6,B:2,终点:∞
算法执行过程如下
起点--B--终点 终点开销更新为 7
起点--B--A A点开销更新为5
起点--B--A--终点 终点开销更新为 6
起点--A A处理过,不在处理
最后开销:A:5,B:2,终点:6
代码实现:
'''--------------加权散列表逻辑体现-----------'''
graph = {}
graph['start'] = {}
graph['start']['A'] = 6
graph['start']['B'] = 2
#print(graph['start'].keys())
graph['A'] = {}
graph['A']['FIN'] = 1
graph['B'] = {}
graph['B']['FIN'] = 5
graph['B']['A'] = 3
graph['FIN'] = {} #没有任何邻居
'''--------------开销表逻辑体现-----------'''
infinity = float('inf')
costs = {}
costs['A'] = 6
costs['B'] = 2
costs['FIN'] = infinity
'''--------------父节点散列表逻辑体现-----------'''
parent = {}
parent['A'] = 'start'
parent['B'] = 'start'
parent['FIN'] = 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 is not None: #这个while循环再所有节点都被处理后结束
cost = costs[node]
neighbors = graph[node]
for n in neighbors.keys(): #遍历当前节点的所有邻居节点
new_cost = cost + neighbors[n]
if costs[n] > new_cost: #如果当前节点前往该邻居更近
costs[n] = new_cost #就更新该邻居的开销
parent[n] = node
processed.append(node)
node = find_lowest_cost_node(costs)
print(costs)
print(parent)
终点最短开销:6
路径:start--B--A--FIN
小结
- 广度优先搜索用于在非加权图中查找最短路径。
- 狄克斯特拉算法用于在加权图中查找最短路径。
- 仅当权重为正时狄克斯特拉算法才管用。
- 如果图中包含负权边,请使用贝尔曼福德算法。