A*寻路算法与它的速度

原创 2010年07月14日 10:59:00

如果你是一个游戏开发者,或者开发过一些关于人工智能的游戏,你一定知道A*算法,如果没有接触过此类的东东,那么看了这一篇文章,你会对A*算法从不知道变得了解,从了解变得理解。
我不是一个纯粹的游戏开发者,我只是因为喜欢而研究,因为兴趣而开发,从一些很小的游戏开始,直到接触到了寻路等人工智能,才开始查找一些关于寻路方面的文章,从而知道了A*算法,因为对于初期了解的我这个算法比较复杂,开始只是copy而已,现在我们一起来精密的研究一下A*算法,以及提高它的速度的方法。

一,A*算法原理

我看过Panic翻译的国外高手Patrick Lester的一篇关于A*算法初探的文章,现在我就根据回忆,来慢慢认识A*算法的原理。
我们先来看一张图

aa

图中从起点到终点,需要绕过一些遮挡,也许我们看的比较简单,但是实际上,交给电脑来实现却要经过一番周折,电脑如何知道哪里有遮挡物,又是如何找到从起点到终点的最短路径的呢?
了解这些,我们首先要知道一个公式:
F = G + H
其中,F 是从起点经过该点到终点的总路程,G 为起点到该点的“已走路程”,H 为该点到终点的“预计路程”。
A*算法,要从起点开始,按照它的算法,逐步查找,直到找到终点。
初期,地图上的节点都是未开启也未关闭的初始状态,我们每检测一个节点,就要开启一些节点,检测完之后,要把检测完的节点,就要把它关闭。
我们需要一个开启列表和关闭列表,用来储存已经被开启的节点和被关闭的节点。
这些就让我们在实际过程中来深入了解吧。
看下面的图

aa

首先,我们来从起点出发,开启它周围的所有点,因为遮挡是无法通过的,我们不去管它,这样,被我们开启的节点,就是图中的三个节点,它们的父节点就是起点,所以图中的箭头指向起点,计算相应的FGH值,如图所视,检测完毕,将起点放入关闭列表。
这个时候,我们从被开启的所有节点中查找F值最小的节点,做为下一次检测的节点,然后开启它周围的点。
这时候起点左方和下方的F值都是70,我们根据自己的喜好选择任意一个,这里先选择下方的节点进行检测。
如下图

aa

首先把未被开启的剩下的节点的父节点指向检测点。
已经开启的点,我们不去开启第二遍,但是我们计算一下从检测点到达它们的新的G值是否更小,如果更小则代表目前的路径是最优的路径,那么把这个节点的父节点改为目前的检测点,并重新计算这个点的FGH的值,全部检测完毕之后,关闭检测点,然后开始寻找下一个节点,如此循环,直到找到终点。
然后从终点开始,按照每个节点的父节点,倒着画出路径,如下图

 

1

 

这个就是A*算法的原理,说难倒是不难,但是对于初步接触的人来说有点费劲而已。

 

二,A*算法的速度

前面,我们了解了A*算法的原理,发现,在每次查找最小节点的时候,我们需要在开启列表中查找F值最小的节点,研究A*的速度,这里就是关键,如何更快的找出这个最小节点呢?

1,普通查找算法

我们先来看看,最简单的做法,就是每次都把开启列表中所有节点检测一遍,从而找到最小节点

这里我用了一张很简单的地图来验证此方法
运行结果如图

aa

我们看到,耗时38毫秒,其实这个数字是不准确的,我们权且当作参考

2,排序查找算法

顾名思义,这个算法就是,始终维持开启列表的排序,从小到大,或者从大到小,这样当我们查找最小值时,只需要把第一个节点取出来就行了
维持列表的排序,方法是在太多了,我的方法也许很笨,勉强参考一下吧,我们每次排序的同时,顺便计算列表中的平均值,这样插入新节点的时候,根据这个平均值来判断从前面开始判断还是从后面开始判断

运行结果如图

aa

我们看到,耗时25毫秒,这个数字虽然不准确的,但是与普通查找算法相比较,速度确实是提高了

3,二叉树查找算法
(参考了火夜风舞的C++新霖花园中的文章)
这个算法可以说是A*算法的黄金搭档,也是被称为苛求速度的binary heap”的方法
就是根据二叉树原理,来维持开启列表的“排序”,这里说的排序只是遵循二叉树的原理的排序而已,即父节点永远比子节点小,就像下面这样
   1
|    |
5    9
|   |  |
7  12 10
二叉树每个节点的父节点下标 = n / 2;(小数去掉)
二叉树每个节点的左子节点下标 = n * 2;右子节点下标 = n * 2 +1
注意,这里的下标和它的值是两个概念

运行结果如图

aa

我们看到,耗时15毫秒,速度是这三个方法里最快的,但是因为这个数字是不够准确的,实际上,用二叉树查找法,会让A*算法的速度提高几倍到10几倍,在一些足够复杂的地图里,这个速度是成指数成长的。

4,总结
得出结论,用了A*算法,就要配套的用它的黄金搭档,二叉树,它可以让你的游戏由完美走向更完美。

 

 

 

A星算法详解(个人认为最详细,最通俗易懂的一个版本)

A* 寻路算法 原文地址: http://www.gamedev.net/reference/articles/article2003.asp 概述 虽然掌握了 A* 算法的人认为它容易,但...
  • hitwhylz
  • hitwhylz
  • 2014年04月07日 10:29
  • 23773

A*,那个传说中的算法

老王带你揭开传说中的面纱
  • zgwangbo
  • zgwangbo
  • 2016年07月31日 14:12
  • 16585

堪称最好的A*算法

如此好贴,不能不转!原文地址:http://dev.gameres.com/Program/Abstract/Arithmetic/AmitAStar.mht本文版权归原作者、译者所有,我只是转贴;如...
  • b2b160
  • b2b160
  • 2009年04月08日 17:58
  • 87112

A*寻路算法浅析

A*算法:A*(A-Star)算法是一种静态路网中求解最短路径最有效的直接搜索方法。估价值与实际值越接近,估价函数取得就越好。(像这种专业的概念的解释,我们还是交给度娘来做吧)...
  • yiyikela
  • yiyikela
  • 2015年05月28日 21:59
  • 4074

理解A*寻路算法具体过程

原文地址:http://www.cnblogs.com/technology/archive/2011/05/26/2058842.html         当然寻路算法不止 A* 这一种, 还...
  • cubesky
  • cubesky
  • 2015年03月10日 10:35
  • 4845

A*寻路 曼哈顿启发式算法 初探 经典寻路算法

作者: Patrick Lester 译者:Panic 2005年3月18日 译者序:很久以前就知道了A*算法,但是从未认真读过相关的文章,也没有看过代码,只是脑子里有个模糊的概念。这次决定从头开...
  • linjiayun
  • linjiayun
  • 2013年12月17日 18:36
  • 1447

明明白白A*寻路,一定让你懂

当我们要对一张地图进行寻路时,首先要对这张地图打掩码,掩码可能会有多种,如可通过,不可通过,被挡住,沉下等。这取决于你的需求。我们以最简单的方式来介绍A*寻路。     A*寻路需要2张表,一张叫cl...
  • dssdss123
  • dssdss123
  • 2013年09月09日 23:12
  • 1904

A*寻路算法——多人寻路、实时碰撞寻路、最近目的地

A* 路算法原理可以参考这个文章,已经写的很详细了http://www.cppblog.com/mythit/archive/2009/04/19/80492.aspx 这篇文章主要写写多人寻路的实...
  • UnSkyToo
  • UnSkyToo
  • 2015年11月04日 21:34
  • 3174

游戏开发中的人工智能——A*路径寻找算法

转载至 阅读笔记-游戏开发中的人工智能-第7章-A*路径寻找算法 1. 简述     A*是当今游戏软件开发中十分常用的一种路径寻找算法。A*算法之所以会如此吸引人,是因为它可以保证在任何起点...
  • Boyhou
  • Boyhou
  • 2013年08月15日 16:09
  • 2527

cocos2d-x学习日志(14) --A星寻路算法之45度地图

一、A星搜索 他就是一种启发性的算法,根据现在到达这个位置的步数及之后的“估计步数”,即f=g+h,f是整个从起点到终点的代价,g是从起点到我们目前位置的步数,h是从目前位置到终点的估计值,注意这...
  • my183100521
  • my183100521
  • 2013年12月16日 12:03
  • 3614
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:A*寻路算法与它的速度
举报原因:
原因补充:

(最多只允许输入30个字)