我正在寻找一种数据结构来支持一种高级优先级队列。思路如下。我需要按顺序处理许多项目,并且在任何给定的时间点,我都知道下一步要做的“最佳”项目(基于某些指标)。问题是,处理一个项目会改变一些其他项目的指标,所以静态队列不能解决问题。
在我的问题中,我知道哪些项目需要更新其优先级,所以我正在寻找的数据结构应该有方法
- 入队(项目,优先级)
- 出队()
- 重新排队(项目,新优先级)
理想情况下,我想在 O(log n) 时间内重新排队。有任何想法吗?
我正在寻找一种数据结构来支持一种高级优先级队列。思路如下。我需要按顺序处理许多项目,并且在任何给定的时间点,我都知道下一步要做的“最佳”项目(基于某些指标)。问题是,处理一个项目会改变一些其他项目的指标,所以静态队列不能解决问题。
在我的问题中,我知道哪些项目需要更新其优先级,所以我正在寻找的数据结构应该有方法
理想情况下,我想在 O(log n) 时间内重新排队。有任何想法吗?
有一种算法的时间复杂度与您所需的相似,但它O(log n)仅在平均时间上运行,如果它是您需要的。在此算法中,您可以使用现有的优先级队列而不使用该requeue()功能。
假设您在图表中的节点与优先级队列中的元素之间存在连接。让优先级队列的元素也存储一个称为 的额外位ignore。修改后的dequeue运行算法如下:
dequeue()ignore元素中的位为真,则返回 1,否则返回项目 id。修改后的enqueue运行算法如下:
v逐个
访问图中item的邻居节点ignore为 true 对应于vv与新入队元素的连接。num_ignore++num_ignore)的数量大于非忽略元素的数量,则重建优先队列
dequeue所有元素,存储,然后enqueue再次仅非忽略元素在这个算法中,ignore位的设置需要恒定的时间,所以你基本上会延迟O(log n)“重新排队”,直到你积累了O(n)忽略元素。然后将它们全部清除一次,这需要O(n log n). 因此,平均而言,每个“重新排队”需要O(log n).
您无法达到您要求的复杂性,因为在更新元素时,复杂性还应取决于更新元素的数量。
但是,如果我们假设在给定步骤中更新元素的数量是p堆的大多数典型实现,那么对于O(1)获取最大元素的值、O(log(n))对于双端队列和O(p * log(n))更新操作来说,这将变得更加复杂。我个人会选择二进制堆,因为它很容易实现并且可以满足您的要求。
http://www.eecs.wsu.edu/~ananth/CptS223/Lectures/heaps.pdf描述了 increaseKey()、reduceKey() 和 remove() 操作。这会让你做你想做的事。我还没有弄清楚 C++ stdlib 实现是否支持它。
Further, the version: http://theboostcpplibraries.com/boost.heap seems to support update() for some subclasses, but I haven't found a full reference yet.