狄克斯特拉算法-最短路径

  • 以下图为例, 计算加权图中从起点到终点的最短路径
  1. 先建立三个字典分别存储每个节点(node)的邻居(neighbor)、节点之间的距离(distance)以及父节点(parent).
# 存储每个节点的neighbor和前往neighbor的distance
graph = {} 
graph["start"] = {}
graph["start"]['A'] = 6
graph["start"]['B'] = 2
graph["A"] = {}
graph["A"]["final"] = 1
graph["B"] = {}
graph["B"]["A"] = 3
graph["B"]["final"] = 5
graph["final"] = {}    # 终点无neighbor

# 存储节点的distance, 即从起点出发前往该节点的distance
costs= {}
costs["A"] = 6
costs["B"] = 2
costs["final"] = float("inf")   # 到终点所需时间未知, 设为 ∞

# 存储父节点
parents = {}
parents["A"] = "start"
parents["B"] = "start"
parents["final"] = None
  1. 计算最短距离
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: # 如果当前节点的distance更小且未处理
            lowest_cost = cost                           # 将其视为distance最小的节点
            lowest_cost_node = node
    return lowest_cost_node

processed = []  # 记录处理过的节点
node = find_lowest_cost_node(costs)    # 在未处理的node中找出distance最小的node
while node is not None:                # while循环在所有node都被处理过后结束
    cost = costs[node]
    neighbors = graph[node]
    for n in neighbors.keys():          # 遍历当前node的所有neighbor
        new_cost = cost + neighbors[n]
        if costs[n] > new_cost:         # 如果经当前node前往该neighbor更近,就更新该neighbor的distance
            costs[n] = new_cost         
            parents[n] = node           # 同时将该neighbor的parent设置为当前node
    processed.append(node)              # 将当前node标记为处理过,找出接下来要处理的node,并循环
    node = find_lowest_cost_node(costs) 

print(costs)   # {'A': 5, 'B': 2, 'final': 6}

到达终点的最短距离是6, 很明显最短路径为:起点->B->A->终点

note:

  • 广度优先搜索用于在非加权图中查找最短路径
  • 狄克斯特拉算法用于在加权图中查找最短路径
  • 仅当权重为正时狄克斯特拉算法才管用
  • 如果图中包含负权边,请使用贝尔曼-福德算法

你可能感兴趣的:(狄克斯特拉算法-最短路径)