c ++ set vs vector +堆操作用于A *优先级队列

时间:2009-06-13 03:35:59

标签: c++ stl containers a-star

什么时候使用std :: set比使用std :: vector和make_heap/push_/pop_更高效(w.r.t。时间)作为A *操作中的优先级队列?我的猜测是,如果打开列表中的顶点很小,使用向量是一个更好的选择。但有没有人有这方面的经验?

5 个答案:

答案 0 :(得分:4)

如果我不得不猜测?我猜测矢量版本可能是一个不错的选择,因为一旦它增长到一定的大小,就不会有很多的分配。

但我不喜欢猜测。我更喜欢硬数字。试试两个,个人资料!

答案 1 :(得分:1)

我认为用于A *搜索的优先级队列的基于矢量的数据结构不是一个好主意,因为您将不断在列表中的某处添加单个元素。如果边缘(我假设这是你正在做的那样)很大并且元素将被添加到中间,这是非常低效的。

几周前,当我在Java中实现A *时,我使用了Java PriorityQueue,它显然基于优先级堆,这似乎是一种很好的方法。我建议在C ++中使用set

编辑:谢谢Niki。我现在明白了如何实现二进制堆(使用数组),我理解你在问题中实际问的是什么。我怀疑priority_queue是最好的选择,尽管(正如Igor所说)将它交换到set以检查其性能并不困难。我猜是有一个原因,为什么优先级队列(至少在Java和C ++中)使用二进制堆实现。

答案 2 :(得分:1)

如果您正在进行A *寻路工作,请查看Dan Higgins的AI Wisdom中的文章。在这里有一个如何快速获取数据结构的描述。他提到了一个“廉价列表”,就像为最近的节点设置了一个热缓存,并避免了对寻路数据结构的大量惩罚。

http://introgamedev.com/resource_aiwisdom.html

答案 3 :(得分:0)

  1. 对于A *搜索,我会选择 std ::基于矢量的优先级队列。
  2. 然而,改变了 从std :: vector到另一个STL容器的实现应该是 非常琐碎,所以我会尝试不同的版本,看看如何 它会影响算法吗? 性能。除了stl :: map之外,我肯定会尝试使用stl :: deque。

答案 4 :(得分:0)

使用优先级队列。基于二进制堆的一个很好(就像基于矢量的std优先级队列)。您可以在O(n)时间内构建堆,并且所有相关操作都需要O(logn)。除此之外,您还可以实现对*有用的减少键操作。但是,为std队列实现它可能很棘手。使用set执行此操作的唯一方法是删除元素并使用不同的优先级重新插入。

编辑:您可能需要查看使用

std::make_heap

(及相关功能)。这样您就可以访问向量并轻松实现reduce_key。

编辑2:我看到你打算使用make heap,所以你所要做的就是实现reduce键。