图-最短路径-Floyd

每一对顶点之间的最短路径
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(n1)
    其中

    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(k1)[i][j],D(k1)[i][k]+D(k1)[k][j]} 0Kn1

    从上述计算公式可见, 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(n1)[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语言版)].严蔚敏
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值