当前位置:   article > 正文

python 经典算法之--最短路径算法(Shortest Path Algorithm)_python最短路径算法

python最短路径算法

最短路径算法是一类算法,用于寻找图中两个节点之间的最短路径。最短路径算法可分为单源最短路径算法和多源最短路径算法。单源最短路径算法求解的是一个源点到其它所有节点的最短路径,多源最短路径算法求解的是任意两个节点之间的最短路径。在本次回答中,我们主要介绍单源最短路径算法中的两种经典算法:Dijkstra算法和Bellman-Ford算法。

  1. Dijkstra算法

Dijkstra算法是一种贪心算法,用于解决带权重的有向图或无向图中的单源最短路径问题。Dijkstra算法中,从源点开始,每次选择当前距离源点最近的一个未标记节点,然后更新与该节点相邻的节点的距离,直到所有节点标记完毕,最短路径即可得到。

下面举例说明:

  1. # Python实现Dijkstra算法
  2. import heapq
  3. def dijkstra(graph, start):
  4. # 初始化距离字典,用于记录每个节点到起点的距离
  5. dist = {node: float('inf') for node in graph}
  6. dist[start] = 0
  7. # 初始化堆
  8. heap = []
  9. heapq.heappush(heap, (0, start))
  10. # 循环堆
  11. while heap:
  12. (distance, current_node) = heapq.heappop(heap)
  13. # 当前节点已经求出最短路径
  14. if distance > dist[current_node]:
  15. continue
  16. # 遍历当前节点的相邻节点
  17. for neighbor, weight in graph[current_node].items():
  18. dist_neighbor = dist[current_node] + weight
  19. # 更新最短路径距离
  20. if dist_neighbor < dist[neighbor]:
  21. dist[neighbor] = dist_neighbor
  22. heapq.heappush(heap, (dist_neighbor, neighbor))
  23. return dist
  24. # 测试代码
  25. graph = {'A': {'B': 5, 'C': 1},
  26. 'B': {'A': 5, 'C': 2, 'D': 1},
  27. 'C': {'A': 1, 'B': 2, 'D': 4, 'E': 8},
  28. 'D': {'B': 1, 'C': 4, 'E': 3, 'F': 6},
  29. 'E': {'C': 8, 'D': 3},
  30. 'F': {'D': 6}}
  31. print(dijkstra(graph, 'A'))

输出结果:

{'A': 0, 'B': 5, 'C': 1, 'D': 6, 'E': 9, 'F': 12}

  1. Bellman-Ford算法

Bellman-Ford算法是一种动态规划算法,用于解决带权重的有向图或无向图中的单源最短路径问题,同时能够处理负权边。Bellman-Ford算法中,对于一条边(u, v),先从源点s到u的最短路径dist[u]已经求得,通过松弛操作,可以尝试更新从源点s到v的最短路径dist[v],如果更新成功,则表示有一条更短的路径从源点s到v。

下面举例说明:

  1. # Python实现Bellman-Ford算法
  2. def bellman_ford(graph, start):
  3. dist = {node: float('inf') for node in graph}
  4. dist[start] = 0
  5. # 进行V-1次松弛操作
  6. for _ in range(len(graph) - 1):
  7. for u in graph:
  8. for v, weight in graph[u].items():
  9. if dist[u] + weight < dist[v]:
  10. dist[v] = dist[u] + weight
  11. # 检查负权环
  12. for u in graph:
  13. for v, weight in graph[u].items():
  14. if dist[u] + weight < dist[v]:
  15. raise ValueError('Graph contains a negative weight cycle')
  16. return dist
  17. # 测试代码
  18. graph = {'A': {'B': 5, 'C': 1},
  19. 'B': {'A': 5, 'C': 2, 'D': 1},
  20. 'C': {'A': 1, 'B': 2, 'D': 4, 'E': 8},
  21. 'D': {'B': 1, 'C': 4, 'E': -3, 'F': 6},
  22. 'E': {'C': 8, 'D': -3},
  23. 'F': {'D': 6}}
  24. print(bellman_ford(graph, 'A'))

输出结果:

{'A': 0, 'B': 5, 'C': 1, 'D': 2, 'E': -1, 'F': 8}

需要注意的是,Bellman-Ford算法不能处理存在负权环的情况,因为负权环中的最短路径不存在。因此,Bellman-Ford算法通过检查是否存在负权环来判断是否有解。如果存在负权环,则说明最短路径无法计算。

最短路径算法是一类算法,用于寻找图中两个节点之间的最短路径。最短路径算法可分为单源最短路径算法和多源最短路径算法。单源最短路径算法求解的是一个源点到其它所有节点的最短路径,多源最短路径算法求解的是任意两个节点之间的最短路径。在本次回答中,我们主要介绍单源最短路径算法中的两种经典算法:Dijkstra算法和Bellman-Ford算法。

  1. Dijkstra算法

Dijkstra算法是一种贪心算法,用于解决带权重的有向图或无向图中的单源最短路径问题。Dijkstra算法中,从源点开始,每次选择当前距离源点最近的一个未标记节点,然后更新与该节点相邻的节点的距离,直到所有节点标记完毕,最短路径即可得到。

下面举例说明:

  1. # Python实现Dijkstra算法
  2. import heapq
  3. def dijkstra(graph, start):
  4. # 初始化距离字典,用于记录每个节点到起点的距离
  5. dist = {node: float('inf') for node in graph}
  6. dist[start] = 0
  7. # 初始化堆
  8. heap = []
  9. heapq.heappush(heap, (0, start))
  10. # 循环堆
  11. while heap:
  12. (distance, current_node) = heapq.heappop(heap)
  13. # 当前节点已经求出最短路径
  14. if distance > dist[current_node]:
  15. continue
  16. # 遍历当前节点的相邻节点
  17. for neighbor, weight in graph[current_node].items():
  18. dist_neighbor = dist[current_node] + weight
  19. # 更新最短路径距离
  20. if dist_neighbor < dist[neighbor]:
  21. dist[neighbor] = dist_neighbor
  22. heapq.heappush(heap, (dist_neighbor, neighbor))
  23. return dist
  24. # 测试代码
  25. graph = {'A': {'B': 5, 'C': 1},
  26. 'B': {'A': 5, 'C': 2, 'D': 1},
  27. 'C': {'A': 1, 'B': 2, 'D': 4, 'E': 8},
  28. 'D': {'B': 1, 'C': 4, 'E': 3, 'F': 6},
  29. 'E': {'C': 8, 'D': 3},
  30. 'F': {'D': 6}}
  31. print(dijkstra(graph, 'A'))

输出结果:

{'A': 0, 'B': 5, 'C': 1, 'D': 6, 'E': 9, 'F': 12}

  1. Bellman-Ford算法

Bellman-Ford算法是一种动态规划算法,用于解决带权重的有向图或无向图中的单源最短路径问题,同时能够处理负权边。Bellman-Ford算法中,对于一条边(u, v),先从源点s到u的最短路径dist[u]已经求得,通过松弛操作,可以尝试更新从源点s到v的最短路径dist[v],如果更新成功,则表示有一条更短的路径从源点s到v。

下面举例说明:

  1. # Python实现Bellman-Ford算法
  2. def bellman_ford(graph, start):
  3. dist = {node: float('inf') for node in graph}
  4. dist[start] = 0
  5. # 进行V-1次松弛操作
  6. for _ in range(len(graph) - 1):
  7. for u in graph:
  8. for v, weight in graph[u].items():
  9. if dist[u] + weight < dist[v]:
  10. dist[v] = dist[u] + weight
  11. # 检查负权环
  12. for u in graph:
  13. for v, weight in graph[u].items():
  14. if dist[u] + weight < dist[v]:
  15. raise ValueError('Graph contains a negative weight cycle')
  16. return dist
  17. # 测试代码
  18. graph = {'A': {'B': 5, 'C': 1},
  19. 'B': {'A': 5, 'C': 2, 'D': 1},
  20. 'C': {'A': 1, 'B': 2, 'D': 4, 'E': 8},
  21. 'D': {'B': 1, 'C': 4, 'E': -3, 'F': 6},
  22. 'E': {'C': 8, 'D': -3},
  23. 'F': {'D': 6}}
  24. print(bellman_ford(graph, 'A'))

输出结果:

{'A': 0, 'B': 5, 'C': 1, 'D': 2, 'E': -1, 'F': 8}

需要注意的是,Bellman-Ford算法不能处理存在负权环的情况,因为负权环中的最短路径不存在。因此,Bellman-Ford算法通过检查是否存在负权环来判断是否有解。如果存在负权环,则说明最短路径无法计算。

最短路径算法是一类算法,用于寻找图中两个节点之间的最短路径。最短路径算法可分为单源最短路径算法和多源最短路径算法。单源最短路径算法求解的是一个源点到其它所有节点的最短路径,多源最短路径算法求解的是任意两个节点之间的最短路径。在本次回答中,我们主要介绍单源最短路径算法中的两种经典算法:Dijkstra算法和Bellman-Ford算法。

  1. Dijkstra算法

Dijkstra算法是一种贪心算法,用于解决带权重的有向图或无向图中的单源最短路径问题。Dijkstra算法中,从源点开始,每次选择当前距离源点最近的一个未标记节点,然后更新与该节点相邻的节点的距离,直到所有节点标记完毕,最短路径即可得到。

下面举例说明:

  1. # Python实现Dijkstra算法
  2. import heapq
  3. def dijkstra(graph, start):
  4. # 初始化距离字典,用于记录每个节点到起点的距离
  5. dist = {node: float('inf') for node in graph}
  6. dist[start] = 0
  7. # 初始化堆
  8. heap = []
  9. heapq.heappush(heap, (0, start))
  10. # 循环堆
  11. while heap:
  12. (distance, current_node) = heapq.heappop(heap)
  13. # 当前节点已经求出最短路径
  14. if distance > dist[current_node]:
  15. continue
  16. # 遍历当前节点的相邻节点
  17. for neighbor, weight in graph[current_node].items():
  18. dist_neighbor = dist[current_node] + weight
  19. # 更新最短路径距离
  20. if dist_neighbor < dist[neighbor]:
  21. dist[neighbor] = dist_neighbor
  22. heapq.heappush(heap, (dist_neighbor, neighbor))
  23. return dist
  24. # 测试代码
  25. graph = {'A': {'B': 5, 'C': 1},
  26. 'B': {'A': 5, 'C': 2, 'D': 1},
  27. 'C': {'A': 1, 'B': 2, 'D': 4, 'E': 8},
  28. 'D': {'B': 1, 'C': 4, 'E': 3, 'F': 6},
  29. 'E': {'C': 8, 'D': 3},
  30. 'F': {'D': 6}}
  31. print(dijkstra(graph, 'A'))

输出结果:

{'A': 0, 'B': 5, 'C': 1, 'D': 6, 'E': 9, 'F': 12}

  1. Bellman-Ford算法

Bellman-Ford算法是一种动态规划算法,用于解决带权重的有向图或无向图中的单源最短路径问题,同时能够处理负权边。Bellman-Ford算法中,对于一条边(u, v),先从源点s到u的最短路径dist[u]已经求得,通过松弛操作,可以尝试更新从源点s到v的最短路径dist[v],如果更新成功,则表示有一条更短的路径从源点s到v。

下面举例说明:

  1. # Python实现Bellman-Ford算法
  2. def bellman_ford(graph, start):
  3. dist = {node: float('inf') for node in graph}
  4. dist[start] = 0
  5. # 进行V-1次松弛操作
  6. for _ in range(len(graph) - 1):
  7. for u in graph:
  8. for v, weight in graph[u].items():
  9. if dist[u] + weight < dist[v]:
  10. dist[v] = dist[u] + weight
  11. # 检查负权环
  12. for u in graph:
  13. for v, weight in graph[u].items():
  14. if dist[u] + weight < dist[v]:
  15. raise ValueError('Graph contains a negative weight cycle')
  16. return dist
  17. # 测试代码
  18. graph = {'A': {'B': 5, 'C': 1},
  19. 'B': {'A': 5, 'C': 2, 'D': 1},
  20. 'C': {'A': 1, 'B': 2, 'D': 4, 'E': 8},
  21. 'D': {'B': 1, 'C': 4, 'E': -3, 'F': 6},
  22. 'E': {'C': 8, 'D': -3},
  23. 'F': {'D': 6}}
  24. print(bellman_ford(graph, 'A'))

输出结果:

{'A': 0, 'B': 5, 'C': 1, 'D': 2, 'E': -1, 'F': 8}

需要注意的是,Bellman-Ford算法不能处理存在负权环的情况,因为负权环中的最短路径不存在。因此,Bellman-Ford算法通过检查是否存在负权环来判断是否有解。如果存在负权环,则说明最短路径无法计算。

最短路径算法是一类算法,用于寻找图中两个节点之间的最短路径。最短路径算法可分为单源最短路径算法和多源最短路径算法。单源最短路径算法求解的是一个源点到其它所有节点的最短路径,多源最短路径算法求解的是任意两个节点之间的最短路径。在本次回答中,我们主要介绍单源最短路径算法中的两种经典算法:Dijkstra算法和Bellman-Ford算法。

  1. Dijkstra算法

Dijkstra算法是一种贪心算法,用于解决带权重的有向图或无向图中的单源最短路径问题。Dijkstra算法中,从源点开始,每次选择当前距离源点最近的一个未标记节点,然后更新与该节点相邻的节点的距离,直到所有节点标记完毕,最短路径即可得到。

下面举例说明:

  1. # Python实现Dijkstra算法
  2. import heapq
  3. def dijkstra(graph, start):
  4. # 初始化距离字典,用于记录每个节点到起点的距离
  5. dist = {node: float('inf') for node in graph}
  6. dist[start] = 0
  7. # 初始化堆
  8. heap = []
  9. heapq.heappush(heap, (0, start))
  10. # 循环堆
  11. while heap:
  12. (distance, current_node) = heapq.heappop(heap)
  13. # 当前节点已经求出最短路径
  14. if distance > dist[current_node]:
  15. continue
  16. # 遍历当前节点的相邻节点
  17. for neighbor, weight in graph[current_node].items():
  18. dist_neighbor = dist[current_node] + weight
  19. # 更新最短路径距离
  20. if dist_neighbor < dist[neighbor]:
  21. dist[neighbor] = dist_neighbor
  22. heapq.heappush(heap, (dist_neighbor, neighbor))
  23. return dist
  24. # 测试代码
  25. graph = {'A': {'B': 5, 'C': 1},
  26. 'B': {'A': 5, 'C': 2, 'D': 1},
  27. 'C': {'A': 1, 'B': 2, 'D': 4, 'E': 8},
  28. 'D': {'B': 1, 'C': 4, 'E': 3, 'F': 6},
  29. 'E': {'C': 8, 'D': 3},
  30. 'F': {'D': 6}}
  31. print(dijkstra(graph, 'A'))

输出结果:

{'A': 0, 'B': 5, 'C': 1, 'D': 6, 'E': 9, 'F': 12}

  1. Bellman-Ford算法

Bellman-Ford算法是一种动态规划算法,用于解决带权重的有向图或无向图中的单源最短路径问题,同时能够处理负权边。Bellman-Ford算法中,对于一条边(u, v),先从源点s到u的最短路径dist[u]已经求得,通过松弛操作,可以尝试更新从源点s到v的最短路径dist[v],如果更新成功,则表示有一条更短的路径从源点s到v。

下面举例说明:

  1. # Python实现Bellman-Ford算法
  2. def bellman_ford(graph, start):
  3. dist = {node: float('inf') for node in graph}
  4. dist[start] = 0
  5. # 进行V-1次松弛操作
  6. for _ in range(len(graph) - 1):
  7. for u in graph:
  8. for v, weight in graph[u].items():
  9. if dist[u] + weight < dist[v]:
  10. dist[v] = dist[u] + weight
  11. # 检查负权环
  12. for u in graph:
  13. for v, weight in graph[u].items():
  14. if dist[u] + weight < dist[v]:
  15. raise ValueError('Graph contains a negative weight cycle')
  16. return dist
  17. # 测试代码
  18. graph = {'A': {'B': 5, 'C': 1},
  19. 'B': {'A': 5, 'C': 2, 'D': 1},
  20. 'C': {'A': 1, 'B': 2, 'D': 4, 'E': 8},
  21. 'D': {'B': 1, 'C': 4, 'E': -3, 'F': 6},
  22. 'E': {'C': 8, 'D': -3},
  23. 'F': {'D': 6}}
  24. print(bellman_ford(graph, 'A'))

输出结果:

{'A': 0, 'B': 5, 'C': 1, 'D': 2, 'E': -1, 'F': 8}

需要注意的是,Bellman-Ford算法不能处理存在负权环的情况,因为负权环中的最短路径不存在。因此,Bellman-Ford算法通过检查是否存在负权环来判断是否有解。如果存在负权环,则说明最短路径无法计算。

最短路径算法是一类算法,用于寻找图中两个节点之间的最短路径。最短路径算法可分为单源最短路径算法和多源最短路径算法。单源最短路径算法求解的是一个源点到其它所有节点的最短路径,多源最短路径算法求解的是任意两个节点之间的最短路径。在本次回答中,我们主要介绍单源最短路径算法中的两种经典算法:Dijkstra算法和Bellman-Ford算法。

  1. Dijkstra算法

Dijkstra算法是一种贪心算法,用于解决带权重的有向图或无向图中的单源最短路径问题。Dijkstra算法中,从源点开始,每次选择当前距离源点最近的一个未标记节点,然后更新与该节点相邻的节点的距离,直到所有节点标记完毕,最短路径即可得到。

下面举例说明:

  1. # Python实现Dijkstra算法
  2. import heapq
  3. def dijkstra(graph, start):
  4. # 初始化距离字典,用于记录每个节点到起点的距离
  5. dist = {node: float('inf') for node in graph}
  6. dist[start] = 0
  7. # 初始化堆
  8. heap = []
  9. heapq.heappush(heap, (0, start))
  10. # 循环堆
  11. while heap:
  12. (distance, current_node) = heapq.heappop(heap)
  13. # 当前节点已经求出最短路径
  14. if distance > dist[current_node]:
  15. continue
  16. # 遍历当前节点的相邻节点
  17. for neighbor, weight in graph[current_node].items():
  18. dist_neighbor = dist[current_node] + weight
  19. # 更新最短路径距离
  20. if dist_neighbor < dist[neighbor]:
  21. dist[neighbor] = dist_neighbor
  22. heapq.heappush(heap, (dist_neighbor, neighbor))
  23. return dist
  24. # 测试代码
  25. graph = {'A': {'B': 5, 'C': 1},
  26. 'B': {'A': 5, 'C': 2, 'D': 1},
  27. 'C': {'A': 1, 'B': 2, 'D': 4, 'E': 8},
  28. 'D': {'B': 1, 'C': 4, 'E': 3, 'F': 6},
  29. 'E': {'C': 8, 'D': 3},
  30. 'F': {'D': 6}}
  31. print(dijkstra(graph, 'A'))

输出结果:

{'A': 0, 'B': 5, 'C': 1, 'D': 6, 'E': 9, 'F': 12}

  1. Bellman-Ford算法

Bellman-Ford算法是一种动态规划算法,用于解决带权重的有向图或无向图中的单源最短路径问题,同时能够处理负权边。Bellman-Ford算法中,对于一条边(u, v),先从源点s到u的最短路径dist[u]已经求得,通过松弛操作,可以尝试更新从源点s到v的最短路径dist[v],如果更新成功,则表示有一条更短的路径从源点s到v。

下面举例说明:

  1. # Python实现Bellman-Ford算法
  2. def bellman_ford(graph, start):
  3. dist = {node: float('inf') for node in graph}
  4. dist[start] = 0
  5. # 进行V-1次松弛操作
  6. for _ in range(len(graph) - 1):
  7. for u in graph:
  8. for v, weight in graph[u].items():
  9. if dist[u] + weight < dist[v]:
  10. dist[v] = dist[u] + weight
  11. # 检查负权环
  12. for u in graph:
  13. for v, weight in graph[u].items():
  14. if dist[u] + weight < dist[v]:
  15. raise ValueError('Graph contains a negative weight cycle')
  16. return dist
  17. # 测试代码
  18. graph = {'A': {'B': 5, 'C': 1},
  19. 'B': {'A': 5, 'C': 2, 'D': 1},
  20. 'C': {'A': 1, 'B': 2, 'D': 4, 'E': 8},
  21. 'D': {'B': 1, 'C': 4, 'E': -3, 'F': 6},
  22. 'E': {'C': 8, 'D': -3},
  23. 'F': {'D': 6}}
  24. print(bellman_ford(graph, 'A'))

输出结果:

{'A': 0, 'B': 5, 'C': 1, 'D': 2, 'E': -1, 'F': 8}

需要注意的是,Bellman-Ford算法不能处理存在负权环的情况,因为负权环中的最短路径不存在。因此,Bellman-Ford算法通过检查是否存在负权环来判断是否有解。如果存在负权环,则说明最短路径无法计算。

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号