我是第一次开发A *,而我正在使用priority_queue作为开放集,直到我意识到你需要检查节点是否也在开放集中,而不仅仅是关闭节点。
事实是,你无法迭代一个优先级队列。那么为什么每个人都推荐一个开放集的优先级队列?它还是最好的选择吗?我认为迭代它的唯一方法是制作副本,这样我就可以从中弹出一切(费用很高)。
A *上使用的最佳数据结构是什么?
答案 0 :(得分:7)
优先级队列(PQ)是抽象数据结构(ADS)。实现它们有很多可能性。不幸的是,C ++标准库提供的priority_queue相当有限,其他实现更适合实现A *。 Spoilers:您可以使用std :: set / multiset而不是std :: priority_queue。但请继续阅读:
那么从优先级队列中实现A *需要的是:
任何优先级队列都可以执行1.,但是对于2.,您需要一个“可变”优先级队列。 Standard-Lib不能这样做。此外,您需要一种简单的方法来查找优先级队列中的条目,以找出减少密钥的位置(当A *找到更好的路径到已打开的节点时)。有两种基本方法:将句柄存储到图形节点中的优先级队列元素(或使用映射来存储每个图形节点的句柄) - 或者自己插入图形节点。
对于第一种情况,存储每个节点的句柄,可以使用std :: multiset作为优先级队列。 std :: multiset :: first()将始终是您的“最低成本”密钥,您可以通过从密钥中删除密钥,更改值并重新插入以及更新句柄来减少密钥。或者,您可以使用Boost.Heap中的可变优先级队列,它直接支持“reduce-key”。
对于第二种情况,您需要某种“侵入式”二叉树 - 因为您的寻路节点本身需要位于优先级队列中。如果您不想自己滚动,请参阅Boost.Intrusive中的有序关联容器。
答案 1 :(得分:3)
主题非常大,如果您想了解不同的可能性并且很好地了解哪种数据结构适合您的情况,我建议您阅读本页: http://theory.stanford.edu/~amitp/GameProgramming/ImplementationNotes.html#set-representation
就我而言,二进制堆在实现难度和性能之间取得了很好的平衡,这完全是我想要的。但也许你正在寻找不同的东西?
本文的其余部分是A *游戏开发的非常好的参考 http://theory.stanford.edu/~amitp/GameProgramming/index.html
答案 2 :(得分:-1)
它们意味着优先级队列不一定是该语言附带的std :: priority_queue类。如果内置的不能做你需要它自己写的,或者找另一个。