迪杰斯特拉算法解析

一.理论基础

迪杰斯特拉算法(下文简称DJ算法)是理论基础是一条简单的定理:

下一条最短路径或者是弧(V0, Vx),或者是中间经过S中的某些顶点,而后到达Vx的路径。(S是最短路径已知的顶点集合)

(为了准确的描述定理,这里就直接摘抄了。。至于它对不对,嗯,据说反证法可证之)很明显这是一个递推算法:反复求下一条,直至没有下一条为止。

二.问题分析

现有加权有向图如下:

求从V0出发,到达其它各个顶点的最短路径。

首先为了把它转换成便于描述的数学形式,得写出对应的邻接矩阵(x表示不可达):

0 50 10 x 45 x
x 0 15 x 10 x
20 x 0 15 x x
x 20 x 0 35 x
x x x 30 0 x
x x x 3 x 0

分析定理可以得出:目前S集合中只有1个顶点:V0(V0到自身的肯定是最短路径),除了S集合这个辅助空间外,我们还需要:

  • V集合:最短路径未知的顶点组成的集合,即S集合的补集
  • path[]:记录最短路径,用来显示结果
  • dist[]:记录路径长度,作用同上
  • Vx:记录下一个顶点

准备工作结束,可以开始求解了

三.求解过程

0.初始状态

dist[]初始化为V0到各个顶点的直接距离(x表示不可直达),path[]初始化为对应的路径,不可直达的记作NULL,选取V集合中dist值最小的顶点V2作为下一个顶点(定理中的Vx)

1.第1步

把V2加入S集合,我们多了一个中转站V2,接下来更新dist[],看借助V2中转的话是不是更短,根据计算结果更新dist[]和path[],把更短的路径长度和对应路径放进去,V集合中dist值最小的V3作为下一个顶点

2.第2-5步

继续选取下一个顶点,直至V集合中没有可选顶点为止

四.总结

DJ算法过程非常简单:

  1. 确定S中的第一个点(也就是源点V0);
  2. 根据定理递推(一直找最短,并试图借助最短中转)

算法思路本身不难,当初看不明白是因为被具体的伪代码实现绕进去了,所以学习算法应该关注思路而不是具体实现,尤其是伪代码算法,通常会随意声明一些奇怪的数据结构,却不解释为什么需要这些辅助空间,比如本例中,S集合和V集合只需要有一个即可,path[]和dist[]也可以用结构体清晰的表示出来,但伪代码中零零散散的全都用到了,过多的辅助空间反而妨碍了理解算法本身。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*

code