A*算法在求最短路上的应用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了A*算法在求最短路上的应用相关的知识,希望对你有一定的参考价值。

在学习A*算法之前,首先回忆一下一个非常经典的单源最短路算法Dijkstra

1)维护一个表dist,储存当前求出的各点到S的距离

2)取出dist表中的最小值(显然这个过程是可以用堆优化的),并用该最小值对其他各点的dist值做松弛更新

3)重复2)过程,直到取出的最小值对应节点为T

 

这里其实无形中也用到了接下来即将讲到的open表和close表的概念

open表储存的是待扩展的点,一定程度上对应Dijkstra中的list

close表中储存的是已经扩展过的点,以防出现重复

 

那么接下来谈谈A*算法在Dijkstra算法的基础上做了什

让我们回忆一下,多源最短路算法求出来的结果是什么,其实远远超出了我们的所需,我们最终得到的dist,是S到所有点的最短路距离。

然而当我们只需要S到T的最短路时,我们为什么需要去扩展那些我们没有必要扩展的点,哪怕它对应当前最小的dist?最小的dist又不一定会对S到T的最短路求解有必然的帮助。

所以我们需要引入一个评估函数

            f(p)=h(p)+g(p)

其中, g(p)表示S到p的实际最短距离,h(p)表示p到T的估计距离

g(p)是容易解决的,因为当你对p开始进行评估时,说明它的dist是当前最小,毫无疑问它当前的dist就是g(p)

h(p)取决于问题设定,视情况而定,一般设为p到T的曼哈顿距离或欧几里得距离(栅格化地图中前者更常用)

当你发现,f(p)甚至比当前T的dist还要大,那么根本没有必要对p进行拓展。假装自己扩展过了,将p打入close表的冷宫吧!

这里有一个前提,h(p)估算出的距离必须小于或等于p到T的实际最短距离,这一点比较显然,却是A*算法优化的基础(其实就是一个很基本的搜索剪枝的思想)

先给出A*的流程

1)将起点S放入open表中

2)对open表中dist最小的相邻节点进行评估,评估不合格则直接放入close表(孩子你没救了,洗洗睡吧

  否则进行拓展,将该点放入open表待扩展(少侠有前途,我钦点看好你

  扩展以后的点,也放入close表(该干的都干了,可以卸甲归田了

3)close表中出现了T!那啥也别说了,算法结束

如果需要记录路径的话,只要记录一下某个点是从哪个点扩展而来的,记录一下父节点即可。

 

最后思考一下为什么A*算法中这么强调open表

因为A*算法利用评估函数力求缩减扩展的次数,但Dijkstra一开始就是冲着把所有点扩展一遍去的,因而不需要open表(因为它的open表默认包含了所有点)

但A*则是在评估以后再判断是否放入open表中扩展,这就是优化所在。

 

以上是关于A*算法在求最短路上的应用的主要内容,如果未能解决你的问题,请参考以下文章

贪心算法

疯子的算法总结(四)贪心算法

用Dijkstra算法求最短路径

Dijkstra算法求单源最短路

求最短路径问题 送货郎问题

算法学习:费用流