【专题】最短路径问题下的Dijkstra算法

一、问题引入

在任意一个简单带权图G=<V, E, W>v, u ∈ V中,求u, v之间的最短路径及距离的问题,该问题即为最短路径问题

二、算法讲解

1.1 算法内容

  1. l1 ← 0, p1 ← λ, lj ← +∞, pj ←λ , j = 2,3,4,…,n, P = {v1}, T = V - {V1}, k ← 1, t ← 1
    (λ: 表示为空)
  2. ∀ vj ∈ T ∧ (vk, vj) ∈ E;
    l ← min{lj, lk + wkj};
    l = lk + wij, 则令 lj ← l, pj ← vk
  3. li = min{ lj | vj ∈ T };
    P ← P∪{vi}, T ← T - {vi}, k ← i
  4. t ← t + 1
    t < n, 则转移至步骤2继续进行。

1.2 题例讲解

1.2.1 题例引入

Q: 求下图中结点u到结点v的最短路径
在这里插入图片描述

1.2.2 解答过程

【STEP-1】

  • 起点u进行画圈标号
    (即,表明已经找到了u到u的最短路径。)
  • 将其他结点用进行标记
    (即表明暂未找到u到其他结点的最短路径。)
  • 创建集合S,存储已经标号的顶点。

在集合S中的标号称为永久标号;集合S称为永久标号集

在这里插入图片描述

【STEP-2】

  • 找到当前永久标号集中的最后一个结点,即结点u;
  • 找到结点u相邻的所有结点,对这些结点使用 “[距离]([源头])” 的方法进行标记

[距离]([源头]) 标记法:

  • 距离:起始结点到当前结点的总距离。
  • 源头:当前结点的上一个结点,即当前结点是由哪一个结点引出的。
  • 在所有标记的结点中,找到路径最短的结点,并对其进行画圈标号
    (图中:结点a: 2(u); 结点c: 1(u)。则对结点c进行画圈标号。)
  • 新画圈标号的结点置于永久标号集末尾

在这里插入图片描述

【STEP-3】

  • 找到当前永久标号集的最后一个结点,即结点c;
  • 找到结点c所有相邻且未被画圈标号的结点,对其进行标记
    (图中:结点c相邻且未被画圈标号的结点为结点d,则结点d: 4(c))
  • 在所有标记的结点中,找到路径最短的结点,并对其进行画圈标号
    (图中:结点a: 2(u); 结点d: 4(c)。则对结点c进行画圈标号。)
  • 新画圈标号的结点置于永久标号集末尾

在这里插入图片描述

【STEP-4】

  • 找到当前永久标号集的最后一个结点,即结点a;
  • 找到结点a所有相邻且未被画圈标号的结点,对其进行标记
    (图中:结点a相邻且未被画圈标号的结点为结点b结点d;则结点d: [4(c),3(a)]min ⇒ 3(a);结点b: 5(a)。)

若一个结点出现多个标记,则选取总距离最小的标记进行保留,其余标记全部删去即可。

  • 在所有标记的结点中,找到路径最短的结点,并对其进行画圈标号
    (图中:结点b: 5(a); 结点d: 3(a)。则对结点d进行画圈标号。)
  • 新画圈标号的结点置于永久标号集末尾

在这里插入图片描述

【STEP-5】

  • 找到当前永久标号集的最后一个结点,即结点d;
  • 找到结点d所有相邻且未被画圈标号的结点,对其进行标记
    结点d相邻且未被画圈标号的结点为结点v;则结点v: 5(b)。)
    在这里插入图片描述
  • 在所有标记的结点中,找到路径最短的结点,并对其进行画圈标号
    (图中:结点v: 5(b); 结点b: 5(a)。两结点的路径相等,无最短路径结点。且此时,结点v是整体路径的终点,则直接对结点v进行画圈标号。)
  • 新画圈标号的结点置于永久标号集末尾

在这里插入图片描述

【STEP-6】

  • 通过回溯法来确定最短路径。

结点v开始往回找,找到起点结点u即可终止。

(图中:结点v的标记为 5(d),即由结点v找到结点d结点d的标记为 3(a),即由结点d找到结点a结点a的标记为 2(u),即由结点a找到结点u;结束。)

【STEP-7】
即上图的最短路径为:u→a→d→v
最短路长为:5.

三、实战练习

3.1 练习题目

Q:找出下图中,符合要求的最短路径并求出其路径长度。
(1) v0 → v3
(2) v0 → v4
(3) v0 → v5

在这里插入图片描述

3.2 解答过程

解答(1: v0 → v3):

  1. v0 画圈,S = { v0 }
  2. v0 相邻标记,v5: 100(v0); v4: 30(v0); v2: 10(v0);
    选择最小:v2
    v2 画圈,S = { v0, v2 }
  3. v2 相邻标记,v1: 15(v2); v3: 60(v2);
    选择最小:v4(v1中断,无意义,不考虑)
    v4 画圈,S = { v0, v2,v4 }
  4. v4 相邻标记,v5: [90(v4), 100(v0)]min ⇒ 90(v4); v3: [50(v4), 60(v2)]min ⇒ 50(v4);
    选择最小:v3
    v3 画圈,S = { v0, v2,v4,v3 }
  5. 回溯:v3 ← v4 ← v0
  6. 即 v0到v3的最短路径为:v0 → v4 → v3
    最短路长为:50

在这里插入图片描述

解答(2:v0 → v4):

  1. v0 画圈,S = { v0 }
  2. v0 相邻标记,v5: 100(v0); v4: 30(v0); v2: 10(v0);
    选择最小:v2
    v2 画圈,S = { v0, v2 }
  3. v2 相邻标记,v1: 15(v2); v3: 60(v2);
    选择最小:v4(v1中断,无意义,不考虑)
    v4 画圈,S = { v0, v2,v4 }
  4. 回溯:v4 ← v0
  5. 即 v0到v3的最短路径为:v0 → v4
    最短路长为:30

在这里插入图片描述

解答(3:v0 → v5):

  1. v0 画圈,S = { v0 }
  2. v0 相邻标记,v5: 100(v0); v4: 30(v0); v2: 10(v0);
    选择最小:v2
    v2 画圈,S = { v0, v2 }
  3. v2 相邻标记,v1: 15(v2); v3: 60(v2);
    选择最小:v4(v1中断,无意义,不考虑)
    v4 画圈,S = { v0, v2,v4 }
  4. v4 相邻标记,v5: [90(v4), 100(v0)]min ⇒ 90(v4); v3: [50(v4), 60(v2)]min ⇒ 50(v4);
    选择最小:v3
    v3 画圈,S = { v0, v2,v4,v3 }
  5. v3 相邻标记,v5: [90(v4), 60(v3)]min ⇒ 60(v3)
    选择最小:v5;
    v5 画圈,S = { v0, v2,v4,v3, v5 }
  6. 回溯:v5 ← v3 ← v4 ← v0
  7. 即 v0到v5的最短路径为:v0 → v4 → v3 → v5
    最短路长为:60

在上例中,不难发现:

  • 结点为a, b, c, d, e, f, g
  • 若a到g的最短路径为a→b→c→d→e→f→g
    • 则b到f的最短路径为b→c→d→e→f
    • 则a到e的最短路径为a→b→c→d→e
    • …………
  • 即在已有最短路径中进行相关截取,也可以获得其他结点间的最短路径。

—— writing by Pan Qifan(潘琦藩) ——

  • 18
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

向懒羊羊学习的大猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值