Dijkstra算法求最短路径
1.什么是 Dijkstra 算法(标号法)?
Dijkstra 算法用于在一个带权有向图(通常权值非负)中,从指定的起点出发,求出该起点到图中所有其他顶点的最短路径。
“标号法”这个名字来源于它的操作方式:算法过程中,每个顶点都会被赋予一个标号。
2.实例设定
- T 标号(Temporary Label,临时标号):表示从起点到该点的暂时的最短路径长度估计值。随着算法进行,T 标号会不断变小(被修正)。
- P 标号(Permanent Label,永久标号):表示从起点到该点的真正的最短路径长度已经找到了,不再改变。一旦一个顶点获得 P 标号,它就相当于被“确定”了。
假设我们有如下所示的带权有向图,设起点为V1,我们需要求V1到其他所有点的最短路径:

(注意:如果两点之间没有直接连线,可以理解为权重无穷大 ∞)
图的边及权重(邻接关系):
- V1 → V2 (权重1)
- V1 → V3 (权重4)
- V2 → V3 (权重2)
- V2 → V4 (权重5)
- V2 → V5 (权重10)
- V3 → V4 (权重1)
- V4 → V5 (权重3)
3.算法详细步骤演示
初始状态:
- 起点V1:设为P标号值为 0。记作P(V1) = 0。
- 其他所有点(V2, V3, V4, V5):全部设为T标号,初始值为∞
- 前驱节点:用于记录路径,初始为空。
第1轮迭代:从V1出发
1.修改T标号
我们要检查刚刚获得P标号的点(现在是V1)的所有邻居。 计算方法:新T标号 = 起点P值 + 边的权重
- 邻居V2:
- 当前T(V2) = ∞
- 计算新路径:P(V1) + Weight(V1, V2) = 0 + 1 = 1
- 1 < ∞,所以更新T(V2) = 1。
- 邻居V3:
- 当前T(V3) = ∞
- 计算新路径:P(V1) + Weight(V1, V3) = 0 + 4 = 4
- 4 < ∞,所以更新T(V3) = 4。
2.确定P标号
在所有 T 标号中寻找最小值:
- T(V2) = 1
- T(V3) = 4
- T(V4) = ∞
- T(V5) = ∞
最小值是 1(对应的点是V2)。 所以,将V2的T标号改为P标号:P(V2) = 1。 记录路径:V1 → V2。
当前状态:P(V1) = 0, P(V2) = 1。其他T(V3) = 4, T(V4) = ∞, T(V5) = ∞。
第2轮迭代:从V2出发
1.修改T标号
我们要检查新获得P标号的点(V2)的所有邻居。 注意:V2连接着V3, V4, V5
- 邻居V3:
- 当前T(V3) = 4
- 计算新路径:P(V2) + Weight(V2, V3) = 1 + 2 = 3
- 3 < 4,我们发现这条路更短,所以更新T(V3) = 3。
- (这意味着路径V1 → V2 → V3比V1 → V3更短)
- 邻居V4:
- 当前T(V4) = ∞
- 计算新路径:P(V2) + Weight(V2, V4) = 1 + 5 = 6
- 6 < ∞,所以更新T(V4) = 6。
- 邻居V5:
- 当前T(V5) = ∞
- 计算新路径:P(V2) + Weight(V2, V5) = 1 + 10 = 11
- 11 < ∞,所以更新T(V5) = 11。
2.确定P标号
在所有 T 标号中寻找最小值:
- T(V3) = 3(刚刚更新的)
- T(V4) = 6
- T(V5) = 11
最小值是3(对应的点是V3)。 所以,将V3的T标号改为P标号:P(V3) = 3。 记录路径:V1 → V2 → V3。
当前状态:P(V1) = 0, P(V2) = 1, P(V3) = 3。其他T(V4) = 6, T(V5) = 11。
第3轮迭代:从V3出发
1.修改T标号
检查新获得P标号的点(V3)的所有邻居。 注意:V3连接着V4
- 邻居V4:
- 当前T(V4) = 6
- 计算新路径:P(V3) + Weight(V3, V4) = 3 + 1 = 4
- 4 < 6,我们发现这条路更短,所以更新T(V4) = 4。
- (这意味着路径V1 → V2 → V3 → V4比V1 → V2 → V4更短)
2.确定P标号
在所有 T 标号中寻找最小值:
- T(V4) = 4(刚刚更新的)
- T(V5) = 11
最小值是4(对应的点是V4)。 所以,将V4的T标号改为P标号:P(V4) = 4。 记录路径:V1 → V2 → V3 → V4。
当前状态:P(V1) = 0, P(V2) = 1, P(V3) = 3, P(V4) = 4。其他T(V5) = 11。
第4轮迭代:从V4出发
1.修改T标号
检查新获得P标号的点(V4)的所有邻居。 注意:V3连接着V5
- 邻居V5:
- 当前T(V5) = 11
- 计算新路径:P(V4) + Weight(V4, V5) = 4 + 3 = 7
- 7 < 11,我们发现这条路更短,所以更新T(V5) = 7。
- (这意味着路径V1 → V2 → V3 → V4 → V5比V1 → V2 → V5更短)
2.确定P标号
在所有 T 标号中寻找最小值:
- T(V5) = 7(刚刚更新的)
最小值是7(对应的点是V5)。 所以,将V5的T标号改为P标号:P(V5) = 7。 记录路径:V1 → V2 → V3 → V4 → V5。
当前状态:所有定点都已获得P标号,算法结束。
4.最终结果汇总
通过上述每步的运算,我们得出了从起点V1到所有其他点的最短路径长度及具体路线:
| 目标点 | 最短距离 | 最短路径 |
|---|---|---|
| V1 | 0 | V1(起点) |
| V2 | 1 | V1 → V2 |
| V3 | 3 | V1 → V2 → V3 |
| V4 | 4 | V1 → V2 → V3 → V4 |
| V5 | 7 | V1 → V2 → V3 → V4 → V5 |
5.总结
如果在考试或做题中遇到此类问题,只需记住以下核心步骤: 1. 选P:在所有 T 标号中选一个最小的,改为 P 标号。 2. 改 T:以这个新 P 点为跳板,看它通向哪里。 - 公式 : 新长度 = 新P点值 + 边的权重 - 比较 : 如果新长度 < 邻居当前的T标号,则更新邻居的 T 标号。 3. 循环:重复以上两步,直到所有点都变成 P 标号。
这就是 Dijkstra 标号法的全部过程。
