最短路

举报
兔老大 发表于 2021/04/20 01:29:42 2021/04/20
【摘要】 最短路     典型用途:交通网络的问题——从甲地到乙地之间是否有公路连通?在有多条通路的情况下,哪一条路最短?       交通网络用有向网来表示:顶点——表示城市,弧——表示两个城市有路连通,弧上的权值——表示两城市之间的距离、交通费或途中所花费的时间等。   ...

最短路

    典型用途:交通网络的问题——从甲地到乙地之间是否有公路连通?在有多条通路的情况下,哪一条路最短?
 
    交通网络用有向网来表示:顶点——表示城市,弧——表示两个城市有路连通,弧上的权值——表示两城市之间的距离、交通费或途中所花费的时间等。
    如何能够使一个城市到另一个城市的运输时间最短或运费最省?这就是一个求两座城市间的最短路径问题。
    问题抽象:在有向网中A点(源点)到达B点(终点)的多条路径中,寻找一条各边权值之和最小的路径,即最短路径。最短路径与最小生成树不同,路径上不一定包含n个顶点,也不一定包含n - 1条边。
   常见最短路径问题:单源点最短路径、所有顶点间的最短路径
(1)如何求得单源点最短路径?
    穷举法:将源点到终点的所有路径都列出来,然后在其中选最短的一条。但是,当路径特别多时,特别麻烦;没有规律可循。
    迪杰斯特拉(Dijkstra)算法:按路径长度递增次序产生各顶点的最短路径。
路径长度最短的最短路径的特点:
    在此路径上,必定只含一条弧 <v_0, v_1>,且其权值最小。由此,只要在所有从源点出发的弧中查找权值最小者。
下一条路径长度次短的最短路径的特点:
①、直接从源点到v_2<v_0, v_2>(只含一条弧);
②、从源点经过顶点v_1,再到达v_2<v_0, v_1>,<v_1, v_2>(由两条弧组成)
再下一条路径长度次短的最短路径的特点:
    有以下四种情况:
    ①、直接从源点到v_3<v_0, v_3>(由一条弧组成);
    ②、从源点经过顶点v_1,再到达v_3<v_0, v_1>,<v_1, v_3>(由两条弧组成);
    ③、从源点经过顶点v_2,再到达v_3<v_0, v_2>,<v_2, v_3>(由两条弧组成);
    ④、从源点经过顶点v_1  ,v_2,再到达v_3<v_0, v_1>,<v_1, v_2>,<v_2, v_3>(由三条弧组成);
其余最短路径的特点:    
    ①、直接从源点到v_i<v_0, v_i>(只含一条弧);
    ②、从源点经过已求得的最短路径上的顶点,再到达v_i(含有多条弧)。
Dijkstra算法步骤:
    初始时令S={v_0},  T={其余顶点}。T中顶点对应的距离值用辅助数组D存放。
    D[i]初值:若<v_0, v_i>存在,则为其权值;否则为∞。 
    从T中选取一个其距离值最小的顶点v_j,加入S。对T中顶点的距离值进行修改:若加进v_j作中间顶点,从v_0到v_i的距离值比不加 vj 的路径要短,则修改此距离值。
    重复上述步骤,直到 S = V 为止。

算法实现:


  
  1. void ShortestPath_DIJ(MGraph G,int v0,PathMatrix &P,ShortPathTable &D)
  2. { // 用Dijkstra算法求有向网 G 的 v0 顶点到其余顶点v的最短路径P[v]及带权长度D[v]。
  3.     // 若P[v][w]为TRUE,则 w 是从 v0 到 v 当前求得最短路径上的顶点。  P是存放最短路径的矩阵,经过顶点变成TRUE
  4.     // final[v]为TRUE当且仅当 v∈S,即已经求得从v0到v的最短路径。
  5.     int v,w,i,j,min;
  6.     Status final[MAX_VERTEX_NUM];
  7.     for(v = 0 ;v < G.vexnum ;++v)
  8.     {
  9.         final[v] = FALSE;
  10.         D[v] = G.arcs[v0][v].adj;        //将顶点数组中下标对应是 v0 和 v的距离给了D[v]
  11.         for(w = 0;w < G.vexnum; ++w)
  12.             P[v][w] = FALSE;            //设空路径
  13.         if(D[v] < INFINITY)
  14.         {
  15.             P[v][v0] = TRUE;
  16.             P[v][v] = TRUE;
  17.         }
  18.     }
  19.     D[v0]=0;
  20.     final[v0]= TRUE; /* 初始化,v0顶点属于S集 */
  21.     for(i = 1;i < G.vexnum; ++i) /* 其余G.vexnum-1个顶点 */
  22.     { /* 开始主循环,每次求得v0到某个v顶点的最短路径,并加v到S集 */
  23.         min = INFINITY; /* 当前所知离v0顶点的最近距离 */
  24.         for(w = 0;w < G.vexnum; ++w)
  25.             if(!final[w]) /* w顶点在V-S中 */
  26.                 if(D[w] < min)
  27.                 {
  28.                     v = w;
  29.                     min = D[w];
  30.                 } /* w顶点离v0顶点更近 */
  31.                 final[v] = TRUE; /* 离v0顶点最近的v加入S集 */
  32.                 for(w = 0;w < G.vexnum; ++w) /* 更新当前最短路径及距离 */
  33.                 {
  34.                     if(!final[w] && min < INFINITY && G.arcs[v][w].adj < INFINITY && (min + G.arcs[v][w].adj < D[w]))
  35.                     { /* 修改D[w]和P[w],w∈V-S */
  36.                         D[w] = min + G.arcs[v][w].adj;
  37.                         for(j = 0;j < G.vexnum;++j)
  38.                             P[w][j] = P[v][j];
  39.                         P[w][w] = TRUE;
  40.                     }
  41.                 }
  42.     }
  43. }

 

文章来源: fantianzuo.blog.csdn.net,作者:兔老大RabbitMQ,版权归原作者所有,如需转载,请联系作者。

原文链接:fantianzuo.blog.csdn.net/article/details/87823902

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。