Saurav's Handbook - Shortest Path Algo
Saurav's Handbook - Shortest Path Algo
Shortest Path
Algorithm
A Mathematical Approach
Table of Contents
1. Problem Statement
2. Brute-Force Approach
3. Assumptions
7. Concept of Initialisation
8. Concept of Relaxation
9. Dijkstra’s Algorithm
A Brute Force approach would be to compute all the possible paths from a
source node s to a destination node d. Calculate the sum of distances for
every path and pick the smallest one.
But there can be a lot of possible paths to check, out of which many of them
might not be worth checking in the first place.
Here, we will look into how we can avoid checking the non optimal paths
and compute the shortest path efficiently
Assumptions
V → Set of Vertices
E → Set of Edges
And,
Splu,v) → shortest path from node u to node v
Where, {u,v} E V
We have a weighted-directed graph G(V, E). We have to prove that for a shortest
path existing between the two nodes, all the sub-paths connecting intermediate
nodes are also the shortest paths.
Let’s take the above diagram as a reference to prove the statement. Let
Sp(u, v) be the shortest path between node u and v. Also let d(a,c) be the
sub-path distance between the intermediate nodes a and c.
So,
Sp(u, v) = d(u, a) + d(a, c) + d(c, v)
If our statement is correct then the sub-path d(a, c) should be the shortest
path as well.
Let’s contradict the statement and assume that there is an even shorter path
d`(a, c) between node a and c.
Accordingly we will have a new path say Sp`(u, v) between node u and v.
Since,
d`(a, c) < d(a,c)
But, the above condition can not be true since Sp(u, v) is the shortest path
between node u and v. Hence there can be no possible path Sp’(u, v) which is
even smaller.
Hence, as a result there can not be any path d’(a, c) which is smaller than the sub-
path d(a, c) in the shortest path between node u and v.
Proved!
Shortest Path can not have cycles
In the previous path we have a cycle from node a to b and then back to a.
So, distance traversed in the cyclic path will be:
And,
Hence, for every path (Sp(u, v)) containing a cycle we have an alternate shorter
path (Sp’(u,v)) which does not have that cycle.
Proved!
We can visualise this as:
Sp(u, v) Sp’(u, v)
Shortest Path Algorithms
The shortest path algorithms aim to relax the distance between the source
node and the destination node to the smallest possible value.
A general shortest path algorithm does this using two key operations:
1. Initialisation
2. Relaxation
Initialisation
We will also have another array parent which stores the predecessor node in
the shortest path.
If,
Sp(u, v) = Sp(u -> a -> b -> v)
Then,
In the process of Initialisation we will initialise the distance of every node from
the source node with a maximum possible value.
Later, in the algorithm we will try to eventually perform better by relaxing these
distances.
distance[s] <- 0
The above algorithm does what we discussed previously. But we can also see
this line:
distance[s] <- 0
The above line makes sure that the distance of source node (s) from itself is
always 0. This is obvious!
Relaxation
In this section we will relax the distances. We will search if we can find a shorter
distance from source s to a node.
We will perform this step of Relaxation multiple times, till we get the best solution.
Let’s look at the Relaxation algorithm.
The above algorithm exactly does what we discussed earlier. Here d[u, v] is the
distance from node u to node v.
d[u, v]
distance[u]
distance[v]
If the path going from s -> u -> v is smaller than path from s -> v then we found
a better (shorter) path from node s to node v via node u.
By single-source shortest path, we mean the shortest distance of all the other
vertices of the graph from a single source vertex (say s).
Dijkstra’s algorithm maintains a set S which involves all the vertices/nodes whose
shortest distance from source s has been calculated. The algorithm keeps on
moving the nodes from set V to set S.
S Initially had all
V
the nodes
We start the algorithm with set S being empty and by the end all the reachable
nodes from source s gets moved into set S.
DIJKSTRAS(G, s):
INITIALISATION(G, s)
S <- {}
Q <- G.V
WHILE (Q != {}):
u <- EXTRACT_MIN(Q)
S <- S U {u}
FOR v IN adjacent_nodes(u):
RELAX(u, v, d[u, v])
In the above algorithm, we maintain a queue (Q). At every step we run the function
EXTRACT_MIN(Q) which extracts the node having minimum distance from the
source node s.
Once the algorithm terminates, the shortest distance of every node from
source node s will be present in the distance array.
We can also compute the shortest path for every node from the source node s by
backtracking through the parent array.
SHORTEST_PATH(u):
WHILE(u != s):
print(u)
u = parent[u]
Note: From the above explanation we can say that Dijkstra’s algorithm is a Greedy
Algorithm since it always look for the node with the minimum distance from the
source node.
Analysis of Dijkstra’s Algorithm
We discussed the Dijkstra’s algorithm in depth in our previous section. From the above
discussion we can state out two points:
1) Every node reachable from the source node is processed once and
then put into the set S.
2) For every node being processed, all its adjacent edges are relaxed
exactly once.
So,
adjacent_edges( ) = E
And,
Hence,
run_time = (V * extract_min(Q) + E)
We can see that the runtime of the algorithm depends upon the time taken to
extract the minimum node from the Queue.
Implementation 1:
So,
extract_min(Q) = V
Hence,
run_time = V * V + E
= V+E
= O(V + E)
O(V + E) ~ O(V )
Implementation 2:
Hence,
run_time = V * log(V) + E
= V.log(V) + E
= O(V.log(V) + E)
O(V.log(V) + E)
Hope this handbook helped you
in clearing out the concept of
Shortest Path Algorithms.