每一对顶点之间的最短路径
Floyd
-
时间复杂度:O(n3)O(n^3)O(n3)
弗洛伊德算法仍从图的带权邻接矩阵cost出发,其基本思想是:
假设求从顶点viv_ivi到vjv_jvj的最短路径:
如果从viv_ivi到vjv_jvj有弧,则从viv_ivi到vjv_jvj存在一条长度为arcs[i][j]arcs[i][j]arcs[i][j]的路径,该路径不一定是最短路径,尚需进行n次试探。
首先考虑路径(vi,vo,vj)(v_i,v_o,v_j)(vi,vo,vj)是否存在(即判别弧(vi,vo)(v_i,v_o)(vi,vo)和(vo,vj)(v_o,v_j)(vo,vj)是否存在)
如果存在:则比较(vi,vj)(v_i,v_j)(vi,vj)和(vi,vo,vj)(v_i,v_o,v_j)(vi,vo,vj)的路径长度取长度较短者为从viv_ivi到vjv_jvj的中间顶点的序号不大于0的最短路
径。 假如在路径上再增加一个顶点v1v_1v1,也就是说,如果(vi,...,v1)(v_i,...,v_1)(vi,...,v1)和(v1,...,vj)(v_1,...,v_j)(v1,...,vj)分别是当前找到的中间顶点的序号不大于0的最短路径,那么(vi,...,v1,...,vj)(v_i,...,v_1,...,v_j)(vi,...,v1,...,vj)就有可能是从viv_ivi到vjv_jvj的中间顶点的序号不大于1的最短路径。
将它和已经得到的从viv_ivi到vjv_jvj中间顶点序号不大于0的最短路径相比较,从中选出中间顶点的序号不大于1的最短路径之后,再增加一个顶点v2v_2v2,继续进行试探。依次类推。
在一般情况下,若(vi,...,vk)(v_i,...,v_k)(vi,...,vk)和(vk,...,vj)(v_k,...,v_j)(vk,...,vj)分别是从viv_ivi到vkv_kvk和从vkv_kvk到vjv_jvj的中间顶点的序号不大于k-1的最短路径,则将(vi,...,vk,...,vj)(v_i,...,v_k,...,v_j)(vi,...,vk,...,vj)和已经得到的从 viv_ivi到vjv_jvj且中间顶点序号不大于k-1的最短路径相比较,其长度较短者便是从v:到v;的中间顶点的序号不大于k的最短路径。
这样,在经过n次比较后,最后求得的必是从viv_ivi到vjv_jvj的最短路径。按此方法,可以同时求得各对顶点间的最短路径。
现定义一个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.arcs[i][j]D^{(-1)}[i][j]=G.arcs[i][j]D(−1)[i][j]=G.arcs[i][j]
D(k)[i][j]=Min{D(k−1)[i][j],D(k−1)[i][k]+D(k−1)[k][j]} 0≤K≤n−1D^{(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-1D(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语言版)].严蔚敏
本文详细介绍Floyd算法原理及其应用,该算法能够在O(n³)的时间复杂度内计算出图中每一对顶点间的最短路径。通过逐步迭代,最终确定所有顶点间的最短路径。

被折叠的 条评论
为什么被折叠?



