This project compares the performance of two different priority queue implementations:
-
Binary Heap
-
Fibonacci Heap
The goal is to evaluate their performance across different operations and analyze their theoretical vs. experimental behavior.
A detailed research paper is included in this repository, discussing the design, analysis, and benchmarking of both heap implementations. Download (PDF)
Binary and Fibonacci Heap Implementation
-
Insert (
insert) Insert a new element into the heap -
Extract-Min (
extract) Extract the root element of the heap -
Decrease-key (
decrease_key) Decrease the key of a given element -
Merge (
merge) Merge another heap for the same type -
Display (
display) Return a string representation of the heap
All benchmarks below were run on descending-ordered input to simulate worst-case scenarios. Each data point is averaged over multiple trials and input sizes.
-
Insert (
benchmark_insert)
Measures total time to insertndescending elements into an empty heap. -
Extract-Min (
benchmark_extract)
Insertsnelements, then extracts the minimum until the heap is empty. Reflects consolidation cost in Fibonacci Heaps. -
Merge (
benchmark_merge)
Merges two pre-filled heaps of equal size. Evaluated for both Binary and Fibonacci Heaps. -
Decrease-Key (
benchmark_[heap]_decrease_key_timed_isolated)
Measures the average time for a single decrease-key operation on a freshly constructed heap.
For Fibonacci Heaps, this captures cascading cuts. -
Memory Usage (
benchmark_memory_usage)
Peak memory usage measured usingtracemallocduring heap construction.
These benchmarks isolate the structural cost (not runtime) of a single decrease-key call.
-
Fibonacci Heap Cuts (
benchmark_fibonacci_decrease_key_cuts_isolated)
Tracks how many cuts (i.e., child removals) happen during a decrease-key. -
Binary Heap Swaps (
benchmark_binary_decrease_key_swaps_isolated)
Tracks how many swaps are needed to bubble up a worst-case node.
These tests help demonstrate the hidden structural cost behind decrease_key, which runtime benchmarks might not capture alone.
We ran a version of Dijkstra’s Algorithm with lazy deletion and periodic heap merges:
- Benchmarks tested across graphs of varying size and density
- Compares total runtime and peak memory usage
- Uses both Binary and Fibonacci Heaps as the underlying priority queue
This shows how each heap performs in real-world graph applications, especially when merge frequency is high.
abc– ProvidesABC(Abstract Base Classes)gc– Garbage collection interfaceos– Interact with the operating systemsys– System-specific parameters and functionstime– Time-related functions for performance benchmarkingrandom– Random number generationtracemalloc– Memory profiling and trackingtyping– Provides type hints (List,Optional,Generic,TypeVar)
matplotlibData visualization (for plotting graphs)seabornStatistical data visualization (enhanced graph aesthetics).pandasData analysis and manipulation.tkintersGUI framework (used for creating the benchmark viewer).
Run the following command to install are the required external libaries:
pip install -r requirements.txt- Miller Fourie: Core heap implementations, benchmarking code, Dijkstra's algorithm, runtime measurement, data analysis.
- Owen Zgurski: Analyzed and validated merge benchmarks.
- kobs3720: Evaluated decrease-key performance and structural impact.