Floyd 的最短路径算法 C++
Posted
技术标签:
【中文标题】Floyd 的最短路径算法 C++【英文标题】:Floyd's Shortest Path Algorithm C++ 【发布时间】:2017-04-18 17:46:09 【问题描述】:我已经在 C++ 中为弗洛伊德算法实现了一个函数,该函数可以正常工作,除了当我生成一个路径矩阵时,它会在尝试到达目的地时给出下一个节点,它将顶点放在目的地之前而不是矩阵中源的下一个节点。距离矩阵(dist)是正确的,如果源和目标之间最多有一个节点,那么整个路径矩阵是正确的。因此,如果从顶点 i 到 j 有很长的最短路径,那么 path[i][j] 应该等于连接到 i 的 k 值,而不是连接到 j 的 k 值,我不知道为什么。功能如下图。
void floyd(const Graph<City>& g, double**& dist, int**& path)
int n = g.size();
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
path[i][j]=0;
if (i==j)
dist[i][j]=0;
else if (!g.isEdge(i, j))
dist[i][j]=INFINITY;
else
dist[i][j]=g.retrieveEdge(i, j);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
for (int k = 1; k <= n; k++)
if ((dist[i][k]!=INFINITY) && (dist[k][j]!=INFINITY) && k!=i && k!=j && i!=j)
if ((dist[i][j]) > (dist[i][k]+dist[k][j]))
path[i][j]=k;
dist[i][j]=dist[i][k]+dist[k][j];
【问题讨论】:
首先使用您的调试器查看代码中哪里偏离了您的设想。其次,在 C++ 中伪造基于 1 的数组是一种危险的游戏——它可能导致一次次内存覆盖。 使用 base 1 数组只会在内存中造成一些浪费的地方,我一定要注意那里的问题,但是使用调试器我只能发现它一定是我的样子覆盖路径[i][j]。它有时会被不正确的值覆盖,无论我做什么,我都不明白为什么。 如果值被“无缘无故”覆盖,那么基于 1 的数组可能是它的原因。同样,使用从 1 开始的数组是内存覆盖或在某些情况下无意使用元素 0 的主要原因,其中元素 0 是垃圾值(但不是非法内存访问)。 不是无缘无故的。只是不正确。它们应该被沿路径的源中的下一个节点覆盖,而不是沿路径到目的地的紧邻目的地之前的节点。 好吧,使用调试器,看看为什么这部分代码正在做它正在做的事情。我们没有minimal reproducible example,所以我们无法编译和运行任何东西。 【参考方案1】:所以如果从顶点 i 到 j 有很长的最短路径,那么 path[i][j] 应该等于连接到 i 的 k 值,而不是连接到 j 的 k 值,我不知道为什么。
不幸的是,两者都没有。您的实现中没有任何内容可以保证path[i][j]
应该等于紧跟在i
之后的k
值,并且您观察到path[i][j]
当前是紧接在j
之前的k
值也是不正确。 (请多尝试几个样本来验证第二点。)
您的实现唯一保证的是顶点path[i][j] == k
位于某处从顶点i
到顶点j
的最短路径中。
因此,您可以通过以下方式递归检索路径:
get_path(i, j):
k = path[i][j]
get_path(i, k) + k + get_path(k, j)
澄清后,there does exist a method 可以存储path[i][j]
以便它是紧跟在i
之后的顶点。
【讨论】:
以上是关于Floyd 的最短路径算法 C++的主要内容,如果未能解决你的问题,请参考以下文章
a*算法求最短路径和floyd还有dijsktra算法求最短路径的区别?
C++ 实现带权有向图的每对顶点之间的最短路径Floyd算法(完整代码)
四大算法解决最短路径问题(Dijkstra+Bellman-ford+SPFA+Floyd)