带启发的寻路算法
A*算法寻路算法的一种,它与Dijkstra、BFS不同。A*算法适用于二维平面地图上的寻路算法,而Dijkstra需要先将平面地图转化成带权的有向图。除此之外,Dijkstra只是做简单的广度优先搜索,搜索效率比较低,而A*算法利用地图上两个点之间的位置和距离信息进行高效的搜索。
首先介绍一下启发式搜索算法。 启发式搜索依赖于启发函数,也就是评估函数。评估函数的作用是根据起点和终点的位置和距离信息给出下一步需要搜索各个位置的评估值。而启发式可以利用各个位置的评估值:
- 选择评估值最高的位置进行下一步搜索
- 决定搜索顺序
- 剪枝
A*算法启发函数
A*算法的启发原理结合了BFS算法和Dijkstra算法。BFS算法的评估函数考虑的是当前点与终点的距离,其策略是选择于终点最进的点进行搜索,而Dijkstra算法关注的是起点于当前点的距离,其策略是选择与起点最近的点开始搜索。A*算法的启发函数也是两者的结合。
A*算法的启发函数公式是
F(n) = G(n) + H(n)
G(n)是从当前点到当前节点的移动距离
H(n)是从当前点到终点的移动距离的估计值
如果假设G(n) 为 0, 则算法效果于BFS相似。反过来,如果H(n)的值为0, 则算法效果于Dijkstra相似。
H(n)是A*算法的距离估计值,通过距离评估函数的计算得到这个值,下面介绍三种常用的距离评估函数:
曼哈顿距离
两个点在各个坐标轴上的距离差值的总和叫曼哈顿距离
D = |(X1 -X2)| + |Y1 - Y2|
~~~~~~~~~~~~欧氏几何平面距离
两个点之间的真实距离
D = sqrt( (X1 - X2) ^2 + (Y1 - Y2)^2 )
~~~~~~~~~~~~切比雪夫距离
向量中各个分量的差的最大的绝对值
D = max( |X1 - X2|, |Y1 - Y2| )
距离评估函数H(n)的值越小,启发信息越少,搜索范围越大,速度越慢,但是越有希望得到最短的路径
A*算法主要内容
根据我看的书《算法的乐趣》里的大概说一下
A*算法的搜索过程需要两个表,一个是OPEN表,存放当前已经被发现但是还没有搜索过的节点。另一个是CLOSE表,存放已经搜索过的节点。
A*算法的主要步骤有三步
1. 初始化OPEN表和CLOSE表,将起点加入到OPEN表中
2. 从OPEN表中取出当前F(n)值最小的节点作为当前的搜索节点NOW, NOW节点加入到CLOSE表中
3. 对于每一个于NOW可连通的节点ADJ, 考察ADJ节点:
如果ADJ已经在CLOSE表中,则对该节点不作处理;
如果ADJ不再OPEN表中,则计算F(ADJ),将ADJ的前驱节点设置成NOW并将ADJ加入到OPEN表中; 如多ADJ在OPEN表中,比较
G(NOW) + 1 < G(ADJ),则令G(ADJ) = G(NOW) + 1,同时将ADJ的前驱设置为NOW;重复步骤2,3,直到2步得到的搜索节点NOW就是终点为止