简体   繁体   English

A *优先级队列的C ++设置与向量+堆操作

[英]c++ set versus vector + heap operations for an A* priority queue

When is using a std::set more efficient (wrt time) than using a std::vector along with make_heap/push_/pop_ for the priority queue in an A* operation? 什么时候使用std :: set效率(写入时间)比对A *操作中的优先级队列使用std :: vector和make_heap/push_/pop_更为有效? My guess is that if the vertices in the open list are small, using a vector is a better option. 我的猜测是,如果打开列表中的顶点很小,则使用矢量是更好的选择。 But does anyone have experience with this? 但是有人有经验吗?

If i had to venture a guess? 如果我不得不冒险猜测? I'd guess that the vector version is probably a good choice because once it grows to a certain size, there won't be very many allocs. 我猜矢量版本可能是一个不错的选择,因为一旦它增长到一定的大小,就不会有太多的分配。

But I don't like guessing. 但是我不喜欢猜测。 I prefer hard numbers. 我更喜欢硬数字。 Try both, profile! 尝试一下,个人资料!

If you're doing A* pathfinding work, check out the articles in AI Wisdom by Dan Higgins. 如果您要进行A *寻路工作,请查看Dan Higgins的AI Wisdom中的文章。 In there is a description of how to get data structures fast. 其中介绍了如何快速获取数据结构。 He mentions a "cheap list" which is like having a hot cache for recent nodes and avoiding a lot of the penalties for pathfinding data structures. 他提到了一个“便宜列表”,就像为最近的节点提供了一个高速缓存,并且避免了对寻路数据结构的许多惩罚。

http://introgamedev.com/resource_aiwisdom.html http://introgamedev.com/resource_aiwisdom.html

I don't think a vector based data structure for a priority queue for an A* search is a good idea because you're going to be constantly adding a single element somewhere in the list. 我认为A *搜索优先级队列的基于矢量的数据结构不是一个好主意,因为您将不断在列表中的某个位置添加单个元素。 If the fringe (I assume this is how you're doing it) is large and the element is to be added in the middle, this is highly inefficient. 如果边缘较大(我认为这是您的操作方式),并且要在中间添加元素,则效率很低。

When I implemented A* in Java a few weeks ago, I used the Java PriorityQueue which apparently is based on a priority heap, and that seems like a good way to do it. 几周前,当我用Java实现A *时,我使用了Java PriorityQueue,它显然是基于优先级堆的,这似乎是一种很好的方法。 I recommend using set in C++. 我建议在C ++中使用set

EDIT: thanks Niki. 编辑:谢谢妮基。 I now understand how binary heaps are implemented (with an array), and I understand what you're actually asking in your question. 现在,我了解了如何(使用数组)实现二进制堆,并且了解了您实际上在问什么。 I suspect a priority_queue is the best option, although (as Igor said) it wouldn't be hard to swap it over to a set to check the performance of that. 我怀疑priority_queue是最好的选择,尽管(如Igor所说)将它交换到一set以检查其性能并不困难。 I'm guessing there's a reason why priority queues (in Java and C++ at least) are implemented using binary heaps. 我猜测存在使用二进制堆实现优先级队列(至少在Java和C ++中)的原因。

  1. For A* search, I would go with a std::vector-based priority queue. 对于A *搜索,我将使用基于std :: vector的优先级队列。
  2. However, the change in the implementation from std::vector to another STL container should be quite trivial, so I would experiment with different versions and see how does it affect the algorithm performance. 但是,从std :: vector到另一个STL容器的实现更改应该是微不足道的,因此我将尝试不同的版本,并观察它如何影响算法性能。 In addition to stl::map, I would definitely try stl::deque. 除了stl :: map,我肯定会尝试stl :: deque。

Use a priority queue. 使用优先级队列。 A binary heap based one is fine (like the vector based std priority queue). 基于二进制的堆是好的(就像基于向量的std优先级队列一样)。 You can build the heap in O(n) time and all relevent operations take O(logn). 您可以在O(n)时间内构建堆,所有相关事件操作都需要O(logn)。 In addition to that you can implement the decrease key operation which is useful for a*. 除此之外,您还可以实现对a *有用的减少键操作。 It might be tricky to implement for the std queue however. 但是,为std队列实现它可能很棘手。 The only way to do that with a set is to remove the element and reinsert it with a different priority. 用集合执行此操作的唯一方法是删除元素,然后以其他优先级将其重新插入。

Edit: you might want to look into using 编辑:您可能想研究使用

std::make_heap

(and related functions). (和相关功能)。 That way you get access to the vector and can easily implement decrease_key. 这样,您就可以访问向量,并且可以轻松实现reduce_key。

Edit 2: I see that you were intending on using make heap, so all you'd have to do is implement decrease key. 编辑2:我看到您打算使用make堆,所以您要做的就是实现reduce键。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM