求任意两点间的最短路径
思路——动态规划
- 假设一个邻接矩阵 M,初始时刻,任意两个节点之间的距离就是邻接矩阵,因此将 dp 矩阵初始化为邻接矩阵,也就是边界条件。定义一个 path 矩阵记录任意两个节点之间的第一个中转节点,path 矩阵的初始值是终点节点自身。
- 然后每次选择一个节点加入路径作为中转节点,并更新 dp 矩阵,状态转移方程为:M[i][j] = min(M[i][j], M[i][k] + M[k][i])。将 dp 矩阵中路径值发生变化的两个节点的 path 更新为 : path[i][j] = path[i][k]。
- 直到最后选择完所有节点加入路径作为中转节点,最后的 dp 矩阵就是任意两点间的最短路径,path 矩阵就是任意两个节点之间的第一个中转节点。
- 想要知道两个节点 u 和 v 之间最短路径上的节点,可以通过 path 矩阵。
4.1 首先查询 path 矩阵中,节点 u 和节点 v 之间的第一个中转节点 path[u][v] = k,加入栈。
4.2 然后查询该中转节点 k 和节点 v 之间的中转节点 path[k][v],加入栈。
4.3 重复查询中转节点,直到找到终点节点 j,加入栈。
4.4 最后栈底到栈顶就是节点 u 到节点 v 的最短路径上的节点。
python代码
import copy
import math
def floyd(graph):
node_num = len(graph)
dist = copy.deepcopy(graph)
path = [[i for i in range(node_num)] for _ in range(node_num)]
for k in range(node_num):
for i in range(node_num):
for j in range(node_num):
temp, dist[i][j] = dist[i][j], min(dist[i][j], dist[i][k] + dist[k][j])
if dist[i][j] != temp:
path[i][j] = path[i][k]
return dist, path
if __name__ == '__main__':
graph = [[0, 3, 4],
[3, 0, math.inf],
[4, math.inf, 0]]
dist, path = floyd(graph)