Introduction

This article introduces a powerful data structure in network optimization – Fibonacci Heaps. First, consider a common binary heap, where every node as at most two children, which must both have a lesser key value. For Fibonacci Heaps, we reject this restriction. So every node can have any number of children. Furthermore, there exists no single root element, but a list of roots, whereas the root with the minimum key is distinguished by a head pointer.

This special heap also has different operations, which are in general not as expensive as for binary heaps. The operations decrease_key, make_heap, insert, and meld can be done in time O(1). The most time-consuming operation is delete_min in time O(log n).

This article should also present the usage of Fibonacci Heaps for a faster implementation of Dijkstra's algorithm for network optimization.

Fibonacci Heaps in detail

First, let us define a Fibonacci Heap:

A Fibonacci Heap is a Heap with a list of root elements. Every node in the heap can have any number of children. Elements are sorted in heap-order: a node does not have a greater key value than the lowest key of its children.

How does a node look like?

Which requirements do we have for a single node of the heap?

For comparison: in a binary heap, every node has 4 pointers: 1 to its parent, 2 to its children, and 1 to the data.

Since we have an unknown number of children in Fibonacci heaps, we have to arrange the children of a node in a linked list. So, we need at most two pointers to the siblings of every node. This results in a linear double-linked list. Now, we need another pointer to any node of the children list and to the parent of every node. All in all, there are 5 pointers:

left sibling

right sibling

parent

children

data

Furthermore, we define a rank for every node, which says how many children a node has.

Now, consider the operations for such a node element which are required for the Fibonacci heap implementation.

Heap node operations

Now, we are ready to implement the node operations.

The required operations are:

AddChild

Adds a child node to the current node by inserting it into the children list and linking it. This operation is done in time O(1).

AddSibling

Adds a node into the children list the current node belongs to. This is done in time O(1) too.

Remove

Removes the node from the sibling list and refreshes the affected pointers. This is also done in time O(1).

Fibonacci Heap operations

Now the Fibonacci Heap can be implemented. The tree of nodes is accessed by a distinguished pointer to the node with the lowest value. This element is located in the root list and has no parent. Otherwise, the heap-order would be violated.

The basic operations are:

insertNode

Inserts a node into the root list and checks whether its value is lower than the currently lowest node and changes the access pointer if necessary. The time for this operation is O(1).

Decreases the value of a specified node. Then the node is removed from its sibling list and is inserted into the root list. At least, it is checked whether the access pointer needs to be changed. This operation needs time O(1).

Copies all children of the node referenced by the access pointer into the root list. After each insertion, a linking step is done if necessary. At least the minimum element is deleted, and the node with the minimum key is determined. The amortized time depends on the count of children of the minimum node. In the worst case, for each child, a removing, inserting, and linking operation required. This takes time O(log n).

Now we have implemented all the necessary operations for the Dijkstra's algorithm we will discuss in the next part.

Dijkstra's algorithm using Fibonacci Heaps

The concept of Dijkstra

Dijkstra's algorithm works the following way. Beginning at the target vertex, it checks for each vertex, which has an incoming edge to the current one; if the path over the current vertex is shorter than the previously found one, it replaces it. Then, the same operation is done for this vertex. The algorithm is aborted when all vertices have been scanned. This operation is called scan for the following reason.

To summarize, a scan can be described by these steps:

Find all vertices, which are the head of an edge, whose tail is the current node.

For each of these vertices, check whether the best found way can be improved by going the way over the current vertex and the edge between these vertices.

Implementation of Dijkstra's algorithm

The actual Dijkstra algorithm is very simple. Beginning with the source vertex, we do a scan and mark the vertex as scanned. Then, we repeat this step with the vertices which have an edge with the head on the source vertex. Then, we repeat the scan for all vertices which have an edge to the last scanned vertex.

During the algorithm, a node can have three states: LABELED, UNLABELED, and SCANNED. Nodes are marked labels when the shortest path to the target is found. A node is unlabeled when there is no path found yet (initial state), and labeled when a path is found, but when maybe a shorter one exists.

After this algorithm, we have the predecessor for every node in the pred pointer. This points to the next vertex of the shortest path to the target. The result is that we have the shortest path to the target for every vertex. We just have to follow the predecessors:

Share

About the Author

Since 2006 I study technical mathematics at Dresden University of Technology and since 2008 I work than working student at SAP Research in Dresden. My programming interests are developing and implementing algorithms for solving mathematical problems in C/C++, especially optimization.

Let me first congratulate you on your awesome code. I was debugging my own program when this caught my eye. In the leftMostSibling function, you're checking if this == NULL. This is generally an undefined code. However because of the way most compilers are designed you're actually getting away with this and in return getting the desired result/behavior. I understand this is a acceptable hack but according to c++ standard it is not OK.

I suggest the following replacement which basically does the same thing.

Hi,Let me thank you for implementing such a beautiful project over Dijkstra's using Fibonacci heap. I have a doubt, whats the 4th field in the input data. I scanned the code, and to my scanned knowledge, I didn't find any reference to it. If I am mistaken, kindly correct it. I am trying to incorporate geometry with Dijkstra as a project.Also there are some edges with length 0. What is its significance?

Hi i am a new programmer and i know how the dijkstra's algorith works , but i still have some problems , and some questions to ask , firstlywhat does the 4 arguments in the scotland fil mean ( vertex vertex weight .. ?? ) thank you for the project its really helpful [ ]Fin de la conversation

Can I ask something else. When I run your example everything is OK, but when I add your code to a Thread ( to speed up my project ) I get memory leaks for every new vertice, edge and for the FibonacciHeap, which is expected and is allright, but when at the end of the thread I try do delete them I get heap errors. Any advice on how to fix that?

thank u for this work , it s really useful , but i still have some problems :/ after compiling the hole project , and run Dijkstra.cpp nothing happens it appears a second and disappear ! what should i do ??

As the message is telling you, you have to specify a program argument. This is the name of the graph file.I added such a file in the Package - scotland_big.dat.

When you want to start the program from command line interface, navigate to the directory and type "Dijkstra.exe scotland_big.dat". This works for both Windows and Linux.

If you are using Visual Studio and want to start the program directly you can set some program arguments in the menu"Configuration and Properties -> Debugging -> Command Line Arguments".Adding the line "scotland_big.dat" should do what you need.

i am using Dev C++ i understood that the function needs an argument, but while running the program i cannot type anything in the command line interface ... i had some problems while compiling , so i created a new empty project and add the files downloaded from here ... and still have the some problem :/ thanks Mister MAX

hi,I would like to thank you for this code.It is the best code online.However,I was wondering if we can find the shortest distance for all pair of nodes.I tried using loop to compute all distance but couldn't get the right answer.If you could tell me how to implement it,it will be of great help.Thanks...

Notice that this algorithm generates a shortest-path tree. This means that it will find the shortest path from an arbitrary node to a end node. Therefore you have to go along the implicitly defined path beginning at your start node: