Dijkstra最短路径算法初探

数据源:

一组顶点Vi(i=1~n),顶点间通路(Vi, Vj), 通路的距离dis(i,j)

 

目标:

任意给定一组起点s, 终点d, 计算s==》d之间的最短距离, 并给出通路。

 

算法输入数据举例如下:

4            //四个顶点

4            //四个通路

1 2 4      //顶点1到顶点2存在距离为4的通路

1 3 5      //…

2 4 3      //…

3 4 1      //顶点3到顶点4存在距离为1的通路

1 4         //求顶点1到顶点4的最短距离

 

Dijkstra算法可能的思路:

1.s==》d之间的最短距离为dis_min(s,d),设在s==》d之间可以找到k(k一般为无穷大)条通路,每条通路距离为dis_m(s,d) m=1~k,显然dis_min(s,d) = min{dis_m(s,d) m=1~k}。如果,我们选定了一条s==》d之间的通路,我们如何确定它就是最短的呢?这个不好论证,因此我们需要换一种方法来论证:扩大dis_min(s,d)的比较范围和论证范围。

2.s==》n个点之间的无穷个路径的无穷个距离排序后为0dis_max,显然0s==》s的最短距离,那么哪一个是s==》d之间的最短距离呢?或者说:哪一个是s==》任意点之间的最短距离呢?

3.我们从0dis_max中间挨个选取,首先0被选出(因为是s==》s的最短距离),而后dis_1被选出(因为是s到它附近最近一个点的距离,例如:s周边有j个点与s直接相连,这样就有j个距离,显然在j个距离中必然存在一个最小值dis_xdis_x不可能被突破,有dis_1== dis_x),而后是dis_2被选出?似乎难以判断。但从dis_1的选出可以看到一种不完整的选择规则:我们可以很容易地选出与s最近的点,但是如何选出与s第二近的点?

4.想想第二步中dis_0 = 0被选出的过程,以及dis_1被选出的过程,实际上,找到下一个点的方法已经出来了:将dis_1连接的点(设为s_1)加入到源点s集合中,考察与ss_1直接连接的所有点,计算它们与s的距离,选择最短的路径对应的点s_2加入源点集。这样我们就选出了与s最近的三个点,继续查找下去就会获得sd的最短路径。

另注:

一个逆向结论:设s==》s_1==》s_2==》s_3==》==》s_n==》ds==》d的最近路径,那么s==》s_1==》s_2==》s_3==》==》s_n一定是s==》s_n的最近路径,否则就可以用s==》s_n的最近路径来替换s==》d的那段路径,这样就与假设不符了。但是反过来,由s==》s_n是最近路径推论s==》s_n==》d是最短路径是不行的,因为可能存在s==》s_n==》s_a==》d更近。

以上逆向结论对应的顺向推导结论只能这样:找到所有源点集的直接相连点(不能在源点集中找,因为这样会形成无效环路),计算这些通路的距离,将最短的通路所关联的点加入到源点集。

 

数据结构:

1.

2.两点间联通路径及其方向、距离

3.close表、源点集(源路径集。每个源点记载到s点的距离及路径)

4.open表、等待比较的路径集(以路径长度排序)

 

算法:

从点集中将s点移入close表。

whileclose表中没有找到d点)

{

       close表中最近加入的源点的新路径加入open表。

       open表将最短的一条移入close表。从open表中删除尾段为对应新源点的其它路径。

}

 

这个Dijkstra算法,我看过数遍,但至今仍然觉得我没有真正理解它的精髓所在。上次得力于一位朋友给我讲解了一下基本Dijkstra算法及其变化版本,感触最深的是其优雅的适应算法的数据结构。数据结构依赖于算法的确立,算法依赖于源数据和目标的确立,同时数据结构和算法两者又相辅相成。这次花时间用自己的一种方法从特殊的角度描述Dijkstra算法,试图将Dijkstra算法叙说的比较触及根源,但自我感觉还是不够,或许还是我的数学底子太差,描述问题不够清晰条理。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值