부스트 C ++ 라이브러리 에서 피보나치 힙의 구현을 포함한다 boost/pending/fibonacci_heap.hpp
. 이 파일은 pending/
수년 동안 사용 되어 왔으며 내 계획으로는 결코 받아 들여지지 않을 것입니다. 또한, 그 구현에 버그가 있었는데, 내 지인과 만능의 멋진 남자 Aaron Windsor가 수정했습니다. 불행히도, 온라인에서 찾을 수있는 대부분의 파일 버전 (및 Ubuntu의 libboost-dev 패키지에있는 버전)에는 여전히 버그가있었습니다. Subversion 저장소에서 깨끗한 버전 을 가져와야 했습니다 .
버전 1.49 부터 Boost C ++ 라이브러리 는 피보나치 힙을 포함하여 많은 새로운 힙 구조체를 추가했습니다.
나는 컴파일 할 수 있었다 dijkstra_heap_performance.cpp을 의 수정 된 버전에 대해 dijkstra_shortest_paths.hpp 피보나치 힙 및 이진 힙을 비교. (라인 typedef relaxed_heap<Vertex, IndirectCmp, IndexMap> MutableQueue
에서으로 변경 relaxed
하십시오 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.
내가 아는 한, 이것은 피보나치 힙과 이진 힙의 근본적인 차이점을 다룹니다. 두 데이터 구조 사이의 유일한 이론적 인 차이점은 피보나치 힙이 일정한 시간에 감소 키를 지원한다는 것입니다. 반면, 이진 힙은 배열로 구현하여 많은 성능을 얻습니다. 명시적인 포인터 구조를 사용한다는 것은 피보나치 힙이 큰 성능 저하를 겪음을 의미합니다.
따라서 실제로 피보나치 힙의 이점을 얻으려면 reduce_keys 가 매우 빈번한 응용 프로그램에서 사용해야합니다. Dijkstra와 관련하여 이는 기본 그래프가 밀집되어 있음을 의미합니다. 일부 응용 프로그램은 본질적으로 reduce_key-intense 일 수 있습니다. Nagomochi-Ibaraki 최소 자르기 알고리즘 을 시도 하고 싶었지만 명백히 많은 reduce_keys를 생성하기 때문에 타이밍 비교 작업을 수행하는 데 너무 많은 노력이 필요했습니다.
경고 : 뭔가 잘못했을 수 있습니다. 이러한 결과를 직접 재현 해 볼 수 있습니다.
이론적 참고 : reduce_key에서 피보나치 힙의 향상된 성능은 Dijkstra의 런타임과 같은 이론적 응용 프로그램에 중요합니다. 피보나치 힙은 삽입 및 병합시 이진 힙보다 성능이 뛰어납니다 (피보나치 힙의 상각 상수 시간 모두). 삽입은 Dijkstra의 런타임에 영향을 미치지 않기 때문에 본질적으로 무관하며, 상각 된 일정한 시간에 삽입되도록 바이너리 힙을 수정하는 것은 매우 쉽습니다. 일정한 시간에 병합하는 것은 환상적이지만이 응용 프로그램과 관련이 없습니다.
개인 메모 : 내 친구와 나는 한때 새로운 우선 순위 대기열을 설명하는 논문을 작성했는데, 복잡하지 않고 피보나치 힙의 (이론적) 실행 시간을 복제하려고 시도했습니다. 이 논문은 출판되지 않았지만 공동 저자는 이진 힙, 피보나치 힙 및 자체 우선 순위 대기열을 구현하여 데이터 구조를 비교했습니다. 실험 결과의 그래프는 피보나치 힙이 전체 비교 측면에서 이진 힙보다 약간 성능이 우수하다는 것을 나타내며, 이는 비교 비용이 오버 헤드를 초과하는 상황에서 피보나치 힙이 더 나은 성능을 나타냅니다. 불행히도, 사용할 수있는 코드가 없으며 아마도 귀하의 상황에서 비교가 저렴하기 때문에 이러한 의견은 관련이 있지만 직접 적용 할 수는 없습니다.
또한 피보나치 힙의 런타임을 자신의 데이터 구조와 일치시키는 것이 좋습니다. 나는 단순히 피보나치 더미를 재창조한다는 것을 알았습니다. 피보나치 더미의 모든 복잡성이 임의의 아이디어라고 생각하기 전에, 나는 그것들이 모두 자연스럽고 상당히 강제적이라는 것을 깨달았습니다.