Warshall’s algorithm is a dynamic programming algorithm that uses a matrix to calculate the transitive closure of a graph. It works on by the principle of transitivity in binary relations, which states that if and exist on the graph , then is an existing path.
Transitive closure is defined as:
Process
Let be the graph which we are calculating the transitive closure of.
- Initialise a square matrix, (using a 2-dimensional array) of size . Let be this matrix.
- Convert to an adjacency matrix of by a nested for loop.
- For every node in , loop through every node in and if an edge exists, set . Else, set it to 0.
- Use the transitive closure property:
- For every node :
- For every node
- For every node , check if . i.e. there is a path from to via
- For every node
- For every node :
- Return . If is 1, then there exists a path from to .
Warshall’s Algorithm uses dynamic programming because it:
- Splits problem into sub-problems: The problem of finding all paths between any two nodes and in a graph has a trivial and non-trivial section. It can be easily checked if exists, than a path of length 1 exists between and . The non-trivial section is seeing if there is a path with any intermediate nodes. If a path between and exists (with ), then a path exists from to via . Hence, we need to check whether and have paths. This is splitting into sub-problems.
- Uses overlapping solutions to sub-problems: When checking for paths between and (our sub-problems), any paths that start with and make use of as an intermediate node will benefit from the solution to . Hence, the solution of sub-problems can overlap.
As a recurrence relation, this can be expressed as:
Pseudocode
Simple
Algorithm Transitive_Closure(G):
T ← |V| x |V| array
//Initialise the T matrix
For i from 1 to |V| do:
For j from 1 to |V| do:
If i=j or edge i-j exists in G then:
T[i][j] ← 1
Else:
T[i][j] ← 0
End if
End do
End do
For k from 1 to |V| do:
From i from 1 to |V| do:
From j from 1 to |V| do:
If T[i][k] = 1 AND T[k][j] = 1 then:
T[i][j] ← 1
End if
End do
End do
End do
Return T
End Algorithm
Slightly Improved
Since the equality check does not depend on , it can be moved outside the j-loop, which does not change the time complexity, but does make it faster in real-time:
Algorithm Transitive_Closure(G):
...
For k from 1 to |V| do:
From i from 1 to |V| do:
If T[i][k] = 1 then:
From j from 1 to |V| do:
If T[k][j] = 1 then:
T[i][j] ← 1
End if
End do
End if
End do
End do
Return T
End Algorithm
Time Complexity
The time complexity of Warshall’s Algorithm is relatively straightforward. It consists of three nested for loops, each running for times, giving a time complexity of:
This time complexity applies for all cases:
Case Scenario | Input Description | Growth Function | Asymptotic | Notes |
---|---|---|---|---|
Worst | Time complexity is same for every case | |||
Average | ||||
Best |