Performance 有没有人真正有效地实现了斐波那契堆?

Performance 有没有人真正有效地实现了斐波那契堆?,performance,algorithm,language-agnostic,data-structures,fibonacci-heap,Performance,Algorithm,Language Agnostic,Data Structures,Fibonacci Heap,你们中有人实施过一个?我在几年前就这样做了,但它比使用基于数组的二进制堆慢几个数量级 当时,我认为这是一个宝贵的教训,说明研究并不总是像它声称的那样好。然而,许多研究论文声称他们的算法的运行时间是基于使用斐波那契堆 您是否曾经成功地实现过高效的实现?或者您使用的数据集如此之大以至于斐波那契堆更加高效?如果是这样,请提供一些详细信息。在boost/pending/Fibonacci\u heap.hpp中包括Fibonacci堆的实现。该文件显然已处于待定状态/多年,根据我的预测,它将永远不会被接

你们中有人实施过一个?我在几年前就这样做了,但它比使用基于数组的二进制堆慢几个数量级

当时,我认为这是一个宝贵的教训,说明研究并不总是像它声称的那样好。然而,许多研究论文声称他们的算法的运行时间是基于使用斐波那契堆

您是否曾经成功地实现过高效的实现?或者您使用的数据集如此之大以至于斐波那契堆更加高效?如果是这样,请提供一些详细信息。

boost/pending/Fibonacci\u heap.hpp
中包括Fibonacci堆的实现。该文件显然已处于
待定状态/
多年,根据我的预测,它将永远不会被接受。此外,该实现中也存在一些bug,这些bug是由我的熟人兼全能酷哥亚伦·温莎(Aaron Windsor)修复的。不幸的是,我可以在网上找到该文件的大多数版本(以及Ubuntu的libboost开发包中的版本)仍然存在bug;我必须从Subversion存储库中提取

自从版本添加了很多新的堆结构,包括斐波那契堆

我能够根据的修改版本进行编译,以比较斐波那契堆和二进制堆。(在
typedef relaxed\u heap MutableQueue
行中,将
relaxed
更改为
fibonacci
)我首先忘记了使用优化进行编译,在这种情况下,fibonacci和二进制堆的性能大致相同,fibonacci堆的性能通常不太好。在我使用非常强大的优化进行编译之后,二进制堆得到了巨大的提升。在我的测试中,Fibonacci堆仅在图形非常大且密集时优于二进制堆,例如:

Generating graph...10000 vertices, 20000000 edges.
Running Dijkstra's with binary heap...1.46 seconds.
Running Dijkstra's with Fibonacci heap...1.31 seconds.
Speedup = 1.1145.
据我所知,这涉及到斐波那契堆和二进制堆之间的根本区别。这两种数据结构之间唯一真正的理论区别是斐波那契堆支持减少键入(摊销)常数时间。另一方面,二进制堆作为一个数组实现,可以获得很大的性能;使用显式指针结构意味着Fibonacci堆将遭受巨大的性能损失

因此,为了在实践中受益于斐波那契堆,您必须在一个应用程序中使用它们,在这个应用程序中,减少_键的频率非常高。就Dijkstra而言,这意味着基础图是稠密的。某些应用程序可能本质上是键密集型的;我想尝试一下,因为它显然会生成很多减少键,但要让计时比较工作起来太费劲了

警告:我可能做错了什么。您可能希望自己尝试复制这些结果

理论提示:decrease_键上Fibonacci堆的改进性能对于理论应用(如Dijkstra的运行时)非常重要。Fibonacci堆在插入和合并方面也优于二进制堆(Fibonacci堆的摊销固定时间)。插入在本质上是不相关的,因为它不会影响Dijkstra的运行时,而且修改二进制堆使其在摊销常量时间内也具有插入也相当容易。在固定时间内合并非常棒,但与此应用程序无关

个人提示:我和我的一个朋友曾经写过一篇文章,解释了一个新的优先级队列,它试图复制斐波那契堆的(理论)运行时间,而不需要复杂度。这篇论文从未发表过,但我的合作者实现了二进制堆、斐波那契堆和我们自己的优先级队列来比较数据结构。实验结果的图表表明,就总体比较而言,Fibonacci堆的性能略优于二进制堆,这表明在比较成本超过开销的情况下,Fibonacci堆的性能会更好。不幸的是,我没有可用的代码,并且可能在您的情况下比较便宜,因此这些注释是相关的,但不直接适用


顺便说一句,我强烈建议尝试将斐波那契堆的运行时与您自己的数据结构相匹配。我发现我自己只是重新发明了斐波那契堆。在我认为斐波那契堆的所有复杂性都是一些随机的想法之前,但后来我意识到它们都是自然的和相当强制的。

Knuth在1993年为他的书对最小生成树的斐波那契堆和二进制堆进行了比较。他发现,在他测试的图形大小上,斐波那契比二进制堆慢30到60个百分点,在不同密度下有128个顶点。
在MILES_SPAN一节中是C(或者更确切地说是C、math和TeX之间的交叉点)。

免责声明

我知道结果非常相似,“看起来运行时间完全由堆以外的东西控制”(@Alpedar)。但我在密码里找不到任何证据。 代码是开放的,所以如果你能找到任何影响测试结果的东西,请告诉我


也许我做错了什么,但根据anwser的比较:

  • 斐波那契堆
  • D元堆(4)
  • 二进制堆
  • 松散堆
所有堆的执行时间(仅针对完整图)非常接近。 测试是针对具有100020003004000500060007000和8000个顶点的完整图形进行的。对于每个测试,生成50个随机图,输出为每个堆的平均时间:

很抱歉,输出不太详细,因为我需要它来从文本文件构建一些图表


以下是结果(以秒为单位):


我还用斐波那契堆做了一个小实验。以下是有关详细信息的链接:。我只是在谷歌上搜索了术语“Fibonacci堆java”,并尝试了Fibonacci堆的一些现有开源实现。它是