高效的嵌套优先级队列

时间:2017-01-20 03:42:43

标签: algorithm data-structures priority-queue

我正在寻找一种数据结构/算法(不是多线程),它本质上是一个嵌套的优先级队列。那就是:

  1. 要采取的下一个要素是具有最高优先级的要素。
  2. 元素可以是具有优先级的简单元素,也可以是另一个优先级队列(尽管我的目的可以限制一个嵌套级别)。无论嵌套级别如何,队列/子队列/子子队列/等中具有最高优先级的元素都是选择的nexxt。
  3. 可以在任何级别添加或删除元素,但简单节点永远不会变成子队列(或反之亦然)。
  4. 插入后,简单元素的优先级不会改变。
  5. 我无法想出任何有效/优雅的东西,谷歌搜索没有发现任何东西。

1 个答案:

答案 0 :(得分:1)

我实际上并没有建立这个,但我对这个想法做了一些非常广泛的分析,看起来它应该可行。我称之为队列队列。我之所以没有构建它的原因是因为我构建它的项目在我需要队列之前被取消了。

首先,我决定将“简单元素”改为包含单个元素的优先级队列。无需管理两种不同类型的元素简化了设计,分析表明它不应以任何重要方式影响性能。

由于子队列的优先级可以在添加新项目或从中删除项目时发生更改,因此我选择使用Pairing heap作为主队列和子队列。当您必须进行大量优先级更改时,配对堆比二进制堆执行得更好。二进制堆的问题是,如果要更改项的优先级,则必须先找到该项。在二进制堆中,这是一个O(n)操作。在配对堆中,优先级更改的分摊成本为O(log n),因为您已经拥有对该节点的引用。

所以我的想法是,如果你要添加一个新的子队列,你只需将它添加到主队列中,它就会被放到适当的位置。如果要更新子队列,则添加或删除该项(在子队列上为O(log n)),然后调整子队列在主队列中的位置(即O(log n) )在主队列上。)

我的所有分析都表示这应该可以很好地工作,尽管我仍然不确定它对多线程的效果如何。我我很清楚如何同步访问并且不会因为每次插入和删除而最终阻塞整个队列,除非是非常短暂的时间。我想我会发现是否构建它。 可能可以创建一个无锁的并发配对堆。

我之所以选择Pairing堆是因为它在重新排序键方面表现更好,而且因为它比Fibonacci堆或许多其他堆更容易实现,虽然它的渐近性能比Fibonacci堆慢,但它的真实世界表现要好得多。我唯一的缺点是配对堆将占用比等效二进制堆更多的内存。这是旧的时间/空间权衡。

另一种选择是实现skip list优先级队列,该队列还具有O(log n)性能,用于插入和更改优先级。我已经看到了无锁并发跳过列表实现。在C中实现高效的跳过列表并不困难,因为它可以很好地处理可变记录大小。在C#和其他不允许您构建不同长度结构的语言中,跳过列表可能是真正的内存耗尽。

正如我所说,我从来没有真正构建过这个东西,但是我所有的研究和设计笔记都告诉我,它应该相当容易构建并且应该表现得非常好。