上篇博客介绍了广度优先搜索。本篇博客介绍狄克斯特拉算法,可以算是BFS进阶版(加上了权重的考量)
书籍参考:《算法图解》
狄克斯特拉算法
- 找出加权图中前往X的最短路径
- 狄克斯特拉算法只适用于无负权重的有向无环图(无向图意味着两个节点彼此指向对方,其实就是环)
- 有负权重的参考贝尔曼-福德算法(Bellman-Ford algorithm)
算法思路:
- 找出“最便宜”的节点,即可在最短时间内到达的节点。
- 对于该节点的邻居,检查是否有前往它们的更短路径,如果有,就更新其开销(找出图中最便宜的节点,并确保没有到该节点的更便宜的路径)
- 重复这个过程,直到对图中的每个节点都这样做了
- 计算最终路径。
实例
*上图源自《算法图解》
问题:从起点走到终点,求最短路径
代码实现
##创建graph表
graph = {}
graph['start']={}
graph['start']['a'] = 6
graph['start']['b'] = 2
graph['a'] = {}
graph['a']['fin'] = 1
graph['b'] = {}
graph['b']['a'] = 3
graph['b']['fin'] = 5
graph['fin'] = {}
## 存储每个节点开销
infinity = float('inf')
costs = {}
costs['a'] = 6
costs['b'] = 2
costs['fin'] = infinity
## 创建父节点
parents = {}
parents['a'] = 'start'
parents['b'] = 'start'
parents['fin'] = None
proceeded = []
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 proceeded:
lowest_cost = cost
lowest_cost_node = node
return lowest_cost_node
node = find_lowest_cost_node(costs)
while node is not None:
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
parents[n] = node
proceeded.append(node)
node = find_lowest_cost_node(costs)
print(f'{node} is done')
print(f'{costs["fin"]} is mininum')