Title: Chapter 9: More Graph Algorithms
1Chapter 9 More Graph Algorithms
- We conclude our examination of graph algorithms
by considering two related algorithms - Transitive closure and all-pair shortest paths
- Transitive closure means that a path exists
between two given nodes - We will generate a matrix showing all transitive
closures - for instance, if a path exists from x to y, then
closurex, y will be true - All-pair shortest paths means finding between
every two vertices, the shortest path between
them - The all-pair shortest path sounds like it could
use Dijkstras algorithm, and in fact we will use
a part of Dijkstra, but we will try to improve on
it - It turns out that the transitive closure
algorithm will be very similar to the all-pair
shortest path algorithm - We are going to skip the remainder of the chapter
on matrix operations and matrix multiplications
2Transitive Closure
- Recall from our definitions on graphs that graphs
contain connected components such that - from each vertex in the connected component
subgraph, you can reach every other vertex in the
subgraph, but that if there are two more such
subgraphs, there are no paths between vertices of
different subgraphs - if there is a path from x to y and from y to z,
then there is a path from x to z - Transitive closure determines if there is a path
from one node to the next through transitivity - We want an algorithm to determine, given the
graph, what vertices can reach what other
vertices - Consider the following adjacency matrix on the
left representing a directed graph, the
transitive closure is given on the right
illustrating which vertices can reach other
vertices
a b c d e a b c d e a 0 1 0 0 1 1 1 1 1
1 b 0 0 0 1 0 0 1 1 1 0 c 0 1 0 0 0 0 1 1 1
0 d 0 0 1 0 0 0 1 1 1 0 e 0 0 0 1 0 0 1 1 1
1
Since there is an edge from a to b and e, and b
can reach d and d can reach c, a can reach all
vertices. But b cannot reach a
3Strategy for Transitive Closure
- We noted earlier that if there is an path from a
to b and from b to c, then there is a path from a
to c - Our strategy for deriving a transitive closure
matrix will be based on this simple idea - Start with a, compare it against each other
vertex and see if there is an edge - if so, the corresponding matrix value is true
- if not, see if there is already a path known from
some vertex c to b and an edge from a to b, if
so, then we know that there is a path from a to b - This will require the use of 3 nested for-loops,
one for the starting vertex of a path, one for
the destination vertex of a path, and one to see
if a path already exists from start to this point
and from this point to destination
4Warshalls Algorithm
- The algorithm to the left is known as Warshalls
Algorithm for Transitive Closure - It should be obvious that the complexity is ?(n3)
because of the 3 nested for-loops - The result is an NxN matrix where entry Ri, j
is true if there is a path from vertex i to
vertex j - The algorithm will work on either undirected or
directed graphs - The resulting matrix for an undirected graph will
be symmetrical (along the diagonal) but not
necessarily so for a DAG
A is the original graph R is the transitive
matrix generated as a result R ? A for(int
k0kltnk) for(int j0jltnj)
for(int i0iltni) Ri, j Ri,
j OR (Ri, k AND Rk,
j) Note If we are using a network instead of
a graph, we must make a slight alteration by
considering any value gt 0 and lt infinity to
be true, false otherwise
5All-Pairs Shortest Path
- We could compute the shortest distance between
every pair of points by using 2 nested for loops
and calling Dijkstras algorithm each time - Such an algorithm is shown to the right
- This is in ?(n4)
- We already know that Warshalls algorithm is
?(n3) - can we use Warshalls somehow to improve our
All-Pairs Shortest Path strategy? - Yes, we will make two modifications to Warshalls
- We replace the logic operation with a comparison
to determine - If, at node k, we see that the distance from i to
k distance from k to j is shorter than our
previously computed distance from i to j, we
update the distance from i to j to be the new sum - We also update a path array to store the node
that is taking us to j (that is, we say that our
shortest path to j is through k)
for(i0iltni) for(j0jltnj)
Dijkstra(i, j) Unlike Dijkstras, the distance
and path information will be stored in NxN
arrays rather than 1-d arrays These arrays will
store the shortest distance between every pair
of points as opposed to Dijkstra where it was
just the shortest distance from a given
starting point
6Floyds All-Pairs Shortest Path
Assume N is the original network and F is the
matrix we will compute where Fi, j will be the
cost of the shortest path from i to j and
pathx, y stores the vertex used to get to y
from x F ? N for(int k0kltnk) for(int
j0jltnj) for(int i0iltni)
if(Fi, j gt Fi, k Fk, j) Fi, j
Fi, k Fk, j pathi, j k
- This algorithm is named after its creator, R. W.
Floyd, and, unlike the strategy of using
Dijkstras over and over again, this algorithm is
only ?(n3) - In fact, it is nearly identical to Warshalls
except for the manipulation of the arrays
(distance and path)
As with Dijkstra, we need to generate the actual
path from x to y by starting at pathx, y and
working backwards. If pathx, y z, then check
pathx, z and if that is q then check pathx,
q until we reach x