每一对顶点之间的最短路径
Floyd
-
时间复杂度: O ( n 3 ) O(n^3) O(n3)
弗洛伊德算法仍从图的带权邻接矩阵cost出发,其基本思想是:
假设求从顶点 v i v_i vi到 v j v_j vj的最短路径:
如果从 v i v_i vi到 v j v_j vj有弧,则从 v i v_i vi到 v j v_j vj存在一条长度为 a r c s [ i ] [ j ] arcs[i][j] arcs[i][j]的路径,该路径不一定是最短路径,尚需进行n次试探。
首先考虑路径 ( v i , v o , v j ) (v_i,v_o,v_j) (vi,vo,vj)是否存在(即判别弧 ( v i , v o ) (v_i,v_o) (vi,vo)和 ( v o , v j ) (v_o,v_j) (vo,vj)是否存在)
如果存在:则比较 ( v i , v j ) (v_i,v_j) (vi,vj)和 ( v i , v o , v j ) (v_i,v_o,v_j) (vi,vo,vj)的路径长度取长度较短者为从 v i v_i vi到 v j v_j vj的中间顶点的序号不大于0的最短路
径。 假如在路径上再增加一个顶点 v 1 v_1 v1,也就是说,如果 ( v i , . . . , v 1 ) (v_i,...,v_1) (vi,...,v1)和 ( v 1 , . . . , v j ) (v_1,...,v_j) (v1,...,vj)分别是当前找到的中间顶点的序号不大于0的最短路径,那么 ( v i , . . . , v 1 , . . . , v j ) (v_i,...,v_1,...,v_j) (vi,...,v1,...,vj)就有可能是从 v i v_i vi到 v j v_j vj的中间顶点的序号不大于1的最短路径。
将它和已经得到的从 v i v_i vi到 v j v_j vj中间顶点序号不大于0的最短路径相比较,从中选出中间顶点的序号不大于1的最短路径之后,再增加一个顶点 v 2 v_2 v2,继续进行试探。依次类推。
在一般情况下,若 ( v i , . . . , v k ) (v_i,...,v_k) (vi,...,vk)和 ( v k , . . . , v j ) (v_k,...,v_j) (vk,...,vj)分别是从 v i v_i vi到 v k v_k vk和从 v k v_k vk到 v j v_j vj的中间顶点的序号不大于k-1的最短路径,则将 ( v i , . . . , v k , . . . , v j ) (v_i,...,v_k,...,v_j) (vi,...,vk,...,vj)和已经得到的从 v i v_i vi到 v j v_j vj且中间顶点序号不大于k-1的最短路径相比较,其长度较短者便是从v:到v;的中间顶点的序号不大于k的最短路径。
这样,在经过n次比较后,最后求得的必是从 v i v_i vi到 v j v_j vj的最短路径。按此方法,可以同时求得各对顶点间的最短路径。
现定义一个n阶方阵序列 D ( − 1 ) , D ( 0 ) , D ( 1 ) , . . . , D ( k ) , . . . , D ( n − 1 ) D^{(-1)},D^{(0)},D^{(1)},...,D^{(k)},...,D^{(n-1)} D(−1),D(0),D(1),...,D(k),...,D(n−1)
其中 D ( − 1 ) [ i ] [ j ] = G . a r c s [ i ] [ j ] D^{(-1)}[i][j]=G.arcs[i][j] D(−1)[i][j]=G.arcs[i][j]
D ( k ) [ i ] [ j ] = M i n { D ( k − 1 ) [ i ] [ j ] , D ( k − 1 ) [ i ] [ k ] + D ( k − 1 ) [ k ] [ j ] } 0 ≤ K ≤ n − 1 D^{(k)}[i][j]=Min \left\{D^{(k-1)}[i][j],D^{(k-1)}[i][k]+D^{(k-1)}[k][j]\right\} \space 0≤K≤n-1 D(k)[i][j]=Min{D(k−1)[i][j],D(k−1)[i][k]+D(k−1)[k][j]} 0≤K≤n−1
从上述计算公式可见, D ( 1 ) [ i ] [ j ] D^{(1)}[i][j] D(1)[i][j]是从vi到vi的中间顶点的序号不大于1的最短路径的长度; D ( k ) [ i ] [ j ] D^{(k)}[i][j] D(k)[i][j]是从vi到v;的中间顶点的序号不大于k的最短路径的长度; D ( n − 1 ) [ i ] [ j ] D^{(n-1)}[i][j] D(n−1)[i][j]就是从vi到vi的最短路径的长度。
由此可得Floyd算法。void ShortestPath FLOYD(MGraph G, PathMatrix &P[], DistancMatrix &D){ //用Floyd算法求有向网G中各对顶点v和w之间的最短路径[v][w]及其 //带权长度D[v][w]。若P[v][w][u]为TRUE,则u是从v到w当前求得最 //短路径上的顶点。 for (v=0;v<G.vexnum; ++v) // 各对节点之间初始已知路径及距离 for (w=0; w< G.vexnum; ++w) { D[v][w] = G.arcs[v][w]; // 初始时边的距离 for (u=0; u< G.vexnum; ++u) P[v][w][u] = FALSE; //默认最短路径上的顶点都置为FALSE if (D[v][w] < INFINITY){ // 从v 到w有直接路径 P[v][w][v] = True; P[v][w][w] = TRUE; //有直接路径的置为TRUE }//if }//for for (u = 0; u< G.vexnum; ++u)// 定义的k 序号不大于k的最短路径的长度 for (v=0;v<G.vexnum; ++v) for (w = 0; w<G.vexnum;++w) if (D[v][u]+D[u][w]<D[v][w]){ // 从v经u到w的一条路径更短 D[v][w] = D[v][u]+D[u][w]; for (i = 0; i < G.vexnum; ++i) P[v][w][i] = P[v][u][i] || P[u][w][i]; }// if }// ShortestPath FLOYD
参考
- [数据结构(C语言版)].严蔚敏