关于A *寻路的问题

时间:2012-08-02 22:59:47

标签: java path-finding a-star

好吧,我正在尝试将A * Pathfinding实现为一个简单的tilemap数组,我有几个问题。

对于打开/关闭列表,我应该使用arrayList来存储它找到的所有点,还是有更好的方法来存储它们?

其次,如何检查邻居?我是否采用了起始区块,检查上方,下方,左侧和右侧的区域,以及存储成本最低的区域?

3 个答案:

答案 0 :(得分:1)

只要你没有为游戏实现这一点,意味着高fps视频游戏,我怀疑你的性能会因使用ArrayList而受到重创,那应该没问题。

至于问题的第二部分,假设每个节点只有4个连接方向,那么是,每个邻居的简单顺序检查都可以。

答案 1 :(得分:1)

我过去使用PriorityQueue为打开列表实现了这一点。比较器在A *启发式值上工作。这非常干净,你会得到每次插入的O(log n)性能和最坏的情况。优于标准实现可以将轮询改进为O(1)摊销。对于visited列表,请在切片中使用标记,或者使用单独的HashSet。后者的优点是没有初始化成本和插入和成员资格的相同渐近成本。但是哈希的常数因子比检查布尔映射值要大。

答案 2 :(得分:0)

我不知道“tilemap数组”是什么,但我认为通过“它找到的点”你的意思是搜索树中的节点。存储尚未探索的节点的数据结构需要实现两个重要的属性,继承自Dijkstra的算法:

  1. 以最低成本获取节点应该很快,至少是O( n
  2. 一旦找到更短的路径,您将希望降低节点的成本
  3. 前者可以使用堆来实现。二进制堆很容易实现。 Fibonacci堆给出了渐近的性能,但在大多数应用中不应该是必要的。到目前为止,我见过的库中的大多数堆都不支持后一个要求,通常称为减少键。为了实现这一点,您的节点应该保存有关它们在堆中的当前位置的信息。这样,当节点更改其成本时,您可以在O(1)中获取其当前位置并在O(log n )中调整位置。并且您可以使用相同的变量来确定项目是否在堆中。

    现在提出第二个问题。通常,您通过从堆中删除最小元素来检查成本。换句话说,对于每个neightbour,你要么插入到堆中,要么它已经在堆中,你调整它的成本(以及它的堆位置) )如果新的成本更好。