【问题标题】:Priority Queue - Skip List vs. Fibonacci Heap优先队列 - 跳过列表与斐波那契堆
【发布时间】:2011-10-14 09:41:36
【问题描述】:

我有兴趣实现一个优先级队列以启用一个高效的 Astar 实现,该实现也相对简单(我的意思是优先级队列很简单)。

似乎因为跳过列表提供了一个简单的 O(1) 提取最小操作和一个 O(Log N) 的插入操作,它可能与更难实现的具有 O(log N) 的斐波那契堆竞争) extract-Min 和 O(1) 插入。我认为 Skip-List 对于节点稀疏的图会更好,而斐波那契堆对于节点更密集的环境会更好。

这可能会使斐波那契堆通常更好,但我假设 Big-Oh 明智的做法是正确的吗?

【问题讨论】:

  • 通常的二进制最小堆有什么问题?

标签: algorithm heap priority-queue skip-lists fibonacci-heap


【解决方案1】:

斐波那契堆存在的理由是 O(1) 递减键操作,使 Dijkstra 算法能够在 O(|V| log |V| + |E|) 时间内运行。然而,在实践中,如果我需要一个有效的递减键操作,我会使用配对堆,因为斐波那契堆有可怕的常数。如果您的键是小整数,则使用 bin 可能会更好。

【讨论】:

  • (如果你想要简单且合理高效,很难比标准库做得更好。)
  • 斐波那契堆无论如何都难以实现,主要是理论上的兴趣。联合操作的运行时间为 O(1),这是人们可能想要探索此数据结构的另一个原因。
【解决方案2】:

斐波那契堆非常非常非常慢,除了非常非常非常大且密集的图(数亿条边的数量级)。众所周知,它们也很难正确实施。

另一方面,跳过列表是非常好的数据结构,实现起来也相对简单。

但是我想知道您为什么不考虑使用简单的二进制堆。我相信基于二进制堆的优先级队列甚至比基于跳过列表的优先级队列还要快。跳过列表主要用于利用并发性。

【讨论】:

  • 单独的二叉堆是行不通的,因为它需要 O(n) 才能找到一个特定的节点并更新它的优先级(在这种情况下,是到源的聚合距离)。但是,您可以为节点的 O(1) 位置引入额外的 unordered_map,然后它将复杂度降低到 O(logn),这是在优先级更新后“heapify”的瓶颈给出的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-29
  • 2015-06-05
  • 2017-07-08
  • 1970-01-01
相关资源
最近更新 更多