算法介绍
迪杰斯特拉算法是由荷兰计算机科学家在1956年发现的算法,此算法使用类似广度优先搜索的方法解决了带权图的单源最短路径问题。它是一个贪心算法。
核心思想
1.选定一个点,这个点满足两个条件:①未被选过,②距离最短
2. 对于这个点的所有邻近点去尝试松弛
算法步骤
首先,可以设置两个集合分别是A和B,A用来存放已经求出最短路径的点,B用来存放还未计算出最短路径的点
从图中任选一点来解题,假设我们将源点source选择在” 0 "这个点。一开始所有点到达源点0的距离我们假设为∞,代表不可达。源点0到自己本身的距离为0,初始化如下:此时A集合为:{0},B集合为:{1,2,3,4,5,6}
第一步:从0点开始,更新和0邻接的所有点的距离,此时,因为与0邻接的有1和2,并且到这两个点的距离,小于原来的∞距离,所以要将这两个点到0的距离都进行更新如下图,
第二步:从B集合里面选择一个点加入A集合,这个点要满足距离0点的距离最短,因此我们选择2这个点添加到集合A,此时集合A变为:{0,2},集合B变为:{1,3,4,5,6},如下图
第三步:选择刚刚加入的这个2点,更新所有与2点邻接的点,因为与2邻接的点有3和5,并且这两个点到0点的距离小于原来它们到0点的距离∞
第四步:从B集合里面选择1这点加入到集合A中,因为1这个点在B集合中距离0最近,如下图,此时A集合变成:{0,1,2},B集合变成:{3,4,5,6}
第五步:选择刚刚加入的1这个点,更新1所有的邻接点,它的邻接点有3和4,因为此刻从0到3的距离为6,小于原来0到3的距离8,因此这个时候到6的距离更新为6(5+1),此时0到4的距离被更新为11
第六步:从B集合中选择一个距离0点最小距离的点,加入集合A,此时可以选择3这个点,因为3这个点在B集合里面距离0点最近,此时集合A变为:{0,1,2,3},集合B变为:{4,5,6}
第七步:从刚刚选择的这个3点出发,更新3所有的邻接点,3的邻接点有4和5,原来4到0的距离为11,3加进来之后,4到0的距离为7,小于原来的11,所以要更新,原来5到0的距离为10,3加进来之后,5到0的距离为8,所以也要更新
第八步:从B集合中选择一个距离0点最小距离的点,因此我们选择4点,因为此时4这个点距离0点最近,为7,于是集合A变成:{0,1,2,3,4},集合B变成:{5,6}
第九步:从刚刚选择的点4出发,更新它的所有邻接点,4的邻接点有6,原来6到0的距离为∞,此时4加进来之后6到0的距离变为14,它小于∞,因此要更新6到0的距离,更新为11
第十步:从集合B中选择一个距离0点最短距离的点,加入集合,此时我们可以选择5这个点,因为这个时候它在B集合中是距离0点最近的点,于是集合A变为:{0,1,2,3,4,5},集合B变为{6}
第11步:从刚刚选择的这个点出发,也就是从点5出发,更新它所有的邻接点,此时5的邻接点为6,原来0到6的距离为14,此时点5加进来之后,0到6的距离变为了11,因此需要更新0到6的距离
第12步:因为B集合只剩下一个点,为点6,直接将其加入A集合即可,此时A集合变为:{0,1,2,3,4,5,6},B集合变为:{ },至此,从0点到其它所有点的最短路径已经算出来了,为下图
基本思想
- 通过Dijkstra计算图G中的最短路径时,需要指定一个起点D(即从顶点D开始计算)。
- 此外,引进两个数组S和U。S的作用是记录已求出最短路径的顶点(以及相应的最短路径长度),而U则是记录还未求出最短路径的顶点(以及该顶点到起点D的距离)。
- 初始时,数组S中只有起点D;数组U中是除起点D之外的顶点,并且数组U中记录各顶点到起点D的距离。如果顶点与起点D不相邻,距离为无穷大。
- 然后,从数组U中找出路径最短的顶点K,并将其加入到数组S中;同时,从数组U中移除顶点K。接着,更新数组U中的各顶点到起点D的距离。
- 重复第4步操作,直到遍历完所有顶点。
以上图为例,来对迪杰斯特拉进行算法演示(以顶点D为起点)