Biblioteki Boost C ++ zawierają implementację stert Fibonacciego w boost/pending/fibonacci_heap.hpp
. Ten plik najwyraźniej istnieje pending/
od lat i według moich prognoz nigdy nie zostanie zaakceptowany. Ponadto w tej implementacji pojawiły się błędy, które zostały naprawione przez mojego znajomego i ogólnie fajnego gościa, Aarona Windsora. Niestety, większość wersji tego pliku, które udało mi się znaleźć w sieci (i ta w pakiecie libboost-dev Ubuntu) nadal zawierała błędy; Musiałem pobrać czystą wersję z repozytorium Subversion.
Od wersji 1.49 biblioteki Boost C ++ dodały wiele nowych struktur stert, w tym stertę Fibonacciego.
Udało mi się skompilować dijkstra_heap_performance.cpp ze zmodyfikowaną wersją dijkstra_shortest_paths.hpp, aby porównać sterty Fibonacciego i sterty binarne. (W wierszu typedef relaxed_heap<Vertex, IndirectCmp, IndexMap> MutableQueue
zmień relaxed
na fibonacci
.) Najpierw zapomniałem skompilować z optymalizacjami, w którym to przypadku stosy Fibonacciego i binarne działają mniej więcej tak samo, przy czym sterty Fibonacciego zwykle osiągają niewiele lepsze wyniki. Po skompilowaniu z bardzo silnymi optymalizacjami stosy binarne uzyskały ogromny wzrost. W moich testach stosy Fibonacciego przewyższały stosy binarne tylko wtedy, gdy wykres był niewiarygodnie duży i gęsty, np .:
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.
O ile rozumiem, dotyka to podstawowych różnic między stertami Fibonacciego a stertami binarnymi. Jedyną prawdziwą teoretyczną różnicą między tymi dwiema strukturami danych jest to, że sterty Fibonacciego obsługują klucz zmniejszania w (amortyzowanym) stałym czasie. Z drugiej strony, stosy binarne uzyskują dużą wydajność dzięki ich implementacji jako tablicy; użycie jawnej struktury wskaźnika oznacza, że stosy Fibonacciego mają ogromny wpływ na wydajność.
Dlatego, aby w praktyce skorzystać ze stosów Fibonacciego , trzeba ich używać w aplikacji, w której klawisze zmniejszania są niezwykle częste. W przypadku Dijkstry oznacza to, że bazowy wykres jest gęsty. Niektóre aplikacje mogą z natury rzeczy intensywnie zmniejszać_klucz; Chciałem wypróbować algorytm minimalnego cięcia Nagomochi-Ibaraki, ponieważ najwyraźniej generuje on wiele klawiszy zmniejszania, ale uzyskanie porównania czasu było zbyt dużym wysiłkiem.
Ostrzeżenie : mogłem zrobić coś złego. Możesz spróbować samodzielnie odtworzyć te wyniki.
Uwaga teoretyczna : Poprawiona wydajność stert Fibonacciego na zmniejsz_klucz jest ważna dla zastosowań teoretycznych, takich jak środowisko uruchomieniowe Dijkstry. Sterty Fibonacciego również przewyższają sterty binarne przy wstawianiu i scalaniu (obie amortyzowane w czasie stałym dla stert Fibonacciego). Wstawianie jest zasadniczo nieistotne, ponieważ nie wpływa na czas działania Dijkstry i dość łatwo jest zmodyfikować sterty binarne, aby również wstawiać w amortyzowanym stałym czasie. Scalanie w stałym czasie jest fantastyczne, ale nie dotyczy tej aplikacji.
Uwaga osobista : Razem z moim przyjacielem napisaliśmy kiedyś artykuł wyjaśniający nową kolejkę priorytetową, która próbowała odtworzyć (teoretyczny) czas działania stosów Fibonacciego bez ich złożoności. Artykuł nigdy nie został opublikowany, ale mój współautor zaimplementował stosy binarne, sterty Fibonacciego i naszą własną kolejkę priorytetową do porównywania struktur danych. Wykresy wyników eksperymentalnych wskazują, że stosy Fibonacciego nieznacznie przewyższają wykonane stosy binarne pod względem całkowitych porównań, co sugeruje, że stosy Fibonacciego działałyby lepiej w sytuacji, gdy koszt porównania przewyższa koszty ogólne. Niestety nie mam dostępnego kodu i prawdopodobnie w twojej sytuacji porównanie jest tanie, więc te komentarze są istotne, ale nie mają bezpośredniego zastosowania.
Nawiasem mówiąc, bardzo polecam próbę dopasowania środowiska wykonawczego stosów Fibonacciego do własnej struktury danych. Odkryłem, że sam wymyśliłem na nowo stosy Fibonacciego. Wcześniej pomyślałem, że wszystkie zawiłości stosów Fibonacciego były przypadkowymi pomysłami, ale potem zdałem sobie sprawę, że wszystkie są naturalne i dość wymuszone.