Dijkstra's AlgorithmThe following tutorial will teach us about Dijkstra's Shortest Path Algorithm. We will understand the working of Dijkstra's Algorithm with a stepwise graphical explanation. We will cover the following:
So, let's get started. A Brief Introduction to GraphsGraphs are non-linear data structures representing the "connections" between the elements. These elements are known as the Vertices, and the lines or arcs that connect any two vertices in the graph are known as the Edges. More formally, a Graph comprises a set of Vertices (V) and a set of Edges (E). The Graph is denoted by G(V, E). Components of a Graph
The following figure shows a graphical representation of a Graph: Figure 1: Graphical Representation of a Graph In the above figure, the Vertices/Nodes are denoted with Colored Circles, and the Edges are denoted with the lines connecting the nodes. Applications of the GraphsGraphs are used to solve many real-life problems. Graphs are utilized to represent the networks. These networks may include telephone or circuit networks or paths in a city. For example, we could use Graphs to design a transportation network model where the vertices display the facilities that send or receive the products, and the edges represent roads or paths connecting them. The following is a pictorial representation of the same: Figure 2: Pictorial Representation of Transportation Network Graphs are also utilized in different Social Media Platforms like LinkedIn, Facebook, Twitter, and more. For example, Platforms like Facebook use Graphs to store the data of their users where every person is indicated with a vertex, and each of them is a structure containing information like Person ID, Name, Gender, Address, etc. Types of GraphsThe Graphs can be categorized into two types:
Undirected Graph: A Graph with edges that do not have a direction is termed an Undirected Graph. The edges of this graph imply a two-way relationship in which each edge can be traversed in both directions. The following figure displays a simple undirected graph with four nodes and five edges. Figure 3: A Simple Undirected Graph Directed Graph: A Graph with edges with direction is termed a Directed Graph. The edges of this graph imply a one-way relationship in which each edge can only be traversed in a single direction. The following figure displays a simple directed graph with four nodes and five edges. Figure 4: A Simple Directed Graph The absolute length, position, or orientation of the edges in a graph illustration characteristically does not have meaning. In other words, we can visualize the same graph in different ways by rearranging the vertices or distorting the edges if the underlying structure of the graph does not alter. What are Weighted Graphs?A Graph is said to be Weighted if each edge is assigned a 'weight'. The weight of an edge can denote distance, time, or anything that models the 'connection' between the pair of vertices it connects. For instance, we can observe a blue number next to each edge in the following figure of the Weighted Graph. This number is utilized to signify the weight of the corresponding edge. Figure 5: An Example of a Weighted Graph An Introduction to Dijkstra's AlgorithmNow that we know some basic Graphs concepts let's dive into understanding the concept of Dijkstra's Algorithm. Ever wondered how does Google Maps finds the shortest and fastest route between two places? Well, the answer is Dijkstra's Algorithm. Dijkstra's Algorithm is a Graph algorithm that finds the shortest path from a source vertex to all other vertices in the Graph (single source shortest path). It is a type of Greedy Algorithm that only works on Weighted Graphs having positive weights. The time complexity of Dijkstra's Algorithm is O(V2) with the help of the adjacency matrix representation of the graph. This time complexity can be reduced to O((V + E) log V) with the help of an adjacency list representation of the graph, where V is the number of vertices and E is the number of edges in the graph. History of Dijkstra's AlgorithmDijkstra's Algorithm was designed and published by Dr. Edsger W. Dijkstra, a Dutch Computer Scientist, Software Engineer, Programmer, Science Essayist, and Systems Scientist. During an Interview with Philip L. Frana for the Communications of the ACM journal in the year 2001, Dr. Edsger W. Dijkstra revealed: "What is the shortest way to travel from Rotterdam to Groningen, in general: from given city to given city? It is the algorithm for the shortest path, which I designed in about twenty minutes. One morning I was shopping in Amsterdam with my young fiancée, and tired, we sat down on the café terrace to drink a cup of coffee and I was just thinking about whether I could do this, and I then designed the algorithm for the shortest path. As I said, it was a twenty-minute invention. In fact, it was published in '59, three years later. The publication is still readable, it is, in fact, quite nice. One of the reasons that it is so nice was that I designed it without pencil and paper. I learned later that one of the advantages of designing without pencil and paper is that you are almost forced to avoid all avoidable complexities. Eventually, that algorithm became to my great amazement, one of the cornerstones of my fame." Dijkstra thought about the shortest path problem while working as a programmer at the Mathematical Centre in Amsterdam in 1956 to illustrate the capabilities of a new computer known as ARMAC. His goal was to select both a problem and a solution (produced by the computer) that people with no computer background could comprehend. He developed the shortest path algorithm and later executed it for ARMAC for a vaguely shortened transportation map of 64 cities in the Netherlands (64 cities, so 6 bits would be sufficient to encode the city number). A year later, he came across another issue from hardware engineers operating the next computer of the institute: Minimize the amount of wire required to connect the pins on the machine's back panel. As a solution, he re-discovered the algorithm called Prim's minimal spanning tree algorithm and published it in the year 1959. Fundamentals of Dijkstra's AlgorithmThe following are the basic concepts of Dijkstra's Algorithm:
Understanding the Working of Dijkstra's AlgorithmA graph and source vertex are requirements for Dijkstra's Algorithm. This Algorithm is established on Greedy Approach and thus finds the locally optimal choice (local minima in this case) at each step of the Algorithm. Each Vertex in this Algorithm will have two properties defined for it:
Let us understand these properties in brief. Visited Property:
Path Property:
Initially, we mark all the vertices, or nodes, unvisited as they have yet to be visited. The path to all the nodes is also set to infinity apart from the source node. Moreover, the path to the source node is set to zero (0). We then select the source node and mark it as visited. After that, we access all the neighboring nodes of the source node and perform relaxation on every node. Relaxation is the process of lowering the cost of reaching a node with the help of another node. In the process of relaxation, the path of each node is revised to the minimum value amongst the node's current path, the sum of the path to the previous node, and the path from the previous node to the current node. Let us suppose that p[n] is the value of the current path for node n, p[m] is the value of the path up to the previously visited node m, and w is the weight of the edge between the current node and previously visited one (edge weight between n and m). In the mathematical sense, relaxation can be exemplified as: p[n] = minimum(p[n], p[m] + w) We then mark an unvisited node with the least path as visited in every subsequent step and update its neighbor's paths. We repeat this procedure until all the nodes in the graph are marked visited. Whenever we add a node to the visited set, the path to all its neighboring nodes also changes accordingly. If any node is left unreachable (disconnected component), its path remains 'infinity'. In case the source itself is a separate component, then the path to all other nodes remains 'infinity'. Understanding Dijkstra's Algorithm with an ExampleThe following is the step that we will follow to implement Dijkstra's Algorithm: Step 1: First, we will mark the source node with a current distance of 0 and set the rest of the nodes to INFINITY. Step 2: We will then set the unvisited node with the smallest current distance as the current node, suppose X. Step 3: For each neighbor N of the current node X: We will then add the current distance of X with the weight of the edge joining X-N. If it is smaller than the current distance of N, set it as the new current distance of N. Step 4: We will then mark the current node X as visited. Step 5: We will repeat the process from 'Step 2' if there is any node unvisited left in the graph. Let us now understand the implementation of the algorithm with the help of an example: Figure 6: The Given Graph
Hence, the final paths we concluded are: Pseudocode for Dijkstra's AlgorithmWe will now understand a pseudocode for Dijkstra's Algorithm.
Let us now implement a pseudocode of the above illustration: Pseudocode: Explanation: In the above pseudocode, we have defined a function that accepts multiple parameters - the Graph consisting of the nodes and the source node. Inside this function, we have iterated through each node in the Graph, set their initial distance to INFINITY, and set the previous node value to NULL. We have also checked whether any selected node is not a source node and added the same into the Priority Queue. Moreover, we have set the distance of the source node to 0. We then iterated through the nodes in the priority queue, selected the node with the least distance, and marked it as visited. We then iterated through the unvisited neighboring nodes of the selected node and performed relaxation accordingly. At last, we have compared both the distances (original and temporary distance) between the source node and the destination node, updated the resultant distance with the minimum value and previous node information, and returned the final list of distances with their previous node information. Implementation of Dijkstra's Algorithm in Different Programming LanguagesNow that we have successfully understood the pseudocode of Dijkstra's Algorithm, it is time to see its implementation in different programming languages like C, C++, Java, and Python. Code for Dijkstra's Algorithm in CThe following is the implementation of Dijkstra's Algorithm in the C Programming Language: File: DijkstraAlgorithm.c Output Distance from the Source Node to 1: 4 Distance from the Source Node to 2: 12 Distance from the Source Node to 3: 19 Distance from the Source Node to 4: 12 Distance from the Source Node to 5: 8 Distance from the Source Node to 6: 10 Explanation: In the above snippet of code, we have included the stdio.h header file defined two constant values: INF = 9999 and MAX = 10. We have declared the prototyping of the function and then defined the function for Dijkstra's Algorithm as DijkstraAlgorithm that accepts three arguments - the Graph consisting of the nodes, the number of nodes in the Graph, and the source node. Inside this function, we have defined some data structures such as a 2D matrix that will work as the Priority Queue for the algorithm, an array to main the distance between the nodes, an array to maintain the record of previous nodes, an array to store the visited nodes information, and some integer variables to store minimum distance value, counter, next node value and more. We then used a nested for-loop to iterate through the nodes of the Graph and add them to the priority queue accordingly. We have again used the for-loop to iterate through the elements in the priority queue starting from the source node and update their distances. Outside the loop, we have set the distance of the source node as 0 and marked it as visited in the visited_nodes[] array. We then set the counter value as one and used the while loop iterating through the number of nodes. Inside this loop, we have set the value of minimum_distance as INF and used the for-loop to update the value of the minimum_distance variable with the minimum value from a distance[] array. We then iterated through the unvisited neighboring nodes of the selected node using the for-loop and performed relaxation. We then printed the resulting data of the distances calculated using Dijkstra's Algorithm. In the main function, we have defined and declared the variables representing the Graph, the number of nodes, and the source node. At last, we have called the DijkstraAlgorithm() function by passing the required parameters. As a result, the required shortest possible paths for every node from the source node are printed for the users. Code for Dijkstra's Algorithm in C++The following is the implementation of Dijkstra's Algorithm in the C++ Programming Language: File: DijkstraAlgorithm.cpp Output Distance from start: 4 F G D A Explanation: In the above code snippet, we included the 'iostream' and 'vector' header files and defined a constant value as MAX_INT = 10000000. We then used the standard namespace and prototyped the DijkstraAlgorithm() function. We then defined the main function of the program within, which we have called the DijkstraAlgorithm() function. After that, we declared some classes to create vertices and edges. We have also prototyped more functions to find the shortest possible path from the source vertex to the destination vertex and instantiated the Vertex and Edge classes. We then defined both classes to create the vertices and edges of the graph. We have then defined the DijkstraAlgorithm() function to create a graph and perform different operations. Inside this function, we have declared some vertices and edges. We then set the source vertex of the graph and called the Dijkstra() function to find the shortest possible distance and Print_Shortest_Route_To() function to print the shortest distance from the source vertex to vertex 'F'. We have then defined the Dijkstra() function to calculate the shortest possible distances of the all the vertices from the source vertex. We have also defined some more functions to find the vertex with the shortest distance to return all the vertices adjacent to the remaining vertex, to return the distance between two connected vertices, to check if the selected vertex exists in the graph, and to print the shortest possible path from the source vertex to the destination vertex. As a result, the required shortest path for the vertex 'F' from the source node is printed for the users. Code for Dijkstra's Algorithm in JavaThe following is the implementation of Dijkstra's Algorithm in the Java Programming Language: File: DijkstraAlgorithm.java Output Distance from Vertex 0 to Vertex 0 is 0 Distance from Vertex 0 to Vertex 1 is 1 Distance from Vertex 0 to Vertex 2 is 1 Distance from Vertex 0 to Vertex 3 is 2 Distance from Vertex 0 to Vertex 4 is 4 Distance from Vertex 0 to Vertex 5 is 4 Distance from Vertex 0 to Vertex 6 is 3 Explanation: In the above snippet of code, we have defined a public class as DijkstraAlgorithm(). Inside this class, we have defined a public method as dijkstraAlgorithm() to find the shortest distance from the source vertex to the destination vertex. Inside this method, we have defined a variable to store the number of nodes. We have then defined a Boolean array to store the information regarding the visited vertices and an integer array to store their respective distances. Initially, we declared the values in both the arrays as False and MAX_VALUE, respectively. We have also set the distance of the source vertex as zero and used the for-loop to update the distance between the source vertex and destination vertices with the minimum distance. We have then updated the distances of the neighboring vertices of the selected vertex by performing relaxation and printed the shortest distances for every vertex. We have then defined a method to find the minimum distance from the source vertex to the destination vertex. We then defined the main function where we declared the vertices of the graph and instantiated the DijkstraAlgorithm() class. Finally, we have called the dijkstraAlgorithm() method to find the shortest distance between the source vertex and the destination vertices. As a result, the required shortest possible paths for every node from the source node are printed for the users. Code for Dijkstra's Algorithm in PythonThe following is the implementation of Dijkstra's Algorithm in the Python Programming Language: File: DikstraAlgorithm.py Output Distance of A from source node: 0 Distance of B from source node: 3 Distance of C from source node: 1 Distance of D from source node: 2 Distance of E from source node: 2 Distance of F from source node: 4 Distance of G from source node: 3 Explanation: In the above snippet of code, we have imported the sys module and declared the lists consisting of the values for the nodes and edges. We have then defined a function as toBeVisited() to find which node will be visited next. We then found the total number of nodes in the graph and set the initial distances for every node. We have then calculated the minimum distance from the source node to the destination node, performed relaxation on neighboring nodes, and updated the distances in the list. We then printed those distances from the list for the users. As a result, the required shortest possible paths for every node from the source node are printed for the users. Time and Space Complexity of Dijkstra's Algorithm
Advantages and Disadvantages of Dijkstra's AlgorithmLet us discuss some advantages of Dijkstra's Algorithm:
Despite having multiple advantages, Dijkstra's algorithm has some disadvantages also, such as:
Some Applications of Dijkstra's AlgorithmDijkstra's Algorithm has various real-world applications, some of which are stated below:
The Conclusion
Next TopicHuffman Coding Algorithm |