图的最小路径之弗洛伊德算法
实现源码:
typedef int Pathmatirx[MAXVER][MAXVER];
typedef int ShortPathTable[MAXVER][MAXVER];void ShortestPath_Floyd(MGraph G, Pathmatirx *P, ShortPathTable *D)
{
int v, w, k;
for (v = 0; v < G.numVertexes; v++)
{
for (w = 0; w < G.numVertexes; w++)
{
(*D)[v][w] = G.arc[v][w];//初始话D二维数组为邻接矩阵
(*P)[v][w] = w;//初始化前驱表的值为w
}
}for (k = 0; k < G.numVertexes; k++)
{
for (v = 0; v < G.numVertexes; v++)
{
for (w = 0; w < G.numVertexes; w++)
{
if ((*D)[v][w] > (*D)[v][k] + (*D)[k][w])
{
(*D)[v][w] = (*D)[v][k] + (*D)[k][w];
(*P)[v][w] = (*P)[v][k];
}
}
}
}}
1. 初始化结束后D,P两个二维数组的信息如下:
2. 来看下核心循环的执行
for (k = 0; k < G.numVertexes; k++)
{
for (v = 0; v < G.numVertexes; v++)
{
for (w = 0; w < G.numVertexes; w++)
{
(*D)[v][w] = (*D)[v][k] + (*D)[k][w];
(*P)[v][w] = (*P)[v][k];
}
}
}
当k = 0时的执行过程分析:
a. 遍历顶点的边数组信息,由于我们在边数组形成的矩阵中使用了极大的不可能值,所以当不存在边的时候具有极大值,所以可以正常的进行如下判断:(两顶点不存在边时和具有极大值,判断已经过滤掉,下面分析不考虑这种不存边的情况)
if ((*D)[v][w] > (*D)[v][k] + (*D)[k][w])
{
(*D)[v][w] = (*D)[v][k] + (*D)[k][w];
(*P)[v][w] = (*P)[v][k];
}
上述代码执行的意义:
- 顶点v-->w的路径是否可用经过顶点K的路径来表示,即是否存在 v-->k --->w;
- 如果存在该路径,比较v-->w的权值 和 v-->k --->w 的权值,如果小于v-->w的权值则更新D[v][w]权值为当前的最小值
- 记录当前存在最小路径经过的下标信息
- D[v][w]代表点到点的最小路径,P[v][w]记录前驱下标的信息
当k = 1 时:
重复执行以上的判断。。。。
最后会得到一个顶点到顶点的最小路径表和下标信息表:
3. 有了D[v][w]和P[v][w]之后如何获取路径:
如v0--->v8的最短路径信息获取:
p[0][8] : v1 ---> p[1][8] : v2 ----> p[2][8] : v4 -----> p[4][8] : v3 -----> p[3][8] : v6 -----> p[6][8] : v7 -----> p[7][8] : v8
以上参考:
- 大话数据结构