如何解决Floyd Warshall的算法为何成功?
如何阻止在经过迭代的更早的外部循环的后续迭代(遍历所有可能的中间顶点)中找到更好的中间路径?
解决方法
我认为您对Floyd-Warshall算法的工作方式有误解。作为参考,这是一个实现(来自https://cp-algorithms.com/graph/all-pair-shortest-path-floyd-warshall.html):
for (int k = 0; k < n; ++k) {
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
d[i][j] = min(d[i][j],d[i][k] + d[k][j]);
}
}
}
最外面的循环不会在所有中间顶点上循环。计算从i
到j
的最短路径时,最外面的循环定义了一组顶点,这些顶点可以是从i
到j
的路径的一部分。特别是,如果我们标记n
顶点1,2,3,...,n
,则k
的值指定在该迭代中我们只能访问集合{1,k}
的顶点。您可以看到,k -> n
的值d[i][j]
最终收敛到我们的解决方案中(因为应该允许使用真正的“最短路径”将任何顶点用作中间值)。
为什么我们要用这种方式分解它?因为如果我们知道固定值k
的解决方案,那么我们可以轻松地构造k + 1
的解决方案。这是动态编程的关键原则,您应该尝试了解循环d[i][j] = min(d[i][j],d[i][k] + d[k][j])
如何耗尽所有可能性。
现在可以更直接地直接回答您的问题,使用集{1,k}
的新计算路径是否使用最外层循环的上一次迭代的结果也没关系。这是正确的,因为集合{1,k - 1}
是{1,k}
的子集,因此如果我们确实重用了之前缩短的计算路径,那将是非常好的。关键思想是我们具有 option 来使用新添加的顶点k
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。