unm.cs351.f11.tdrl.p1
Interface GraphAnalyzer<T>


public interface GraphAnalyzer<T>

Interface for an object that analyzes basic graph structural statistics. Objects of this type provide a number of methods for calculating statistics about average graph topology, including shortest paths and connected components, diameter, degree distributions, etc.

Caching (optional). The intent is that objects of this type accept a Graph object in the constructor and then all operations are defined with respect to that Graph. If this object is made immutable, and the Graph is not changed during the existence of this object, then the GraphAnalyzer can cache intermediate results. For example, a number of operations require essentially the same loop over the graph; the GraphAnalyzer can arrange to perform that loop only once and to cache the results of the computation.

Regardless of whether implementations of this interface support caching, the constructor for any concrete implementations MUST run in O(1) time and consume only O(1) space. In particular, they MUST NOT pre-compute/pre-allocate any expensive values at construction time. They MUST wait until requested via one of the methods defined in this interface. This avoids potentially computing expensive results that will never be requested by the user.

The documentation of all methods in this interface assumes a directed graph, G, containing V nodes and E edges. The notation x^p represents "x raised to the pth power", not "x xor p". The notation x_{ij} should be read "x subscripted with ij".

Note that none of the methods in this interface depend on the type of the Graph's nodes -- GraphAnalyzer only cares about the structure of the graph, not its contents. However, objects of this type MUST be Java generics because they will be initialized with Graphs of some specific type.

Efficiency The runtime bounds given for a number of the operations in this interface are fairly loose. It is certainly possible to carry out a number of these operations (such as all-pairs shortest paths and computation of strongly connected components) more efficiently than the values given here. But the values given here are amenable to simple implementations. Ambitious designers are encouraged to find more efficient implementations of these operations.

Version:
1.0
Author:
terran

Method Summary
 int[][] allPairsShortestPaths()
          Compute the all-pairs shortest paths distances between every pair of nodes in the graph.
 double avgShortestPathDistance()
          Returns the average distance between all reachable pairs of nodes.
 int diameter()
          Computes the diameter of the reachable portion of the graph.
 int maxInDegree()
          Computes the maximum INDEGREE for any node in the graph.
 int maxOutDegree()
          Computes the maximum OUTDEGREE for any node in the graph.
 int minInDegree()
          Computes the minimum INDEGREE for any node in the graph.
 int minOutDegree()
          Computes the minimum OUTDEGREE for any node in the graph.
 List<T> shortestPath(T from, T to)
          Computes the shortest path between nodes from and to.
 Graph<T> sphere(T center, int radius)
          Construct the subgraph that is a sphere of specified radius, surrounding a specified center node.
 

Method Detail

allPairsShortestPaths

int[][] allPairsShortestPaths()
                              throws GraphAnalysisException
Compute the all-pairs shortest paths distances between every pair of nodes in the graph. This uses an all-pairs shortest paths algorithm (such as Floyd-Warshall) to compute the shortest directed distance between every two nodes in the graph. Note: this does not return the shortest paths themselves; it merely computes the distances that those paths require.

The returned matrix has one row and one column for every node in the graph. The interpretation of this matrix is:

   dist[i][j]==d
 
means that the shortest distance starting at node i and ending at node j is d. (That is, nodes whose Graph.getNodeID(Object) is i and j.)

The distance from node i to itself is 0 and if j is not reachable from i then dist[i][j]==Integer.MAX_VALUE (i.e., infinity).

If the graph is empty (contains no nodes or edges), then this returns a size-0 matrix. That is, it returns essentially new int[0].

This routine MUST run in O(V^3) time for a graph containing V nodes. It SHOULD require only O(V^2) space. It MAY use more than O(V^2) space, but not more than O(V^3) space.

WARNING Because this runs in cubic time, running it on a large graph (e.g., thousands or more) of nodes will crush any modern computer. Be careful with this function.

Returns:
Inter-node distance matrix.
Throws:
GraphAnalysisException - if there is a structural flaw in the graph being analyzed.

shortestPath

List<T> shortestPath(T from,
                     T to)
                     throws GraphAnalysisException
Computes the shortest path between nodes from and to. This MAY use a pre-computed all-pairs distance matrix, if such a matrix exists, but it MUST NOT cause an all-pairs distance calculation. This method MUST run in O(V+E) time (i.e., it can use breadth-first search.)

(Note that in general, shortest-path calculations in a weighted graph would require a more sophisticated algorithm, such as Dijkstra's. However, since we're working with unweighted graphs here, we can treat all edges as having unit distance and use the simpler breadth-first method.)

This returns a list containing the nodes of the shortest path from node from to node to, in the order encountered along the shortest path, including both from (as the first element of the list) and to (as the last element of the list). The list will be L+1 elements long, where L is the length (in edges) of the shortest path. If from.equals(to) then the returned list should be only one element long (L=0, in this case).

If there is no path from from to to (unreachable), then this MUST return an empty (zero element) list. It MUST NOT generate an exception or otherwise fail in this case.

Returns:
List of nodes along the shortest path from from to to (including both end points).
Throws:
GraphAnalysisException - from or to does not exist in the graph, or if there is a structural error when analyzing the graph.

sphere

Graph<T> sphere(T center,
                int radius)
                throws GraphAnalysisException
Construct the subgraph that is a sphere of specified radius, surrounding a specified center node. This method constructs and returns a new Graph object by extracting a specific sphere out of the target graph.

Recall that a sphere is the set of all points within a fixed radius, r of a center point c. For a graph G that means:

This method MUST run in O(V'+E') time, where V' and E' are the number of nodes and edges in the sphere-graph, respectively. This method MAY allocate up to O(V'+E') new storage, though it MUST NOT explicitly copy the nodes of the original graph. (It is free to make reference to those nodes, but it is not allowed to copy/duplicate them.)

Parameters:
center - Node at the center of the sphere
radius - Radius of the sphere to be constructed. Must be >=0.
Returns:
Newly constructed spherical subgraph.
Throws:
GraphAnalysisException - If center does not exist in the graph, if radius<0, or if there is a structural flaw in the graph being analyzed.

avgShortestPathDistance

double avgShortestPathDistance()
Returns the average distance between all reachable pairs of nodes. That is, this examines all pairs of nodes, i,j, such that dist[i][j]<Integer.MAX_VALUE and returns the average distance over those nodes.

An empty graph is defined to have an average distance of 0.

This method MUST run in time O(V^2) beyond that required by the allPairsShortestPaths() method. (That is, this method MAY execute allPairsShortestPaths() and then spend up to O(V^2) time beyond that.

Returns:
Average shortest-path distance

diameter

int diameter()
             throws GraphAnalysisException
Computes the diameter of the reachable portion of the graph. This method finds the maximum distance between any pair of nodes that are reachable (i.e., whose distance is not infinite). That is, it computes
 dmax=max_{i,j in V} ( d_{ij} )
 subject to:
   d_{ij}<Integer.MAX_VALUE
 

An empty graph is defined to have a diameter of 0.

This MUST run in time O(V^3)

Returns:
Diameter of reachable portion of the graph
Throws:
GraphAnalysisException

maxInDegree

int maxInDegree()
Computes the maximum INDEGREE for any node in the graph. This method finds the node with the maximum number of edges entering it, and returns that number of edges.

An empty graph is defined to have a max indegree of 0.

This method MUST run in O(V+E) time for a graph with V nodes.

Returns:
Maximum indegree over all nodes in the graph.

minInDegree

int minInDegree()
Computes the minimum INDEGREE for any node in the graph. This method finds the node with the minimum number of edges entering it, and returns that number of edges. Note that a node with no parents has an INDEGREE of 0, although a node with a self-edge has an INDEGREE of 1.

An empty graph is defined to have a min indegree of 0.

This method MUST run in O(V+E) time for a graph with V nodes.

Returns:
Minimum indegree over all nodes in the graph.

maxOutDegree

int maxOutDegree()
Computes the maximum OUTDEGREE for any node in the graph. This method finds the node with the maximum number of edges leaving it, and returns that number of edges.

An empty graph is defined to have a max outdegree of 0.

This method MUST run in O(V) time for a graph with V nodes.

Returns:
Maximum outdegree over all nodes in the graph.

minOutDegree

int minOutDegree()
Computes the minimum OUTDEGREE for any node in the graph. This method finds the node with the smallest number of edges leaving it, and returns that number of edges. Note that a node with no neighbors has an OUTDEGREE of 0, although a node with a self-edge has an OUTDEGREE of 1.

An empty graph is defined to have a min outdegree of 0.

This method MUST run in O(V) time for a graph with V nodes.

Returns:
Minimum outdegree over all nodes in the graph.