码迷,mamicode.com
首页 > 编程语言 > 详细

使用C++实现高效的A星(A*/A Star)算法

时间:2015-03-31 10:31:38      阅读:315      评论:0      收藏:0      [点我收藏+]

标签:

    最近闲来无事想实现一下A*算法,其实例子在网上已经很多了。我只是想自己动手试试,如果效率还行的话可以保存起来以便日后使用。

    A*算法的基本原理可以参考这里:

http://www.gamedev.net/page/resources/_/technical/artificial-intelligence/a-pathfinding-for-beginners-r2003 。

    本文只是对实现A*算法中遇到的问题和解决思路进行总结记录。为了速度我使用了二叉堆的方法。

   在第一个版本完成后我进行了测试,在100*100的格子里从左上角搜索到右下角居然需要0.6秒之久!然后我使用Visual Studio的性能和诊断功能,发现大量时间被消耗在了判断位置是否在开启列表和关闭列表中。以前的方法是用两个vector来存放开启列表和关闭列表的位置信息,然后遍历容器来判别是否在其中,效率自然很低。然后我就改变方法,构建一个和地图行、列一样的二维数组来存放位置的状态信息,这样我直接通过当前的x和y坐标就能够直接判断是否在开启列表或关闭列表中了。最后测试发现效率的确提高了非常多!


    然后再打开Visual Studio的性能和诊断工具观察,发现在开启列表中发现更近的路径时,需要更新G值的时候。这时候效率就非常低,因为我之前的做法是在这里重新构建一个二叉堆,效率自然就低了。这里解决比较简单,只需要把当前节点进行上滤就好了。不过这个std里面没提供这个,自己实现了一下,具体可以参考百度一下二叉堆。


    再测试一下速度还挺满意的,再看看有没有需要优化的地方。刚才在解决判断位置是否在开启/关闭列表的时候,我使用了一个二维数组来存放状态信息。对二维数组的访问时比较慢的,特别是在访问频繁的时候,这里我改为了一维数组。


    然后我又发现了一个问题,在搜索过程中我需要经常new 一个对象出来存放位置信息,在地图比较大的时候效率就比较低了。为了不经常创建对象我又整了一个小对象分配器来。听说box2d这个物理引擎就使用了一个小对象分配器,遂翻它源码看了一下,发现还是蛮适合这里的情况的,然后就把它弄了过来。测试之后发现效果提升明显,在1000*1000的地图里从左上角搜索到右下角需要0.3秒以上,使用了小对象分配器后只需要0.1几秒。


    下面给出测试数据:

地图大小 允许斜走 耗时
100*100 0.001s
100*100 0.000s
1000*1000 0.137s
1000*1000 0.006s

    

代码下载:https://github.com/zhangpanyi/AStar

使用C++实现高效的A星(A*/A Star)算法

标签:

原文地址:http://www.cnblogs.com/jiushichenan/p/4380009.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!