Die Boost C ++ - Bibliotheken enthalten eine Implementierung von Fibonacci-Heaps in boost/pending/fibonacci_heap.hpp
. Diese Datei ist anscheinend seit pending/
Jahren in und wird von meinen Projektionen nie akzeptiert. Außerdem gab es Fehler in dieser Implementierung, die von meinem Bekannten und rundum coolen Aaron Windsor behoben wurden. Leider hatten die meisten Versionen dieser Datei, die ich online finden konnte (und die in Ubuntus libboost-dev-Paket), immer noch die Fehler; Ich musste eine saubere Version aus dem Subversion-Repository ziehen.
Seit Version 1.49 haben Boost C ++ - Bibliotheken viele neue Heap-Strukturen hinzugefügt, einschließlich Fibonacci-Heap.
Ich konnte dijkstra_heap_performance.cpp gegen eine modifizierte Version von dijkstra_shortest_paths.hpp kompilieren , um Fibonacci-Heaps und binäre Heaps zu vergleichen. ( typedef relaxed_heap<Vertex, IndirectCmp, IndexMap> MutableQueue
Wechseln Sie relaxed
in der Zeile zu fibonacci
.) Ich habe zuerst vergessen, mit Optimierungen zu kompilieren. In diesem Fall funktionieren Fibonacci-Heaps und binäre Heaps ungefähr gleich, wobei Fibonacci-Heaps normalerweise eine unbedeutende Leistung erbringen. Nachdem ich mit sehr starken Optimierungen kompiliert hatte, erhielten binäre Heaps einen enormen Schub. In meinen Tests übertrafen Fibonacci-Heaps nur dann binäre Heaps, wenn der Graph unglaublich groß und dicht war, z.
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.
Soweit ich weiß, berührt dies die grundlegenden Unterschiede zwischen Fibonacci-Haufen und binären Haufen. Der einzige wirkliche theoretische Unterschied zwischen den beiden Datenstrukturen besteht darin, dass Fibonacci-Haufen die Abnahme des Schlüssels in (amortisierter) konstanter Zeit unterstützen. Auf der anderen Seite erzielen binäre Heaps durch ihre Implementierung als Array eine hohe Leistung. Die Verwendung einer expliziten Zeigerstruktur bedeutet, dass Fibonacci-Haufen einen enormen Leistungseinbruch erleiden.
Um von Fibonacci-Haufen in der Praxis zu profitieren , müssen Sie sie daher in einer Anwendung verwenden, in der Abnahmeschlüssel unglaublich häufig sind. In Bezug auf Dijkstra bedeutet dies, dass der zugrunde liegende Graph dicht ist. Einige Anwendungen können von Natur aus abnehmungsintensiv sein. Ich wollte den Nagomochi-Ibaraki-Minimum-Cut-Algorithmus ausprobieren, da er anscheinend viele Abnahmeschlüssel generiert, aber es war zu aufwendig , einen Timing-Vergleich zum Laufen zu bringen.
Warnung : Ich habe möglicherweise etwas falsch gemacht. Möglicherweise möchten Sie versuchen, diese Ergebnisse selbst zu reproduzieren.
Theoretischer Hinweis : Die verbesserte Leistung von Fibonacci-Heaps auf minus_key ist wichtig für theoretische Anwendungen wie die Laufzeit von Dijkstra. Fibonacci-Heaps übertreffen auch binäre Heaps beim Einfügen und Zusammenführen (beide amortisierte konstante Zeit für Fibonacci-Heaps). Das Einfügen ist im Wesentlichen irrelevant, da es die Laufzeit von Dijkstra nicht beeinflusst und es ziemlich einfach ist, binäre Heaps so zu ändern, dass sie auch in einer amortisierten konstanten Zeit eingefügt werden. Das Zusammenführen in konstanter Zeit ist fantastisch, aber für diese Anwendung nicht relevant.
Persönliche Anmerkung : Ein Freund von mir und ich haben einmal ein Papier geschrieben, in dem eine neue Prioritätswarteschlange erklärt wurde, in der versucht wurde, die (theoretische) Laufzeit von Fibonacci-Haufen ohne deren Komplexität zu replizieren. Das Papier wurde nie veröffentlicht, aber mein Co-Autor hat binäre Heaps, Fibonacci-Heaps und unsere eigene Prioritätswarteschlange implementiert, um die Datenstrukturen zu vergleichen. Die Grafiken der experimentellen Ergebnisse zeigen, dass Fibonacci-Heaps die binären Heaps in Bezug auf Gesamtvergleiche leicht übertrafen, was darauf hindeutet, dass Fibonacci-Heaps in einer Situation, in der die Vergleichskosten den Overhead übersteigen, eine bessere Leistung erbringen würden. Leider habe ich den Code nicht zur Verfügung und vermutlich ist der Vergleich in Ihrer Situation billig, daher sind diese Kommentare relevant, aber nicht direkt anwendbar.
Im Übrigen empfehle ich dringend, die Laufzeit von Fibonacci-Heaps mit Ihrer eigenen Datenstruktur abzugleichen. Ich fand heraus, dass ich Fibonacci-Haufen einfach neu erfunden habe. Früher dachte ich, dass alle Komplexitäten von Fibonacci-Haufen zufällige Ideen waren, aber danach wurde mir klar, dass sie alle natürlich und ziemlich erzwungen waren.