A*算法

一、简介

         A*算法是启发式算法的一种,可以求出在图形平面上有着多个节点时,找到两个节点之间的最短路径,它的用到的地方还是挺多的,如游戏中的NPC移动,其实A*算法和Dijkstra算法很像很像的(个人相当感觉额,但也有一点点差异),如果你了解Dijkstra算法的话,那对于A*算法就很容易接受了。

二、算法主要内容

         对于A*算法而言,需要设计一个估计函数,即f(n) = g(n) + h(n),其中g(n)表示搜索起点到当前节点的代价(通常用某节点在搜索树中的深度来表示的),h(n)表示当前节点到目标节点的估计值,对于A*算法的估计函数而言,其中h(n)的设计最为重要,也是衡量是否为A*算法的一个标准。

       对于A*算法而言,需要满足一下几个条件才算得上A*算法:

             1).图中存在从起点到目标终点的最有路径。

             2).问题是有限的。

             3).所有节点的子节点代价>0。

             4).h(n) =< h*(n)          (其中h*(n)为实际问题的代价值)

三、算法实现示意图

           求V0->V5的路径,在V0->V5过程中,可以经过V1、V2、V3、V4到达目标及诶大V5

四、算法设计伪代码

将起点放入OPEN表;
while(OPEN!=NULL)
{
   从OPEN表中取估价值f最小的节点n;
   if(n节点==目标节点)
   {
      找到了目标
      break;
   }
   for(当前节点n的每个子节点X)
   { 
      算X的估价值;
      if(X in OPEN)
      { 
         if( X的估价值小于OPEN表的估价值 )
         {
             把n设置为X的父亲;
             更新OPEN表中的估价值; //取最小路径的估价值
         }
      } 
      if(X in CLOSE) 
      {
         continue;
      }  
      if(X not in both)
      {
         把n设置为X的父亲;
         求X的估价值;
         并将X插入OPEN表中; //还没有排序
      }
   }//end for
 将n节点插入CLOSE表中;
 按照估价值将OPEN表中的节点排序; //实际上是比较OPEN表内节点f的大小,从最小路径的节点向下进行。
}//end while(OPEN!=NULL)

保存路径,即从终点开始,每个节点沿着父节点移动直至起点,这就是你的路径

五、A*算法和Dijkstra算法比较

         这两个算法很相似,但一般A*算法的性能比Dijkstra算法好稍稍好一些,A*算法的时间复杂度为nlog(n),而Dijkstra算法为o(n2),这是因为在获得没有遍历的节点时,也就是在OPEN表中的那些,A*算法是对其用快速排序将其按照估计值的大小进行排序的,因而总时间复杂度为o(n)*log(n),其中o(n)外层遍历OPEN表的所有节点,但对于Dijkstra算法,它并没有对那些OPEN表的节点进行排序,所以得到的时间复杂度为o(n)*o(n)。

posted @ 2013-09-12 16:57  梧桐树下的一缕阳光  阅读(626)  评论(0编辑  收藏  举报