数据结构之图(八)——最短路径问题

最短路径问题抽象

  • 典型用途:交通网络问题——从甲地到乙地是否有公路连通?在有许多条公路连通的情况下,哪一条最短?

    • 交通网络用有向网表示:
      顶点——表示地点
      ——表示两个地点有路连通
      弧上的权值——表示两地点之间的距离、交通费或途中所花费的时间的等。

      如何能够使一个地点到另一个地点的运输时间最短或运费最省?这就是一个求两个地点的最短路径问题
  • 问题抽象: 在有向网中A点(源点)到达B点(终点)的多条路径中,寻找一条各边权值之和最小的路径,即最短路径。
    最短路径与最小生成树不同,路径上不一定包含n个顶点,也不一定包含n-1条边。
    通常最短路径问题可分为以下两类:

    • 第一类:两点间最短路径
      在这里插入图片描述
      知道源点(v1)和终点(v7),找到一条最短路径(图中蓝色边)。

    • 第二类:某源点到其他各点最短路径
      在这里插入图片描述
      知道源点(v1),求到其他各顶点的最短路径(如表所示)。

  • 两种常用算法:

    • 单源最短路径(第一类问题)——Dijkstra算法
    • 所有结点间的最短路径(第二类问题)——Floyd算法


Dijkstra算法

  • 算法思路:

    • 1.把顶点集合V分成两组:
      • (1) S:已求出最短路径的顶点的集合
      • (2) T=V-S:尚未确定最短路径的顶点集合
    • 2.将T中顶点按最短路径递增的次序加入到S中,并要满足以下两个条件:
      • (1)从源点 v 0 v_0 v0到S中各顶点的最短路径长度都不大于从 v 0 v_0 v0到T中任何顶点的最短路径长度。
      • (2) 每个顶点对应一个距离值
        S中的顶点:从 v 0 v_0 v0到此顶点的最短路径长度
        T中的顶点:从 v 0 v_0 v0到此顶点的只包括S中顶点作中间顶点的最短路径长度。
  • 算法步骤:

    • 1.初始时,令 S = { v 0 } , T = { 其 余 顶 点 } S=\{v_0\},T=\{其余顶点\} S={v0},T={},T中顶点对应的距离值用辅助数组D存放。
      D[i]的初值: &lt; v 0 , v i &gt; &lt;v_0,v_i&gt; <v0,vi>存在,则为其权值;否则为 ∞ \infty
    • 2.从T中选取一个距离值最小的顶点 v j v_j vj,加入S。
      对T中顶点的距离值进行修改:若加进 v j v_j vj作中间顶点,从 v 0 v_0 v0 v i v_i vi的距离值比不加 v j v_j vj的路径要短,则修改此距离值。
    • 3.重复上述步骤,直至S=V为止。
  • 例子说明:
    1.初始状态如下图,此时, S = { v 0 } , T = { v 1 − v 6 } S=\{v_0\},T=\{v_1-v_6\} S={v0},T={v1v6}
    在这里插入图片描述
    在这里插入图片描述
    2.从T中找一个距离值最小的结点 v 2 v_2 v2加入到S集合中, S = { v 0 , v 2 } , T = { v 1 , v 3 − v 6 } S=\{v_0,v_2\},T=\{v_1,v_3-v_6\} S={v0,v2},T={v1,v3v6},修改距离值。
    在这里插入图片描述
    在这里插入图片描述
    3.从T中找一个距离值最小的结点 v 1 v_1 v1加入到S集合中, S = { v 0 , v 2 , v 1 } , T = { v 3 − v 6 } S=\{v_0,v_2,v_1\},T=\{v_3-v_6\} S={v0,v2,v1},T={v3v6},修改距离值。
    在这里插入图片描述
    在这里插入图片描述
    4.从T中找一个距离值最小的结点 v 3 v_3 v3加入到S集合中, S = { v 0 , v 2 , v 1 , v 3 } , T = { v 4 − v 6 } S=\{v_0,v_2,v_1,v_3\},T=\{v_4-v_6\} S={v0,v2,v1,v3},T={v4v6},修改距离值。
    在这里插入图片描述
    在这里插入图片描述
    5.从T中找一个距离值最小的结点 v 4 v_4 v4加入到S集合中, S = { v 0 , v 2 , v 1 , v 3 , v 4 } , T = { v 5 , v 6 } S=\{v_0,v_2,v_1,v_3,v_4\},T=\{v_5,v_6\} S={v0,v2,v1,v3,v4},T={v5,v6},修改距离值。
    在这里插入图片描述
    在这里插入图片描述
    6.从T中找一个距离值最小的结点 v 6 v_6 v6加入到S集合中, S = { v 0 , v 2 , v 1 , v 3 , v 4 , v 6 } , T = { v 5 } S=\{v_0,v_2,v_1,v_3,v_4,v_6\},T=\{v_5\} S={v0,v2,v1,v3,v4,v6},T={v5},修改距离值。
    在这里插入图片描述
    在这里插入图片描述
    6.从T中找一个距离值最小的结点 v 5 v_5 v5加入到S集合中, S = { v 0 , v 2 , v 1 , v 3 , v 4 , v 6 , v 5 } , T = { } S=\{v_0,v_2,v_1,v_3,v_4,v_6,v_5\},T=\{\} S={v0,v2,v1,v3,v4,v6,v5},T={},修改距离值。此时,S=V,结束。
    在这里插入图片描述
    在这里插入图片描述



Floyd算法

  • 算法思想:

    • 逐个顶点试探
    • v i v_i vi v j v_j vj的所有可能存在的路径中
    • 选出一条长度最短的路径
  • 算法步骤:

    • 初始时置一个n阶方阵,令其对角线元素为0,若存在弧 &lt; v i , v j &gt; &lt;v_i,v_j&gt; <vi,vj>,则对应元素为权值;否则为 ∞ \infty
    • 逐步试着在原直接路径中增加中间结点,若加入中间结点后路径变短,则修改之;否则,维持原值。所有顶点试探完毕,算法结束。
  • 例子说明:
    1.初始时,如下图,
    在这里插入图片描述
    2.加入结点A,进行试探,
    在这里插入图片描述
    3.加入结点B,进行试探,
    在这里插入图片描述
    4.加入结点C,进行试探,
    在这里插入图片描述
    5.此时,所有顶点试探完毕,算法结束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值