A*寻路算法是一种用于静态位置高效搜索算法。他是在平面中两点之间去寻找一条可以到达的最短路径算法。
二维平面之中两个点,寻找可以抵达的最短路径。首先明确三个概念,H值,目前点到终点的曼哈顿距离(曼哈顿距离,就是两个位置长度差值和高度差值的和),G值,目前点到起点的消耗代价值,如果只是寻找路径,可以将该值也看成是这两点的曼哈顿距离,F值,H值和G值的和。
今天我这里讨论的寻路算法,暂时不考虑八个方向,仅仅考虑某个点所对应的上下左右四个方向可以移动。G值处理为距离起点的曼哈顿距离。接下来可能有点绕,但是是该算法的内容核心。
首先定义两个集合,openlist和closelist。openlist用于存放接下来可能会去的点的位置,closelist用于存放已经去过,不会再去的点的位置。然后,选定起点,将起点周边(上下左右)符合要求的点加入openlist,符合的要求需要可以达到,即没有阻挡物并且不存在于closelist中的点。在所有的openlist中找到F值最小的点,然后以该点为下一步行进点,在继续查找该行进点的上下左右符合要求的点。重复操作。结束条件,当openlist为空,没有找到终点,则不存在可以到达的路线,当行进点为终点时,则找到了最小路径。
结合下图,屌丝找女朋友的图来看下。
![A*寻路算法_第1张图片](http://img.e-com-net.com/image/info8/12ae867e329344569c1e34bad0938938.png)
首先定义openlist和closelist。因为openlist每次需要查找最小F值,所以使用multimap结构,将F值作为键值。
struct stInfo
{
int iF = 0;
int iG = 0; //到起点
int iH = 0;
int iPosx = -1;
int iPosy = -1;
int iFPosx = -1;
int iFPosy = -1;
};
std::multimap mapOpenList;
closelist因为需要查找某个位置是否存在于closelist中,如果存在则不能在使用该点,所以以x坐标和y坐标用作键值:std::map, stInfo> mapCloseList;
查找过程类似于一棵树的广度和深度遍历的集合,在屌丝的行进点的时候,先进行广度遍历,将所有可能的结果存放到openlist中,然后进行深度遍历,找到F值最小的一个分支,作为下一个该屌丝的行进点。同时将上一个行进点加入closelist中,以后将不再考虑该点。至于最后怎么将整条路径打印出来,上边的结构体中定义两个变量iFPosx, iFPosy,他们存放父节点的位置,比如行进点的子节点有四个,那么他们四个的父节点都是该行进点。这里可以将上边的屌丝找女朋友的图,理解成为一棵四叉树。最后结束条件:一种情况是openlist为空,那么该屌丝已经将所有的路都完了,还没有找到女朋友,即该屌丝永远找不到女朋友。另一种情况是行进点是女朋友的点,那么该屌丝找到了女朋友。
代码:
#include
#include
以上这份代码里的屌丝,最终找到了女朋友。
![A*寻路算法_第2张图片](http://img.e-com-net.com/image/info8/abf85f5b3da44731a77b27eb57b21e89.jpg)
昨天是A*寻路算法发明人Nilsson去世的日子,谨以此文致敬。