要找到 i→j 的最短路,我们就先从顶点 a 开始尝试,看看 i→a + a→j 是否会更短。接着再多加一个顶点 b ,看看通过 a 与 b 进行中转会不会有更多距离。然后是 a, b 与 c ……以此类推,直到尝试完所有顶点的中转。此时得到的最短路径即为 i→j 的最短路。
代码实现
1
vector<vector<int>> spath = adjacent;
首先为了防止原矩阵被修改,我们创建一个原邻接矩阵的拷贝spath来存储信息。
接着一步步来,对于所有起点 i 与终点 j ,通过顶点 0 进行松弛:
1 2 3 4
for (int i = 0; i < vertex_num; i++) for (int j = 0; j < vertex_num; j++) if (spath[i][0] + spath[0][j] < spath[i][j]) spath[i][j] = spath[i][0] + spath[0][j];
然后是顶点 1 :
1 2 3 4
for (int i = 0; i < vertex_num; i++) for (int j = 0; j < vertex_num; j++) if (spath[i][1] + spath[1][j] < spath[i][j]) spath[i][j] = spath[i][1] + spath[1][j];
由于最后要通过所有顶点都松弛一遍,所以显然,需要再嵌套一个循环:
1 2 3 4 5
for (int k = 0; k < vertex_num; k++) for (int i = 0; i < vertex_num; i++) for (int j = 0; j < vertex_num; j++) if (spath[i][k] + spath[k][j] < spath[i][j]) spath[i][j] = spath[i][k] + spath[k][j];
Floyd算法到此结束。spath中存储的信息就是任意两点间的最短路径。
怎么样,是不是很简洁?下面是算法的完整代码:
1 2 3 4 5 6 7 8 9 10 11 12 13
template <classT> voidAdjacencyMatrix<T>::floyd() { vector<vector<int>> spath = adjacent; for (int k = 0; k < vertex_num; k++) for (int i = 0; i < vertex_num; i++) for (int j = 0; j < vertex_num; j++) if (spath[i][k] + spath[k][j] < spath[i][j]) spath[i][j] = spath[i][k] + spath[k][j]; /**/ //输出结果 /**/ }