
Dijkstra算法求最短路径
迪杰斯特拉(Dijkstra)
引子[摘自:最短路径算法-迪杰斯特拉(Dijkstra)算法 - 知乎 (zhihu.com)]
最短路径算法-迪杰斯特拉(Dijkstra)算法
迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径。
它的主要特点是以起始点为中心向外层层扩展(广度优先遍历思想),直到扩展到终点为止。
基本思想
- 通过Dijkstra计算图G中的最短路径时,需要指定一个起点D(即从顶点D开始计算)。
- 此外,引进两个数组S和U。S的作用是记录已求出最短路径的顶点(以及相应的最短路径长度),而U则是记录还未求出最短路径的顶点(以及该顶点到起点D的距离)。
- 初始时,数组S中只有起点D;数组U中是除起点D之外的顶点,并且数组U中记录各顶点到起点D的距离。如果顶点与起点D不相邻,距离为无穷大。
- 然后,从数组U中找出路径最短的顶点K,并将其加入到数组S中;同时,从数组U中移除顶点K。接着,更新数组U中的各顶点到起点D的距离。
- 重复第4步操作,直到遍历完所有顶点。
我的思考
图中我用绿色标记已经存入S[]中的节点,黄色标记已经计算过某条路径的节点(不一定是最小值)即U[]中非无穷大的节点, “*”代表
至此,我们凭什么认为C->D已经找到了最小路径呢?
证明: |
---|
C->D由(N_d + 1)条路径组成 |
---|
对于C->E->D的路径 |
总路径长度应小于 3 |
在其他C->D路径中 若与D相连的路径没有小于 3 的 此处得证 |
在其他C->D路径中 若与D相连的路径有小于 3 的 |
与第一步 选出最短节点操作相悖 该情况不存在 此处得证 |
同样的问题,我们凭什么认为E->D已经找到了最小路径呢?
证明: |
---|
对于 E->C->D 和 E->D 已完成对比 大小关系已确定 |
---|
E->F->C 一定大于等于 E->C |
同理 E->G->F->C 一定大于等于 E->F->C 大于等于 E->C |
因此E->为最小路径 |
还是那个问题,我们凭什么认为F->E->D已经找到了最小路径呢?
证明: |
---|
F->C->E->D与F->E->C->D均大于等于F->C->D和F->E->D |
---|
对于F->C->D和F->E->D 已完成比较 |
后续的步骤:
规律总结
先回到这一步 |
---|
对于E 非全绿路径路径数一定多于或等于全绿路径 |
---|
因此非全绿路径的路径长一定大于或等于全绿路径的路径长 |
而对于全绿路径,每个路径都会在之前的绿节点确认时进行了充分的对比 |
总结
Dijkstra算法始终在求解一个问题:
|—-|
|接下来,哪一个顶点会是下一个被找出最短路径的节点?|
代码实现
参考实现方法:路径规划求最短路径——Dijkstra算法一步一步讲清楚(附代码/可执行)_dijkstra算法步骤-CSDN博客
我使用了一个二维数组weightTable来存储顶点之间的关系
另一个二维数组connectionTable来记录各个顶点是否相互连接
一个结构体数组DistanceTable来代替传统的S[]和U[]两个数组,用来记录某个顶点是否已经是确定状态(已经达到最小值,也就是上文途中的绿色节点)和当前最小值
十六进制数0x7fffffff是int类型的最大值,用于表示无穷大
代码:
Dijkstra.hpp |
---|
1 |
|
main.cpp |
---|
1 |
|
以上代码托管于:我的github仓库