本文基于http://www.cppblog.com/mythit/archive/2009/04/19/80492.aspx
和http://www.cnblogs.com/technology/archive/2011/05/26/2058842.html
看了一下,最初这个翻译是在2005年,可能更早。
文章中对于A*算法说明的还是比较简明易懂。只是有些地方说的比较简单。可能对于我这种基础不太好的需要添加一些东西,有些是猜测。
1、关于代价的计算
由于算法公式为:F = G + H
可以看成:总代价(总耗费、总值随便称呼) = 已用代价 + 预估代价
其中预估代码是算法中的启发式搜索,所谓的AI前传。文章中的预估代码使用的叫曼哈顿算法。此算法只能横竖去算格子,不能计算斜的。从始发地到目的地出去障碍物的最短距离。
此外这个曼哈顿算法是可以用其他算法代替的,不是唯一的情况。
另外由于H是固定的,变动的只有G,所以实际上每个格子的代价只要计算G就ok了。
2、关于开启列表
从起点A开始, 把它作为待处理的方格存入一个"开启列表",并设置它们的"父方格"为A.
先把所有相关的点放入列表,找到G值最小的点。然后对此点进行查找周围所有点,放入“开启列表”。
然后问题来了,对于已经放入的点,在第二次又要放进去了怎么处理。肯定是要计算G值,然后确定父方格的。
但是是先放进去还是先计算G值。我猜要先计算一次再放进去。后面再计算一下。
这里计算的方法就是用(G值最小的点的代价+重复的点的相对代价)与重复的点之前代价进行对比。
C的代价(10)+D对于C的代价(10) 与 D之前的代价(14)对比

3、如何才算正确路径

以中心为第一个点,然后每个点都需要进行计算。绿色是计算过G值的点,蓝色是最后的路径,如何算的。
关键在于每个点都有父方格,保证父方格的正确性,最后形成了一个路径。
4、代码
把起始格添加到 "开启列表"
do
{
寻找开启列表中F值最低的格子, 我们称它为当前格.
把它切换到关闭列表.
对当前格相邻的8格中的每一个
if (它不可通过 || 已经在 "关闭列表" 中)
{
什么也不做.
}
if (它不在开启列表中)
{
把它添加进 "开启列表", 把当前格作为这一格的父节点, 计算这一格的 FGH
if (它已经在开启列表中)
{
if (用G值为参考检查新的路径是否更好, 更低的G值意味着更好的路径)
{
把这一格的父节点改成当前格, 并且重新计算这一格的 GF 值.
}
} while( 目标格已经在 "开启列表", 这时候路径被找到)
如果开启列表已经空了, 说明路径不存在.
最后从目标格开始, 沿着每一格的父节点移动直到回到起始格, 这就是路径.
浙公网安备 33010602011771号