迪杰斯特拉算法
一、图的某个顶点到另一顶点的最短路径算法
- 核心点1:
顶点与顶点之间,权值不能是负数。
- 核心点2:每次
取起点
到其它所有顶点
路径权值最小的点
,加入到确认列表
中。(一次排序操作
)
如下图所示,求顶点A到顶点F的最短路径。
- 需要申请2个列表:
确认列表{A}
待确认列表{B、C、D、E、F}
下图表示从A
点出发,到B、C、D、E、F
个点的距离。
取出本次路径权值最小的点:C
因为本次求出的是A点
到所有点的权值
,在所有点的权值中取出了最小权值点
,那么就可以确认:从A点到C点的距离,最短的路径就是AC=2
这一个结论很重要,因为根据这个结论,我们可以确认:无法再找出任何一条路径,使得从A点到C点,能比AC还要短
ABC=5+2=7
ADC=∞+4=∞
AEC=∞+3=∞
AFC=∞+∞=∞
所以AC
就是A点到C点
的最短路径
。那么C点就可以从待确认列表,转移到确认列表中
。
此时的列表信息:
确认列表{A、C}
待确认列表{B、D、E、F}
接着计算C点
到B、D、E、F
,哪个路径权值是最小的,算出下一个加入确认列表的节点
。
一直循环迭代,直到F点被加入到确认列表
中。
二、为什么提出两个核心点?
1、假设如果存在负权值的话,例如下图:BC路径的权值是-4。
那么同样的例子,从A点
出发到C点
,会找到一条路径ABC,ABC它的权值=5+(-4)=1
,比AC路径=2
的权值更小
。也就是说ABC才是A点到C点的最短路径
。这会使得我们原本将C点从待确认列表加入到确认列表
,这一操作是错误的。那么整个算法也就被推翻了,所以路径的权值不能是负数。
2、为什么下一个加入确认列表的点,是A点到其它所有顶点路径的最小值?
假设不是取出所有路径权值最小的那个点
,比如我们取B点
加入到确认列表,那么AB路径5
。根据规则,很明显我们能找到一条ACB路径
比AB路径
的权值更小。ACB权值4
,小于AB路径的权值5。所以B顶点不能从待确认列表移动到确认列表中。
三、实际用例
- 游戏中的路点寻路功能
总结
迪杰斯特拉本质是一个排序算法
。在第一轮的计算中,排序了A点到其它所有顶点的距离:
AB、AC、AD、AE、AF,然后从排序结果中选取了最小权值的点
。那么就表示从A点出发到该顶点的路径,绝对是最小的
。我们无法再找出一条路径,其权值比AC还小。