最短路

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

最短路

    典型用途:交通网络的问题——从甲地到乙地之间是否有公路连通?在有多条通路的情况下,哪一条路最短?
 
    交通网络用有向网来表示:顶点——表示城市,弧——表示两个城市有路连通,弧上的权值——表示两城市之间的距离、交通费或途中所花费的时间等。
    如何能够使一个城市到另一个城市的运输时间最短或运费最省?这就是一个求两座城市间的最短路径问题。
    问题抽象:在有向网中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 为止。

算法实现:


      void ShortestPath_DIJ(MGraph G,int v0,PathMatrix &P,ShortPathTable &D)
      { // 用Dijkstra算法求有向网 G 的 v0 顶点到其余顶点v的最短路径P[v]及带权长度D[v]。
          // 若P[v][w]为TRUE,则 w 是从 v0 到 v 当前求得最短路径上的顶点。  P是存放最短路径的矩阵,经过顶点变成TRUE
          // final[v]为TRUE当且仅当 v∈S,即已经求得从v0到v的最短路径。
          int v,w,i,j,min;
          Status final[MAX_VERTEX_NUM];
          for(v = 0 ;v < G.vexnum ;++v)
          {
              final[v] = FALSE;
              D[v] = G.arcs[v0][v].adj;        //将顶点数组中下标对应是 v0 和 v的距离给了D[v]
              for(w = 0;w < G.vexnum; ++w)
                  P[v][w] = FALSE;            //设空路径
              if(D[v] < INFINITY)
              {
                  P[v][v0] = TRUE;
                  P[v][v] = TRUE;
              }
          }
          D[v0]=0;
          final[v0]= TRUE; /* 初始化,v0顶点属于S集 */
          for(i = 1;i < G.vexnum; ++i) /* 其余G.vexnum-1个顶点 */
          { /* 开始主循环,每次求得v0到某个v顶点的最短路径,并加v到S集 */
              min = INFINITY; /* 当前所知离v0顶点的最近距离 */
              for(w = 0;w < G.vexnum; ++w)
                  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) /* 更新当前最短路径及距离 */
                      {
                          if(!final[w] && min < INFINITY && G.arcs[v][w].adj < INFINITY && (min + G.arcs[v][w].adj < D[w]))
                          { /* 修改D[w]和P[w],w∈V-S */
                              D[w] = min + G.arcs[v][w].adj;
                              for(j = 0;j < G.vexnum;++j)
                                  P[w][j] = P[v][j];
                              P[w][w] = TRUE;
                          }
                      }
          }
      }
  
 

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

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

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

作者其他文章

评论(0

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

    全部回复

    上滑加载中

    设置昵称

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

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

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