Floyd-Warshall 算法:获得最短路径

Posted

技术标签:

【中文标题】Floyd-Warshall 算法:获得最短路径【英文标题】:Floyd-Warshall algorithm: get the shortest paths 【发布时间】:2017-09-12 13:34:55 【问题描述】:

假设图由n x n 维度邻接矩阵表示。我知道如何获得所有对的最短路径矩阵。但我想知道有没有办法追踪所有最短路径? Blow是python代码实现。

v = len(graph)
for k in range(0,v):
    for i in range(0,v):
        for j in range(0,v):
            if graph[i,j] > graph[i,k] + graph[k,j]:
                graph[i,j] = graph[i,k] + graph[k,j]

【问题讨论】:

请描述此代码产生的内容以及它如何满足或不满足您的要求。 【参考方案1】:

您必须在 if 语句中添加一个新矩阵来存储路径重建数据(数组 p 是前驱矩阵):

    if graph[i,j] > graph[i,k] + graph[k,j]:
        graph[i,j] = graph[i,k] + graph[k,j]
        p[i,j] = p[k,j]

一开始矩阵p必须填写为:

for i in range(0,v):
    for j in range(0,v):
        p[i,j] = i
        if (i != j and graph[i,j] == 0):
             p[i,j] = -30000  # any big negative number to show no arc (F-W does not work with negative weights)

要重建ij 节点之间的路径,您必须调用:

def ConstructPath(p, i, j):
    i,j = int(i), int(j)
    if(i==j):
      print (i,)
    elif(p[i,j] == -30000):
      print (i,'-',j)
    else:
      ConstructPath(p, i, p[i,j]);
      print(j,)

以及上述功能的测试:

import numpy as np

graph = np.array([[0,10,20,30,0,0],[0,0,0,0,0,7],[0,0,0,0,0,5],[0,0,0,0,10,0],[2,0,0,0,0,4],[0,5,7,0,6,0]])

v = len(graph)

# path reconstruction matrix
p = np.zeros(graph.shape)
for i in range(0,v):
    for j in range(0,v):
        p[i,j] = i
        if (i != j and graph[i,j] == 0): 
            p[i,j] = -30000 
            graph[i,j] = 30000 # set zeros to any large number which is bigger then the longest way

for k in range(0,v):
    for i in range(0,v):
        for j in range(0,v):
            if graph[i,j] > graph[i,k] + graph[k,j]:
                graph[i,j] = graph[i,k] + graph[k,j]
                p[i,j] = p[k,j]

# show p matrix
print(p)

# reconstruct the path from 0 to 4
ConstructPath(p,0,4)

输出:

p:

[[ 0.  0.  0.  0.  5.  1.]
 [ 4.  1.  5.  0.  5.  1.]
 [ 4.  5.  2.  0.  5.  2.]
 [ 4.  5.  5.  3.  3.  4.]
 [ 4.  5.  5.  0.  4.  4.]
 [ 4.  5.  5.  0.  5.  5.]]

路径 0-4:

0
1
5
4

【讨论】:

递归不是python中的最佳选择,记得使用setrecursionlimit (docs.python.org/library/sys.html#sys.setrecursionlimit)(否则你会得到稍长的路径的递归深度限制异常)或将ConstructPath更改为循环。 这种情况我觉得很可观

以上是关于Floyd-Warshall 算法:获得最短路径的主要内容,如果未能解决你的问题,请参考以下文章

多源最短路径--Floyd-Warshall算法

最短路径之Dijkstra算法和Floyd-Warshall算法

如何在 Floyd-Warshall 算法中输出最短路径?

Floyd-Warshall算法(最短路)

多源最短路径---Floyd-Warshall算法

多源最短路径 – Floyd-Warshall Algorithm