Unit III- Graphs
Basic Terminologies related to graph:
[Link]:
A graph G is defined as G = {V, E} where V is a set of all vertices or points and E is the set of all edges in the graph.
Example 1
2. Vertex
A vertex is a synonym of point in graph i.e. one of the points on which the graph is defined and which may be connected
by lines/edges is called a vertex.
3. Edge
Edge is the connection between two vertices. Each edge connects one vertex to another vertex in the graph. Edge can
either be directed or undirected. A directed edge is the edge which points from one vertex to another, and an undirected
edge has no direction.
[Link] of a node:
The degree of a node is the number of edges connected to the node.
[Link]-degree of a node:
The in-degree of a node is the number of incoming edges for that node
[Link]-degree of a node:
The out-degree of a node is the number of outgoing edges from that node.
Types of Graphs
1. Undirected Graph
An undirected graph is a graph whose edges are not directed.
Example
In the above graph since there is no directed edges, therefore it is an undirected graph.
2. Directed Graph
A directed graph is a graph in which the edges are directed by arrows.
Directed graph is also known as digraphs.
Example
In the above graph, each edge is directed by the arrow. A directed edge has an arrow from A to B, means A is related
to B, but B is not related to A.
3. Weighted Graph
A weighted graph is a graph whose edges have been labeled with some weights or numbers.
The length of a path in a weighted graph is the sum of the weights of all the edges in the path.
Example
In the above graph, if path is a -> b -> c -> d -> e -> g then the length of the path is 5 + 4 + 5 + 6 + 5 = 25.
Graph Representations
A graph representation is a technique to store graph into the memory of computer.
There are different ways to optimally represent a graph, depending on the density of its edges, type of operations to be
performed and ease of use.
1. Adjacency Matrix
o Adjacency matrix is a sequential representation.
o It is used to represent which nodes are adjacent to each other. i.e. is there any edge connecting nodes to a graph.
o In this representation, If we have N vertices in a given graph then we have to construct a N * N matrix A. If
there is any edge from a vertex i to vertex j, then the corresponding element of A, ai,j = 1, otherwise ai,j= 0.
o If there is any weighted graph then instead of 1s and 0s, we can store the weight of the edge.
Example
Consider the following undirected graph representation:
Undirected graph representation
Directed graph represenation
See the directed graph representation:
In the above examples, 1 represents an edge from row vertex to column vertex, and 0 represents no edge from row
vertex to column vertex.
Undirected weighted graph represenation
Pros: Representation is easier to implement and follow.
Cons: It takes a lot of space and time to visit all the neighbors of a vertex, we have to traverse all the vertices in the
graph, which takes quite some time.
[Link] List
o Adjacency list is a linked representation.
o In this representation, for each vertex in the graph, we maintain the list of its neighbors. It means, every vertex
of the graph contains list of its adjacent vertices.
o We have an array of vertices which is indexed by the vertex number and for each vertex v, the corresponding
array element points to a singly linked list of neighbors of v.
Example 1:
Representing undirected unweighted graph using adjacency list and adjacency matrix
Example 2:
Directed unweighted graph representation implemented using adjacency list:
Example 3:
o Directed weighted graph representation using adjacency list:
Pros:
o Adjacency list saves lot of space.
o We can easily insert or delete as we use linked list.
o Such kind of representation is easy to follow and clearly shows the adjacent nodes of node.
Cons:
o The adjacency list allows testing whether two vertices are adjacent to each other but it is slower to support this
operation.
[Link] Multilists:
o In the adjacency list representation of an undirected graph each edge (vi,vj) is represented by two entries, one
on the list for vi and the other on the list for vj.
o In some situations it is necessary to be able to determine the second entry for a particular edge and mark that
edge as already having been examined. This can be accomplished easily if the adjacency lists are actually
maintained as multilists (i.e., lists in which nodes may be shared among several lists). For each edge there
will be exactly one node, but this node will be in two lists, i.e., the adjacency lists for each of the two nodes it
is incident to. The node structure is as follows:
o M is a one bit mark field that may be used to indicate whether or not the edge has been examined. The
storage requirements are the same as for normal adjacency lists except for the addition of the mark bit M.
The lists are:
vertex 1: N1 N2 N3
vertex 2: N1 N4 N5
vertex 3: N2 N4 N6
vertex 4: N3 N5 N6
Graph Traversal:
Graph Traversal involves the process of visiting and exploring each vertex or node in a graph. Two fundamental
techniques for this are Breadth-First Search (BFS) and Depth-First Search (DFS).
[Link]-First Search
In breadth-first-search (BFS), you start at a particular vertex, and the algorithm tries to visit all the neighbors at the
given depth before moving on to the next level of traversal of vertices.
BFS algorithm uses a queue to remember to get the next vertex to start a search when a dead end occurs in any iteration.
Example of BFS
Pseudocode:
//assumptions:
//G is graph
//q: queue for storing nodes with enqueue(), dequeue() and empty() operations
//visited[]:Array for storing current status of node (visited or unvisited)
1. DFS(G,s) //( s is the vertex where the search starts )
2. Queue q := []; // ( start with an empty queue )
3. for each vertex v
4. set visited[v] := false;
5. [Link](s); //insert starting node v on the queue
6. while ( [Link]() not true ) do
7. {
8. x = [Link](); //delete front node from queue call it x
9. if ( x has not been visited )
10. {
11. visited[x] = true; // Visit node x (print node x)
12.
13. for ( every adjacent node y of x )
14. if ( y has not been visited )
15. [Link](y)
16. }
17. }
2. Depth-First Search
In depth-first-search (DFS), you start by particularly from the vertex and explore as much as you along all the
branches before backtracking. In DFS, it is essential to keep note of the tracks of visited nodes, and for this, you use
stack data structure.
Example of DFS
Pseudocode:
//Assumptions:
//s: stack for storing nodes (with push(), pop() and empty() operations)
//visited[]:Array for storing current status of node (visited or unvisited)
1. DFS(G,v) ( v is the vertex where the search starts )
2. Stack S := []; ( start with an empty stack )
3. for each vertex v, set visited[v] := false;
4. push S, v; //put starting vertex v on stack
5. while (S is not empty) do
6. v := pop S;
7. if (not visited[v]) then
8. visited[v] := true;
9. for each unvisited neighbour w of v
10. push S, w;
11. end if
12. end while
13. END DFS()
Spanning Tree:
A spanning tree of a graph G is defined as a subset of G that has all the vertices of G connected with the
minimum number of edges possible
Two conditions exist in the spanning tree, which is as follows:
1. The number of vertices (V`) in the spanning tree would be the same as the number of vertices( V ) in the
original graph.
V` = V
2. The number of edges (E` ) in the spanning tree would be equal to the number of edges minus 1.
E` = |V| - 1
The spanning tree should not contain any cycle.
The spanning tree should not be disconnected.
To understand the concept of spanning tree, consider the below graph:
As discussed above, a spanning tree contains the same number of vertices as the graph, the number of vertices in the
above graph is 5; therefore, the spanning tree will contain 5 vertices. The edges in the spanning tree will be equal to the
number of vertices in the graph minus 1. So, there will be 4 edges in the spanning tree
Some of the possible spanning trees that will be created from the above graph are given as follows -
Minimum Spanning tree
A minimum spanning tree can be defined as the spanning tree in which the sum of the weights of the edge is minimum.
The weight of the spanning tree is the sum of the weights given to the edges of the spanning tree. In the real world, this
weight can be considered as the distance, traffic load, congestion, or any random value.
Example of minimum spanning tree
Let's understand the minimum spanning tree with the help of an example.
The sum of the edges of the above graph is 16. Now, some of the possible spanning trees created from the above graph
are -
So, the minimum spanning tree that is selected from the above spanning trees for the given weighted graph is -
Algorithms for Minimum spanning tree:
A minimum spanning tree can be found from a weighted graph by using the algorithms given below -
o Prim's Algorithm
o Kruskal's Algorithm
How does Prim's algorithm work?
Prim’s algorithm is a greedy algorithm that is used to find the minimum spanning tree from a graph. Prim's algorithm
finds the subset of edges that includes every vertex of the graph such that the sum of the weights of the edges can be
minimized.
Prim's algorithm starts with the single node and explores all the adjacent nodes with all the connecting edges at every
step. The edges with the minimal weights causing no cycles in the graph got selected.
Prims Algorithm:
Step 1: Declare an array visited[] to store the visited vertices which is initially empty
Step 2: Choose any arbitrary vertex say S, as a starting vertex and add it to the
visited array.
Step 2: Check whether the adjacent vertices of the last visited vertex are present in the visited[] array or not.
Step 3: If the vertices are not in the visited[] array, compare the cost of edges and add the least cost edge to the
MST.
Step 4: The adjacent unvisited vertex with the least cost edge is added into the visited[] array and the least cost
edge is added to the minimum spanning tree.
Step 5: Steps 2 and 4 are repeated for all the unvisited vertices in the graph to obtain the full minimum spanning
tree output for the given graph.
Step 6: Calculate the cost of the minimum spanning tree obtained.
Example of prim's algorithm
Now, let's see the working of prim's algorithm using an example
Suppose, a weighted graph is -
Step 1 - First, we have to choose a vertex from the above graph. Let's choose B.
Step 2 - Now, we have to choose and add the shortest edge which is connected to vertex B. There are two edges from
vertex B that are B to C with weight 10 and edge B to D with weight 4. Among the edges, the edge BD has the minimum
weight. So, add it to the MST.
Step 3 - Now, again, choose the edge with the minimum weight among all the edges which are adjacent to vertices B
and D. In this case, the edges DE will get added to MST.
Step 4 - Now, choose select the edge with the minimum weight among all the edges which are adjacent to vertices B
and D and E .Edge with minimum weight is [Link] it to the MST.
Step 5 – Similarly we will try to add edge CE but we cannot add the edge CE as it would create a cycle to the graph.
So,we will skip it and choose the edge CA which is next minimum weight edge and add it to the MST.
Since all vertices of Graph are now included in MST, the minimum spanning tree of the given graph is produced. The
cost of the MST is given below -
Cost of MST = 4 + 2 + 1 + 3 = 10 units.
Time Complexity
Prim's algorithm can be simply implemented by using the adjacency matrix or adjacency list graph representation, and
to add the edge with the minimum weight requires the linearly searching of an array of weights. It requires O(|V|2)
running time. It can be improved further by using the implementation of heap to find the minimum weight edges in the
inner loop of the algorithm.
Data structure used for the minimum edge weight Time Complexity
Adjacency matrix, linear searching O(|V|2)
Adjacency list and binary heap O(|E| log |V|)
How does Kruskal's algorithm work?
In Kruskal's algorithm, we start from edges with the lowest weight and keep adding the edges until the goal is reached.
The steps to implement Kruskal's algorithm are listed as follows -
o First, sort all the edges from low weight to high.
o Now, take the edge with the lowest weight and add it to the spanning tree. If the edge to be added creates a
cycle, then reject the edge.
o Continue to add the edges until we reach all vertices, and a minimum spanning tree is created.
Kruskal’s Algorithm:
Step 1: Create a forest F in such a way that every vertex of the graph is a separate tree.
Step 2: Create a set E that contains all the edges of the graph.
Step 3: Repeat Steps 4 and 5 while E is NOT EMPTY
Step 4: Remove an edge from E with minimum weight
Step 5: IF the edge obtained in Step 4 connects two different trees, then add it to the
forest F (for combining two trees into one tree).
ELSE
Discard the edge
Step 6: END
Example of Kruskal's algorithm
Now, let's see the working of Kruskal's algorithm using an example.
Suppose a weighted graph is -
The weight of the edges of the above graph is given in the below table -
Edge AB AC AD AE BC CD DE
Weight 1 7 10 5 3 4 2
Now, sort the edges given above in the ascending order of their weights.
Edge AB DE BC CD AE AC AD
Weight 1 2 3 4 5 7 10
Now, let's start constructing the minimum spanning tree.
Step 1 - First, add the edge AB with weight 1 to the MST.
Step 2 - Add the edge DE with weight 2 to the MST as it is not creating the cycle.
Step 3 - Add the edge BC with weight 3 to the MST, as it is not creating any cycle or loop.
Step 4 - Now, pick the edge CD with weight 4 to the MST, as it is not forming the cycle.
Step 5 - After that, pick the edge AE with weight 5. Including this edge will create the cycle, so discard it.
Step 6 - Pick the edge AC with weight 7. Including this edge will create the cycle, so discard it.
Step 7 - Pick the edge AD with weight 10. Including this edge will also create the cycle, so discard it.
So, the final minimum spanning tree obtained from the given weighted graph by using Kruskal's algorithm is -
The cost of the MST is = AB + DE + BC + CD = 1 + 2 + 3 + 4 = 10.
Time Complexity
The time complexity of Kruskal's algorithm is O(E logE) or O(V logV), where E is the no. of edges, and V is the no.
of vertices.
Floyd-Warshall algorithm:
Floyd-Warshall is an algorithm used to locate the shortest course between all pairs of vertices in a weighted graph. It
works by updating original distance matrix iteratively till the shortest paths are discovered.
Steps for Floyd Warshall algorithm:
1. Initialize a distance matrix D wherein D[i][j] represents the shortest distance between vertex i and vertex j.
2. Set the diagonal entries of the matrix to 0, and all other entries to infinity.
3. For every existing edge (u,v) in the graph, D[u][v] = weight(u,v).
4. In every iteration, choose intermediate vertex k and for all pairs of vertices (i,j) and check if the path from i to
j through k is shorter than the current best path. If it is, update the distance matrix: D[i][j] = min(D[i][j], D[i][k]
D[k][j]).
5. After all iterations, the matrix D will contain the shortest course distances between all pairs of vertices.
When Floyd Warshall Algorithm Is Used?
Floyd Warshall Algorithm is best suited for dense graphs.
This is because its complexity depends only on the number of vertices in the given graph.
Pseudo Code:
FLOYD_Warshall ( W)
// W is the matrix of size n n representing original graph
// D is the distance matrix
D←W
for k ← 1 to n do
for i ← 1 to n do
for j ← 1 to n do
D[i, j]k ← min ( D[i, j]k-1, D[i, k]k-1 + D[k, j]k-1 )
end
end
end
return D
Example:
Problem: Apply Floyd’s method to find the shortest path for the below-mentioned all pairs.
Solution:
Optimal substructure formula for Floyd’s algorithm,
Dk [i, j] = min { Dk – 1 [i, j], Dk – 1 [i, k] + Dk – 1 [k, j] }
Iteration 1 : k = 1 :
D1[1, 2] = min { Do [1, 2], Do [1, 1] + Do [1, 2] }
= min {∞, 0 + ∞}
= ∞
D1[1, 3] = min { Do [1, 3], Do [1, 1] + Do [1, 3] }
= min {3, 0 + 3}
=3
D1[1, 4] = min { Do [1, 4], Do [1, 1] + Do [1, 4] }
= min {∞, 0 + ∞}
= ∞
D1[2, 1] = min { Do [2, 1], Do [2, 1] + Do [1, 1] }
= min {2, 2 + 0}
=2
D1[2, 3] = min { Do [2, 3], Do [2, 1] + Do [1, 3] }
= min {∞, 2 + 3}
=5
D1[2, 4] = min { Do [2, 4], Do [2, 1] + Do [1, 4] }
= min {∞, 2 + ∞}
=∞
D1[3, 1] = min { Do [3, 1], Do [3, 1] + Do [1, 1] }
= min {∞, 0 + ∞}
=∞
D1[3, 2] = min { Do [3, 2], Do [3, 1] + Do [1, 2] }
= min {7, ∞ + ∞}
=7
D1[3, 4] = min { Do [3, 4], Do [3, 1] + Do [1, 4] }
= min {1, ∞ + ∞}
=1
D1[4, 1] = min { Do [4, 1], Do [4, 1] + Do [1, 1] }
= min {6, 6 + 0}
=6
D1[4, 2] = min { Do [4, 2], Do [4, 1] + Do [1, 2] }
= min {∞, 6 + ∞}
=∞
D1[4, 3] = min { Do [4, 3], Do [4, 1] + Do [1, 3] }
= min {∞, 6 + 3}
=9
Note : Path distance for highlighted cell is improvement over original matrix.
Iteration 2 (k = 2) :
D2[1, 2] = D1 [1, 2] = ∞
D2[1, 3] = min { D1 [1, 3], D1 [1, 2] + D1 [2, 3] }
= min {3, ∞ + 5}
=3
D2[1, 4] = min { D1 [1, 4], D1 [1, 2] + D1 [2, 4] }
= min {∞, ∞ + ∞}
=∞
D2[2, 1] = D1 [2, 1] = 2
D2[2, 3] = D1 [2, 3] = 5
D2[2, 4] = D1 [2, 4] = ∞
D2[3, 1] = min { D1 [3, 1], D1 [3, 2] + D1 [2, 1] }
= min {∞, 7 + 2}
=9
D2[3, 2] = D1 [3, 2] = 7
D2[3, 4] = min { D1 [3, 4], D1 [3, 2] + D1 [2, 4] }
= min {1, 7 + ∞}
=1
D2[4, 1] = min { D1 [4, 1], D1 [4, 2] + D1 [2, 1] }
= min {6, ∞ + 2}
=6
D2[4, 2] = D1 [4, 2] = ∞
D2[4, 3] = min { D1 [4, 3], D1 [4, 2] + D1 [2, 3] }
= min {9, ∞ + 5}
=9
Iteration 3 (k = 3) :
D3[1, 2] = min { D2 [1, 2], D2 [1, 3] + D2 [3, 2] }
= min {∞, 3 + 7}
= 10
D3[1, 3] = D2 [1, 3] = 3
D3[1, 4] = min { D2 [1, 4], D2 [1, 3] + D2 [3, 4] }
= min {∞, 3 + 1}
=4
D3[2, 1] = min { D2 [2, 1], D2 [2, 3] + D2 [3, 1] }
= min {2, 5 + 9}
=2
D3[2, 3] = D2 [2, 3] = 5
D3[2, 4] = min { D2 [2, 4], D2 [2, 3] + D2 [3, 4] }
= min {∞, 5 + 1}
=6
D3[3, 1] = D2 [3, 1] = 9
D3[3, 2] = D2 [3, 2] = 7
D3[3, 4] = D2 [3, 4] = 1
D3[4, 1] = min { D2 [4, 1], D2 [4, 3] + D2 [3, 1] }
= min {6, 9 + 9}
=6
D3[4, 2] = min { D2 [4, 1], D2 [4, 3] + D2 [3, 2] }
= min {∞, 9 + 7}
= 16
D3[4, 3] = D2 [4, 3] = 9
Iteration 4 (k = 4) :
D4[1, 2] = min { D3 [1, 2], D3 [1, 4] + D3 [4, 2] }
= min {10, 4 + 16}
= 10
D4[1, 3] = min { D3 [1, 3], D3 [1, 4] + D3 [4, 1] }
= min {3, 4 + 9}
=3
D4[1, 4] = D3 [1, 4] = 4
D4[2, 1] = min { D3 [2, 1], D3 [2, 4] + D3 [4, 1] }
= min {2, 6 + 6}
=2
D4[2, 3] = min { D3 [2, 3], D3 [2, 4] + D3 [4, 3] }
= min {5, 6 + 9}
=5
D4[2, 4] = D3 [2, 4] = 6
D4[3, 1] = min { D3 [3, 1], D3 [3, 4] + D3 [4, 1] }
= min {9, 1 + 6}
=7
D4[3, 2] = min { D3 [3, 2], D3 [3, 4] + D3 [4, 2] }
= min {7, 1 + 16}
=7
D4[3, 4] = D3 [3, 4] = 1
D4[4, 1] = D3 [4, 1] = 6
D4[4, 2] = D3 [4, 2] = 16
D4[4, 3] = D3 [4, 3] = 9
Final distance matrix is,
Example 2: PRACTICE PROBLEM BASED ON FLOYD WARSHALL ALGORITHM-
Consider the following directed weighted graph-
Using Floyd Warshall Algorithm, find the shortest path distance between every pair of vertices.
Solution:
The last matrix D4 represents the shortest path distance between every pair of vertices.
Topological Sorting
A topological sort or topological ordering of a directed graph is a linear ordering of its vertices in which u occurs before
v in the ordering for every directed edge( u,v) from vertex u to vertex v. For example, the graph's vertices could represent
jobs to be completed, and the edges could reflect requirements that one work must be completed before another.
In this case, a topological ordering is just a legitimate task sequence. A topological sort is a graph traversal in which
each node v is only visited after all of its dependencies have been visited. If the graph contains no directed cycles, then
it is a directed acyclic graph. Any DAG has at least one topological ordering, and there exist techniques for building
topological orderings in linear time for any DAG.
Points to Remember:
Topological Sorting is possible if and only if the graph is a Directed Acyclic Graph.
There may exist multiple different topological orderings for a given directed acyclic graph.
Algorithm for Topological sorting:
1. Find a vertex that has indegree = 0 (no incoming edges)
2. Remove all the edges from that vertex that go outward (make its outdegree = 0, remove outgoing
edges)
3. Add that vertex to the array representing the topological sorting of the graph
4. Repeat till there are no more vertices left.
Consider the following directed acyclic graph-
For this graph, following 4 different topological orderings are possible-
123456
123465
132456
132465
Applications of topological sort are-
Scheduling jobs from the given dependencies among jobs
Instruction Scheduling
Determining the order of compilation tasks to perform in makefiles
Data Serialization
Example:
The topological orderings of the above graph are found in the following steps-
Step-01:
Write in-degree of each vertex-
Step-02:
Vertex-A has the least in-degree.
So, remove vertex-A and its associated edges.
Now, update the in-degree of other vertices.
Step-03:
Vertex-B has the least in-degree.
So, remove vertex-B and its associated edges.
Now, update the in-degree of other vertices.
Step-03:
There are two vertices with the least in-degree. So, following 2 cases are possible-
In case-01,
Remove vertex-C and its associated edges.
Then, update the in-degree of other vertices.
In case-02,
Remove vertex-D and its associated edges.
Then, update the in-degree of other vertices.
Now, the above two cases are continued separately in the similar manner.
In case-01,
Remove vertex-D since it has the least in-degree.
Then, remove the remaining vertex-E.
In case-02,
Remove vertex-C since it has the least in-degree.
Then, remove the remaining vertex-E.
For the given graph, following 2 different topological orderings are possible-
ABCDE
ABDCE
Dijkstra Algorithm :
Dijkstra Algorithm is a graph algorithm for finding the shortest path from a source node to all other nodes in a
graph(single source shortest path).
It is a type of greedy algorithm. It only works on weighted graphs with positive weights. It has a time complexity
O(V2) using the adjacency matrix representation of graph. The time complexity can be reduced
to O((V+E)logV) using adjacency list representation of graph, where E is the number of edges in the graph and V is
the number of vertices in the graph.
Dijikstra’s algorithm:
The 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.
Pseudocode :
1. dist[S] ← 0 // The distance to source vertex is set to 0
2. Pred[S] ← NIL // The predecessor of source vertex is set as NIL
3. for all v ∈ V - {S} // For all vertices excluding S
a. do dist[v] ← ∞ // All other distances are set to ∞
b. Pred[v] ← NIL // The predecessor of all other vertices is set as NIL
c. Visited[v] ← 0 // No vertex is visited
4. Q←V // The queue 'Q' initially contains all the vertices
5. while Q ≠ ∅ // While loop executes till the queue is not empty
a. do u ← mindistance (Q, dist) // A vertex from Q with the least distance is selected
b. visited[u]=1 // Vertex 'u' is visited
6. for all v ∈ neighbors[u] // For all the neighboring vertices of vertex 'u'
a. do if dist[v] > dist[u] + w(u,v) // if any new shortest path is discovered
then dist[v] ← dist[u] + w(u,v) // The new value of the shortest path is selected
7. return dist
Example 1:
The algorithm operates step by step, one vertex at a time, starting with the source vertex A. Initially, we do not yet
know the shortest distance between any of the vertices:
The table holds values for each vertex:
Visited - we say a vertex has been visited when we know its shortest path from A. We will visit the vertices
one by one.
Distance - the shortest path from this vertex to the source vertex. Initially, we set this to infinity, the value
will be filled with a tentative distance that might change as the algorithm progresses. Once a vertex has been
visited, its true shortest distance will be known.
Previous - the previous vertex in the shortest path. This allows us to reconstruct the shortest path once the
algorithm is complete.
Algorithm - step 1
The algorithm starts with the source vertex, which is A in our example. At this point, we know that the distance
from A to A is 0, of course. As above, we say we have visited vertex A, because we know the distance from A to A.
From this starting point, we look at all the neighbours of A (the vertices that can be reached in a single step). The
neighbours are B and E.
The tentative shortest distance from A to its neighbour B is 7 (assuming we go from A directly to B) but at this stage
that value might prove to be incorrect. We say we have accessed B, but we haven't visited B yet.
Similarly, the tentative distance from A to E is 1, but again that might change, and again we have accessed E but not
visited it.
Here is the graph with visited vertices in red, accessed vertices in blue, and all the other vertices in grey:
The table has been updated to show that we have visited A. It also shows that our tentative distance to B is 7,
with A as the previous vertex. In addition, our tentative distance to E is 1, with A as the previous vertex.
Algorithm - step 2
In the next step, we look at all the unvisited vertices and choose the one with the smallest tentative distance as the
starting point for the next step. From the previous table, this is E with a distance of 1 (since B has a distance of 7 and
the others are infinity).
This next fact is absolutely key to the algorithm: we now KNOW that the shortest distance from A to E is 1.
How do we know that? Well, we specifically selected E because it has the smallest tentative distance. To get
from A to E we can either go direct, or we can go via B in some way. For example, we could go ABE, or
maybe ABCE. But here is the thing, the distance from A to B is greater than the distance from A to E, so any route
that goes via B must be longer than A to E. Therefore AE must be the shortest route from A to E.
So we can mark vertex E as visited because we know its true distance.
Notice that we don't yet know the shortest route from A to B. It might be AB, with a distance of 8. But since the
distance AE is only 1, there might be a shorter route to B via E. At this point (based on the parts of the graph we have
analysed so far) we simply don't know. That is why we call the distance tentative.
Now, once again, we must look at the unvisited neighbours of the newly visited vertex E. The neighbours
are B, C and D.
For each neighbour, we find its distance from the source vertex A via the current vertex E. If that distance is less than
the current tentative distance, we update it.
For B, the distance AEB is 1 + 8 = 9. This is greater than the current tentative distance for B of 8, so we leave the
current distance unchanged.
C has a tentative distance of infinity, so we replace it with the distance via E, which is AEC. This is 1 + 2 = 3.
Similarly, the tentative distance of D is replaced with AED, which is 1 + 5 = 6
Here is the updated graph and table, with E marked as visited and the new distances added:
Algorithm - step 3
In the next step, we again look at all the unvisited vertices and choose the one with the smallest tentative distance to
go forward for the next step. From the previous table, B, C and D are unvisited, and C has the smallest distance of 3,
and a previous vertex E.
We mark C as visited.
Now we update all the unvisited neighbours of C, these are B and D.
The tentative distance of B, via C, is 3 + 3 = 6. This is calculated from the true distance of C, plus the weight of the
edge BC, which are both equal to 3. Since this new distance is less than the previous distance for B (7), we set the
distance of B to 6 and the previous vertex to C.
The tentative distance of D via C is 3 + 6 = 9. Since that is greater than the current distance, we leave it unchanged.
Here is the updated graph:
Algorithm - step 4
We are nearly finished! Only B and D are unvisited, and B has the shortest tentative distance, so we will mark it as
visited with a true distance of 6.
B has no unvisited neighbours so there is nothing more to do in this step.
Algorithm - step 5
Now there is only one unvisited vertex, D, so we just make it as visited with a true distance of 8. Since there are no
remaining unvisited vertices, we are done.
Algorithm - conclusion
The result of the algorithm is a tree that can be used to calculate the path and distance of any vertex from the
source, A:
So, for example, the shortest path to D is AED with a length of 8. The shortest path to B is AECB with a length of 6.
It is important to remember that this tree is only valid for routes that start from A. If we start from a different vertex,
the route might not be the shortest. For example, if we travel from C to D, according to this tree we have to go via E,
with a total distance of 9. But looking at the full mgraph, we can see that going from C to D directly only has a
distance of 6.
Example 2: Solve following problem for practice
Assume vertex A being the source. Find shortest paths from A to all other vertices
Answer:
The final paths we get are:
A=0(source)
B=4(A−>B)
C=5(A−>C)
D=13(A−>B−>D)
E=8(A−>C−>E)
F=14(A−>C−>E−>F)