A*, A Star A星算法详解( 八 )


在小地图 。这种方法工作的很好 , 但它并不是最快的解决方案 。更苛求速度的A*程序员使用叫做二叉堆的方法 , 这也是我在代码中使用的方法 。凭我的经验 , 这种方法在大多数场合会快2~3倍 , 并且在长路经上速度呈几何级数提升(10倍以上速度) 。如果你想了解更多关于二叉堆的内容 , 查阅我的文章 , UsingHeaps in A*。(译者注:译文:在A*寻路中使用二叉堆)
另一个可能的瓶颈是你在多次寻路之间清除和保存你的数据结构的方法 。我个人更倾向把所有东西都存储在数组里面 。虽然节点可以以面向对象的风格被动态的产生 , 记录和保存 , 我发现创建和删除对象所增加的大量时间 , 以及多余的管理层次减慢的整个过程的速度 。但是 , 如果你使用数组 , 你需要在调用之间清理数据 。这中情形你想做的最后一件事就是在寻路调用之后花点时间把一切归零 , 尤其是你的地图很大的时候 。
我通过使用一个叫做(x,y)的二维数组避免这种开销 , 数组的每个元素表明了节点在开启列表还是在关闭列表中 。尝试寻路之后 , 我没有清零这个数组 。取而代之的是 , 我在新的寻路中重置和的数值 , 每次寻路两个都+5或者类似其他数值 。这种方法 , 算法可以安全的跳过前面寻路留下的脏数据 。我还在数组中储存了诸如F,G和H的值 。这样一来 , 我只需简单的重写任何已经存在的值而无需被清除数组的操作干扰 。将数据存储在多维数组中需要更多内存 , 所以这里需要权衡利弊 。最后 , 你应该使用你最得心应手的方法 。
8. 的算法:尽管A*被认为是通常最好的寻路算法(看前面的“题外话”),还是有一种另外的算法有它的可取之处-算法 。算法和A*本质是相同的 , 只有一点不同 , 就是算法没有启发式(H值总是0) 。由于没有启发式 , 它在各个方向上平均搜索 。正如你所预料 , 由于算法在找到目标前通常会探索更大的区域 , 所以一般会比A*更慢一些 。
那么为什么要使用这种算法呢?因为有时候我们并不知道目标的位置 。比如说你有一个资源采集单位 , 需要获取某种类型的资源若干 。它可能知道几个资源区域 , 但是它想去最近的那个 。这种情况 , 算法就比A*更适合 , 因为我们不知道哪个更近 。用A* , 我们唯一的选择是依次对每个目标许路并计算距离 , 然后选择最近的路径 。我们寻找的目标可能会有不计其数的位置 , 我们只想找其中最近的 , 而我们并不知道它在哪里 , 或者不知道哪个是最近的 。
进一步的阅读
好 , 现在你对一些进一步的观点有了初步认识 。这时 , 我建议你研究我的源代码 。包里面包含两个版本 , 一个是用C++写的 , 另一个用Blitz Basic 。顺便说一句 , 两个版本都注释详尽 , 容易阅读 , 这里是链接 。
* 例子代码: A*(2D)1.9
如果你既不用C++也不用Blitz Basic,在C++版本里有两个小的可执行文件 。Blitz Basic可以在从Blitz Basic网站免费下载的Blitz Basic 3D(不是Blitz Plus)演示版上运行 。Ben O'Neill提供一个联机演示可以在这里找到 。
【A*, A StarA星算法详解】你也该看看以下的网页 。读了这篇教程后 , 他们应该变得容易理解多了 。
* Amit的 A* 页面:这是由Amit Patel制作 , 被广泛引用的页面 , 如果你没有事先读这篇文章 , 可能会有点难以理解 。值得一看 。尤其要看Amit关于这个问题的自己的看法 。