简明理解最短路径之迪杰斯特拉算法

用途

       迪杰斯特拉算法,用来寻找一个带权有向图中的某一顶点v0(源顶点)分别到其他顶点的最短路径集合。

算法所需基础材料声明

       首先,带权有向图的权值例如邻接矩阵arcs[i][j]表示从 i 顶点到 j 顶点的距离。若两顶点不相连其值则为无穷大。

基本思想

       用集合V代表图中所有顶点的集合,集合S代表已经找出了最短路径的顶点,那么集合S-V则为尚未找出最短路径的顶点集合。开始时,S中只有源点v0。我们先找出整个图中与源顶点v0直连的一条最短路径,将该路径的另一顶点加入S。这里有一个规则:假设B为尚未找出最短路径的顶点,则B的最短路径要么为与源点v0直连的一条路径,要么为S中的某条路径L与L到B的长度之和。理解了这一点之后,我们接下来在V-S中再去找下一条与v0直连的最短路径,并与第二种情况相比较,即可求出v0到B的最短路径。如此重复直到S包含所有顶点求解完毕。

算法所用辅助元素

       我们需要一个数组D[n]来存储最短路径(n 为图的顶点数)。先设它的各元素的初值为上面说的第一种情况,即D[i]代表源点v0到 i 顶点的直连路径长度(即为arcs[v][i]),若不直连其值则为无穷大,即先默认所有顶点的最短路径都为第一种情况。同时还需要一个boolean类型的数组Finish[n]代表各顶点是否已经找到了最短路径(即是否被移入S集合)。

代码示例(便于理解,引用严蔚敏著清华大学出版的数据结构一书代码)

       注:要点:P[v]是一个数组,它的各个分量中值为true的即为最短路径。最终的最短路径是一步步比较求出的,不是经过一次比较就可以得出

void ShortestPath(MGraph G,int v0,PathMatrix &P,ShortPathTable &D){
     //用Dijkstra算法求有向网G的v0顶点到其余顶点v的最短路径P[v]及其带权长度D[V]。
     //若P[v][w]为true,则w是从v0到v当前求得最短路径上的顶点。(注意此数组的理解,它表达从源点v0到v的路径是否包含w)
     //final[v]为TRUE当且仅当v∈S,即已经求得从v0到v的最短路径。
     for(v=0;v<G.vexnum;++v){
         final[v]=FALSE;
         D[v]=G.arcs[v0][v];  //D[v]的初态为源点与各顶点的直连路径长度,若没有直连则为无穷大
         for(w=0;w<G.vexnum;++w){  //设空路径:P[v]的初态为:没有任何顶点是其他顶点的最短路径上的点
             P[v][w]=FALSE;
         }
         if(D[v]<INFINITY){  //如果当前顶点与源点直连,那么源点和当前顶点是当前顶点到源点最短路径上的点
              P[v][v0]=TRUE;
              P[v][v]=TRUE;
         }
     }
     D[v0]=0;final[v0]=TRUE;  //初始化,v0源点属于S集合
     //开始主循环,每次求得v0到某个v顶点的最短路径,并加v到S集合
     for(i=1;i<G.vexnum;++i){  //循环其余G.vexnum-1个顶点循环1
          min=INFINITY;  //当前所知离v0顶点的最近距离,是个用于比较的变量
          for(w=0;w<G.vexnum;++w){  //找出剩下的顶点中的一条最短路径循环2
               if(!final[w]){  //w顶点在V-S中
                     if(D[w]<min){
                          v=w;
                          min=D[w];  //w顶点离v0顶点更近
                     }
               }
        }
          final[v]=TRUE;  //离v0顶点最近的v加入S集合
          for(w=0;w<G.vexnum;++w){  //更新当前最短路径及距离:使用循环2得到的一条最短路径重构D[v]数组,
          //当循环1进行完时,已使用每个最短路径重构数组D[v],所以得到了真正最短的最短路径
               if(!final[w]&&(min+G.arcs[v][w]<D[w])){  //修改D[w]和P[w],w∈V-S
                      D[w]=min+G.arcs[v][w];  //替换路径长度
                      P[w]=P[v];  //替换路径,P[v]数组是已经求知的路径
                      P[w][w]=TRUE;           //P[w]=P[v]+P[w]
               }
          }
      }
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值