【Python_038】算法 | 狄克斯特拉算法(Dijkstra)

上篇博客介绍了广度优先搜索。本篇博客介绍狄克斯特拉算法,可以算是BFS进阶版(加上了权重的考量)
书籍参考:《算法图解》

狄克斯特拉算法
  • 找出加权图中前往X的最短路径
  • 狄克斯特拉算法只适用于无负权重的有向无环图(无向图意味着两个节点彼此指向对方,其实就是环)
  • 有负权重的参考贝尔曼-福德算法(Bellman-Ford algorithm)

算法思路:

  1. 找出“最便宜”的节点,即可在最短时间内到达的节点。
  2. 对于该节点的邻居,检查是否有前往它们的更短路径,如果有,就更新其开销(找出图中最便宜的节点,并确保没有到该节点的更便宜的路径)
  3. 重复这个过程,直到对图中的每个节点都这样做了
  4. 计算最终路径。
实例

【Python_038】算法 | 狄克斯特拉算法(Dijkstra)_第1张图片
*上图源自《算法图解》

问题:从起点走到终点,求最短路径

代码实现

##创建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')

你可能感兴趣的:(Python,算法,python)