看了gamedev上的一篇文章http://www.gamedev.net/page/resources/_/technical/artificial-intelligence/a-pathfinding-for-beginners-r2003,对A*算法有了一定的理解,把算法过程用自己的话描述出来,以便于以后有空的时候实现一下。
主要公式 F = G + H,见原文如下:
G = the movement cost to move from the starting point A to a given square on the grid, following the path generated to get there.H = the estimated movement cost to move from that given square on the grid to the final destination, point B. This is often referred to as the heuristic, which can be a bit confusing. The reason why it is called that is because it is a guess. We really don't know the actual distance until we find the path, because all sorts of things can be in the way (walls, water, etc.). You are given one way to calculate H in this tutorial, but there are many others that you can find in other articles on the web.
大概就是G是从起点到网格上一个点的代价,H是从网格上这个点到终点的预估移动距离。
H can be estimated in a variety of ways. The method we use here is called the Manhattan method, where you calculate the total number of squares moved horizontally and vertically to reach the target square from the current square, ignoring diagonal movement, and ignoring any obstacles that may be in the way. We then multiply the total by 10, our cost for moving one square horizontally or vertically. This is (probably) called the Manhattan method because it is like calculating the number of city blocks from one place to another, where you can't cut across the block diagonally.
A*是一种启发式的算法,就是对每一个搜索的位置进行评估,也就是把找的位置离目标的距离当成找点的一个依据,然后猜测这个点是否最佳("启发式"就是猜测)。
这里的H值用的是一种曼哈顿方法,H=(与目标点的行差 + 与目标点的列差)*10
一些说明:
绿格子为起始点,红格子为终点,深蓝格子是不可穿越的点,假设水平或垂直走格子的代价为10,对角线走格子的代价为14,某些情况下受到深蓝格子的影响的话,无法走对角线(如图中绿格子右上方格子不可以进一步再往右上方走,因为被蓝色格子挡住了)。
格子上的数字意义:左上(F)= 左下(G) + 右下(H)。箭头为指向本格子的父格子(即指明从哪个节点走过来的)。
算法流程:
1、有两个表,一个为open表,一个为close表。一开始两个表为空,然后遍历起始格子(绿格子)的邻接得格子,如图所示,把F,G,H都计算出来,把它们都加入open表中,然后把起始点加入close表中。遍历的格子的父格子都为绿色格子。
然后从open表中选择一个F值最小的格子(如果有相同F值就选择最新加入的格子,这个关系不大)。如图所示,选择了绿格子右边的格子(浅蓝色边框),叫它为当前格子,然后遍历当前格子的邻接格子,排除掉蓝色格子,排除掉已经在close表中的格子,然后把还没有在close表中的格子加入到表中,此时当前格子没有这种情况。然后在遍历中看看已经在open表的格子是否需要改变其父格子,使其指向当前格子的话,其G值更小,意义就是从当前格子到达此格子比从其他格子到达此格子的代价更小,例如当前格子上面的那个格子的G值为14,如果是从当前格子走到这个格子的话,其G值应该为10+10=20,因此无需修改上面格子的指向。遍历完后,把当前格子加入到close表中。
2、然后接下来在open表中选择一个F值最小的且最新加入的格子作为当前格子,如图所示。有点要说明的就是当前格子的右下那个格子被蓝色格子挡住是走不过去,因此遍历的时候要抛弃他。然后像之前一样继续遍历,加入了两个新格子到open表中,如图所示,下和左下两个格子。
3、按照2一直进行下去,一直到close表中包含红色格子。
4、此时顺着红格子的父格子一直往前遍历,就能把路径复原出来。
最后用原文的一段话来总结一下。
Summary of the A* Method
Okay, now that you have gone through the explanation, let's lay out the step-by-step method all in one place: