Data Structures, Algorithms, & Applications in Java
Chapter 20, Exercise 15
Since we are interested olny in the existence of a path,
we can change c(i,j,k) to be a
boolean valued method.
c(i,j,k) is false iff there is
no path from vertex i to vertex j
that has no intermediate vertex larger than
k.
With this change, we see that
c(i,j,0) is false
iff i != j and
there is
no edge from vertex i to vertex j.
Further, the recurrence for
c(i,j,k) can be rewritten
using logical operators. The new equation is
c(i,j,k) = c(i,j,k-1) || (c(i,k,k-1) && c(k,j,k-1), k > 0
These changes together with the observation that we
need no longer compute kay
result in the transitive closure code given below.
A test program, input, and output appear in
the files TestReflexiveTransitiveClosure.*.
The complexity of the method
AdjacencyDigraph.reflexiveTransitiveClosure
is seen to be the same as that
of Program 20.8; that is O(n3).
public class AdjacencyDigraphWithReflexiveTransitiveClosure
extends AdjacencyDigraph
{
// constructors
public AdjacencyDigraphWithReflexiveTransitiveClosure(int theVertices)
{super(theVertices);}
// default is a 0 vertex graph
public AdjacencyDigraphWithReflexiveTransitiveClosure()
{this(0);}
/** dynamic programming code to return the reflexive
* transitive closure matrix of a digraph graph, code is
* a modification of Program 20.8 */
public boolean [][] reflexiveTransitiveClosure()
{
// create array for reflexive transitive closure
boolean [][] rtc = new boolean [n + 1][n + 1];
// copy adjacency matrix into rtc
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
rtc[i][j] = a[i][j];
// set diagonal entries to true
for (int i = 1; i <= n; i++)
rtc[i][i] = true;
// 3 nested loops of Program 20.8 using logical operators
for (int k = 1; k <= n; k++)
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
rtc[i][j] = rtc[i][j] || (rtc[i][k] && rtc[k][j]);
return rtc;
}
}