我正在寻找一种数据结构来支持一种高级优先级队列。思路如下。我需要按顺序处理许多项目,并且在任何给定的时间点,我都知道下一步要做的“最佳”项目(基于某些指标)。问题是,处理一个项目会改变一些其他项目的指标,所以静态队列不能解决问题。
在我的问题中,我知道哪些项目需要更新其优先级,所以我正在寻找的数据结构应该有方法
- 入队(项目,优先级)
- 出队()
- 重新排队(项目,新优先级)
理想情况下,我想在 O(log n) 时间内重新排队。有任何想法吗?
我正在寻找一种数据结构来支持一种高级优先级队列。思路如下。我需要按顺序处理许多项目,并且在任何给定的时间点,我都知道下一步要做的“最佳”项目(基于某些指标)。问题是,处理一个项目会改变一些其他项目的指标,所以静态队列不能解决问题。
在我的问题中,我知道哪些项目需要更新其优先级,所以我正在寻找的数据结构应该有方法
理想情况下,我想在 O(log n) 时间内重新排队。有任何想法吗?
有一种算法的时间复杂度与您所需的相似,但它O(log n)
仅在平均时间上运行,如果它是您需要的。在此算法中,您可以使用现有的优先级队列而不使用该requeue()
功能。
假设您在图表中的节点与优先级队列中的元素之间存在连接。让优先级队列的元素也存储一个称为 的额外位ignore
。修改后的dequeue
运行算法如下:
dequeue()
ignore
元素中的位为真,则返回 1,否则返回项目 id。修改后的enqueue
运行算法如下:
v
逐个
访问图中item的邻居节点ignore
为 true 对应于v
v
与新入队元素的连接。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.