具有路径重建的 Floyd–Warshall 算法找不到路径

Posted

技术标签:

【中文标题】具有路径重建的 Floyd–Warshall 算法找不到路径【英文标题】:Floyd–Warshall algorithm with path reconstruction does not find a path 【发布时间】:2014-05-12 10:02:30 【问题描述】:

我正在尝试使用 Floyd-Warshall 算法通过计算所有对之间的最短路径来找到源和目标之间的最短路径。

我需要找到最短的路径,而不仅仅是距离。这就是我想要做的: 我将第一个顶点存储在从 i 到 j 的最短路径上。每当从 i 到 j 的最短路径更新并且它现在经过 k 时,我将从 i 到 j 的最短路径上的第一个顶点设置为从 i 到 k 的最短路径上的第一个顶点。

/*first[i][j] is the first vertex after i on the shortest path from i to j.
first[i][j] is initially j if there is an edge from i to j and the dist[i][j] is the weight of the edge. Otherwise f[i][j] is -1 and the cost is infinity.
*/
for(k = 0; k < N; ++k)
    for(i = 0; i  < N; ++i)
        for(j = 0; j < N; ++j)
            if(dist[i][j] >= dist[i][k]+dist[k][j])
               dist[i][j] = dist[i][k]+dist[k][j];
               //When the distance is updated, update first[i][j]
               first[i][j] = first[i][k];
            
        
    

这个算法的问题是,当我在下图上运行这个算法时,这个算法找到的路径是一个无限循环。

这是算法计算出的first矩阵:

4 4 4 4 4 4 
2 2 2 2 2 2 
5 5 5 5 5 5 
1 1 1 1 1 1 
0 0 0 0 0 0 
2 2 2 2 2 2 

从0到任何其他顶点的最短路径上的第一个顶点,根据算法是4,但是从4到任何其他顶点的最短路径上的第一个顶点是0。

为什么该算法会以这种方式运行? 在计算路径长度时是否有另一种方法可以计算每条路径上的第一个(在源之后)顶点

我已经阅读了Wikipedia 文章以及一些关于 SO 的问题,但它们并没有太大帮助。

【问题讨论】:

dist 和 first 是否正确初始化?顺便说一句,我建议使用 python 来试验算法。容易得多。 是的,它们已正确初始化,我会将其添加到问题中。 哎呀...我看到你又澄清了:) Aaaand... 图不清楚:0 到 3 之间的边是单向的吗?还有一件不清楚的事情:dist[i][i] 0 吗? 请注意,在***中,比较的不是&gt;=,而是&gt;。在那个地方写&gt;=可能是你自循环的原因。 【参考方案1】:

您的dist 矩阵似乎已正确计算,但您的first 矩阵加法似乎存在零成本边缘问题。

查看这个稍微修改过的 Python 版本的代码,它使用 0.01 作为所有自边和其他 0 成本边的成本。

http://pastebin.com/fub60HA5

该代码输出(希望)正确的 distfirst 矩阵

[0.01,  inf,  inf, 0.01, 0.01,  inf]
[0.02, 0.01, 0.01, 0.01, 0.03, 0.02]
[0.01,  inf, 0.01, 0.02, 0.02, 0.01]
[ inf,  inf,  inf, 0.01,  inf,  inf]
[0.01,  inf,  inf, 0.02, 0.01,  inf]
[0.02,  inf, 0.01, 0.01, 0.03, 0.01]

[   0, None, None,    3,    4, None]
[   2,    1,    2,    3,    2,    2]
[   0, None,    2,    5,    0,    5]
[None, None, None,    3, None, None]
[   0, None, None,    0,    4, None]
[   2, None,    2,    3,    2,    5]

【讨论】:

谢谢。您对 >= 的看法也是正确的,因为 first[i][j] 只会为最短路径设置一次,并且它是正确的。

以上是关于具有路径重建的 Floyd–Warshall 算法找不到路径的主要内容,如果未能解决你的问题,请参考以下文章

没有递归的弗洛伊德-沃歇尔路径重建

Java 中的 Floyd Warshall 具有 15000 个顶点的矩阵

Floyd/Warshall Algorithm mod 在最大长度 k 处找到最便宜的路径

Dijkstra vs. Floyd-Warshall:在所有节点对上寻找最优路径

适用于负循环的 Floyd-Warshall 算法 [关闭]

Floyd-Warshall算法正确性证明