A*算法开表选择
A* algorithm open list selection
我知道在 A* 算法中,当采取下一步时,应该从 openlist 或 frontier 中选择具有下一个最低预测成本的步骤,但是当存在多个具有相同预测成本的最低步骤时有什么偏好应该选择哪一个?
我认为后进先出可以更好地工作,但我不确定是否有更好的方法来 select 当有多个匹配成本时下一步行动。
我想你正在寻找 bounded relaxation (AKA A*-epsilon)。
想法是生成f(v) = g(v) + (1+eps)h(v)
。 eps
的值非常小,它不会改变算法的最优性,同时在搜索中有利于 "depth" 而不是 "breadth",并且通常会提高搜索速度。
同样,您可以通过给出非常接近于零但负值的 eps
来支持广度 - 但我不熟悉这里支持广度的任何用法。
根据 A*,具有相同估计成本(从开始的成本加上启发式)的所有步骤都同样值得研究。
问题是,如果没有进一步的启发,我很难做出选择;或者,更确切地说,这取决于您想要什么。
在标准 f(x) = g(x) + h(x)
情况下,如果您没有其他启发式或信息,则有 2 个主要策略:
- 你选择最近的步骤
x
,希望它对应于一个好的轨道(并且它可能有助于解决内存局部性问题):如果它是最近的,则意味着它只有相对较小的成本相对于其他更新;
- 你选择步骤
x
最小的h
,也就是说,已知成本相对于未知成本的相对贡献最高(这就是加权A*的目标) ).
对于第二种策略,除了扩大启发式之外,您只需要按 (f, h)
对而不是 f
对 steps/nodes 进行排序。但是,它不能保证您没有领带:
*
/ \
| |
\ /
+
最后,您需要选择一个,例如最近的(或者只是您的优先级队列实现产生的那个)。
请注意,如果您选择 x
最多 h
,您将更接近 Amit 所指的广度行为。
理论上,两者都不是更好的选择,因为您的适应度函数应该使用所有可用信息来模拟哪个比另一个更好。
选择列表中最容易编程的、最新的或您最喜欢的 ith
素数。应该没关系。
打破平局的一个不错的选择可能是选择具有最大G值的节点,毕竟它们将更接近终点。
这个想法来自这里
http://movingai.com/astar.html
该页面上的视频展示了通过选择最低 G 值和选择最高 G 值打破平局的区别。
很遗憾,没有显示 "greatest G" 与 "last node" 的视频。正如弗朗西斯在他的回答中提到的那样,使用最后一个可能对缓存更友好并导致更快的速度。再加上仅使用最后一个可能需要更少 book-keeping 代码的事实...
同一个站点有一堆真实的游戏地图和测试场景,您可以使用它们来衡量哪个效果更好。你可以在这里找到它们 http://movingai.com/benchmarks/
我的测试,使用我自己的 A* 实现表明......这一切都取决于 map/scenario :)
总的来说,使用上面 link 中的地图和场景以及我自己的 A* 实现,通过简单地选择最后一个节点赢得 90% 的时间来打破平局。另一方面,有一些地图在 90% 的情况下通过选择最高 G 获胜来打破平局。
我很想听听你的情况。
我知道在 A* 算法中,当采取下一步时,应该从 openlist 或 frontier 中选择具有下一个最低预测成本的步骤,但是当存在多个具有相同预测成本的最低步骤时有什么偏好应该选择哪一个?
我认为后进先出可以更好地工作,但我不确定是否有更好的方法来 select 当有多个匹配成本时下一步行动。
我想你正在寻找 bounded relaxation (AKA A*-epsilon)。
想法是生成f(v) = g(v) + (1+eps)h(v)
。 eps
的值非常小,它不会改变算法的最优性,同时在搜索中有利于 "depth" 而不是 "breadth",并且通常会提高搜索速度。
同样,您可以通过给出非常接近于零但负值的 eps
来支持广度 - 但我不熟悉这里支持广度的任何用法。
根据 A*,具有相同估计成本(从开始的成本加上启发式)的所有步骤都同样值得研究。
问题是,如果没有进一步的启发,我很难做出选择;或者,更确切地说,这取决于您想要什么。
在标准 f(x) = g(x) + h(x)
情况下,如果您没有其他启发式或信息,则有 2 个主要策略:
- 你选择最近的步骤
x
,希望它对应于一个好的轨道(并且它可能有助于解决内存局部性问题):如果它是最近的,则意味着它只有相对较小的成本相对于其他更新; - 你选择步骤
x
最小的h
,也就是说,已知成本相对于未知成本的相对贡献最高(这就是加权A*的目标) ).
对于第二种策略,除了扩大启发式之外,您只需要按 (f, h)
对而不是 f
对 steps/nodes 进行排序。但是,它不能保证您没有领带:
*
/ \
| |
\ /
+
最后,您需要选择一个,例如最近的(或者只是您的优先级队列实现产生的那个)。
请注意,如果您选择 x
最多 h
,您将更接近 Amit 所指的广度行为。
理论上,两者都不是更好的选择,因为您的适应度函数应该使用所有可用信息来模拟哪个比另一个更好。
选择列表中最容易编程的、最新的或您最喜欢的 ith
素数。应该没关系。
打破平局的一个不错的选择可能是选择具有最大G值的节点,毕竟它们将更接近终点。
这个想法来自这里 http://movingai.com/astar.html
该页面上的视频展示了通过选择最低 G 值和选择最高 G 值打破平局的区别。
很遗憾,没有显示 "greatest G" 与 "last node" 的视频。正如弗朗西斯在他的回答中提到的那样,使用最后一个可能对缓存更友好并导致更快的速度。再加上仅使用最后一个可能需要更少 book-keeping 代码的事实...
同一个站点有一堆真实的游戏地图和测试场景,您可以使用它们来衡量哪个效果更好。你可以在这里找到它们 http://movingai.com/benchmarks/
我的测试,使用我自己的 A* 实现表明......这一切都取决于 map/scenario :)
总的来说,使用上面 link 中的地图和场景以及我自己的 A* 实现,通过简单地选择最后一个节点赢得 90% 的时间来打破平局。另一方面,有一些地图在 90% 的情况下通过选择最高 G 获胜来打破平局。
我很想听听你的情况。