本文基于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( 目标格已经在 "开启列表", 这时候路径被找到) 
如果开启列表已经空了, 说明路径不存在.

最后从目标格开始, 沿着每一格的父节点移动直到回到起始格, 这就是路径.

posted on 2014-12-31 15:01  神之  阅读(204)  评论(0)    收藏  举报