/*
* Copyright (c) 2003, the JUNG Project and the Regents of the University
* of California
* All rights reserved.
*
* This software is open-source under the BSD license; see either
* "license.txt" or
* http://jung.sourceforge.net/license.txt for a description.
*/
package edu.uci.ics.jung.algorithms.shortestpath;
import java.util.Collection;
import org.apache.commons.collections15.Transformer;
import edu.uci.ics.jung.algorithms.scoring.ClosenessCentrality;
import edu.uci.ics.jung.algorithms.scoring.util.VertexScoreTransformer;
import edu.uci.ics.jung.graph.Hypergraph;
/**
* Statistics relating to vertex-vertex distances in a graph.
*
* <p>
* Formerly known as <code>GraphStatistics</code> in JUNG 1.x.
* </p>
*
* @author Scott White
* @author Joshua O'Madadhain
*/
public class DistanceStatistics {
/**
* For each vertex <code>v</code> in <code>graph</code>, calculates the
* average shortest path length from <code>v</code> to all other vertices in
* <code>graph</code> using the metric specified by <code>d</code>, and
* returns the results in a <code>Map</code> from vertices to
* <code>Double</code> values. If there exists an ordered pair
* <code><u,v></code> for which <code>d.getDistance(u,v)</code>
* returns <code>null</code>, then the average distance value for
* <code>u</code> will be stored as <code>Double.POSITIVE_INFINITY</code>).
*
* <p>
* Does not include self-distances (path lengths from <code>v</code> to
* <code>v</code>).
*
* <p>
* To calculate the average distances, ignoring edge weights if any:
*
* <pre>
* Map distances = DistanceStatistics.averageDistances(g,
* new UnweightedShortestPath(g));
* </pre>
*
* To calculate the average distances respecting edge weights:
*
* <pre>
* DijkstraShortestPath dsp = new DijkstraShortestPath(g, nev);
* Map distances = DistanceStatistics.averageDistances(g, dsp);
* </pre>
*
* where <code>nev</code> is an instance of <code>Transformer</code> that is
* used to fetch the weight for each edge.
*
* @see edu.uci.ics.jung.algorithms.shortestpath.UnweightedShortestPath
* @see edu.uci.ics.jung.algorithms.shortestpath.DijkstraDistance
*/
public static <V, E> Transformer<V, Double> averageDistances(
Hypergraph<V, E> graph, Distance<V> d) {
final ClosenessCentrality<V, E> cc = new ClosenessCentrality<V, E>(
graph, d);
return new VertexScoreTransformer<V, Double>(cc);
}
/**
* For each vertex <code>v</code> in <code>g</code>, calculates the average
* shortest path length from <code>v</code> to all other vertices in
* <code>g</code>, ignoring edge weights.
*
* @see #diameter(Hypergraph)
* @see edu.uci.ics.jung.algorithms.scoring.ClosenessCentrality
*/
public static <V, E> Transformer<V, Double> averageDistances(
Hypergraph<V, E> g) {
final ClosenessCentrality<V, E> cc = new ClosenessCentrality<V, E>(g,
new UnweightedShortestPath<V, E>(g));
return new VertexScoreTransformer<V, Double>(cc);
}
/**
* Returns the diameter of <code>g</code> using the metric specified by
* <code>d</code>. The diameter is defined to be the maximum, over all pairs
* of vertices <code>u,v</code>, of the length of the shortest path from
* <code>u</code> to <code>v</code>. If the graph is disconnected (that is,
* not all pairs of vertices are reachable from one another), the value
* returned will depend on <code>use_max</code>: if
* <code>use_max == true</code>, the value returned will be the the maximum
* shortest path length over all pairs of <b>connected</b> vertices;
* otherwise it will be <code>Double.POSITIVE_INFINITY</code>.
*/
public static <V, E> double diameter(Hypergraph<V, E> g, Distance<V> d,
boolean use_max) {
double diameter = 0;
Collection<V> vertices = g.getVertices();
for (V v : vertices) {
for (V w : vertices) {
if (v.equals(w) == false) // don't include self-distances
{
Number dist = d.getDistance(v, w);
if (dist == null) {
if (!use_max) {
return Double.POSITIVE_INFINITY;
}
} else {
diameter = Math.max(diameter, dist.doubleValue());
}
}
}
}
return diameter;
}
/**
* Returns the diameter of <code>g</code> using the metric specified by
* <code>d</code>. The diameter is defined to be the maximum, over all pairs
* of vertices <code>u,v</code>, of the length of the shortest path from
* <code>u</code> to <code>v</code>, or
* <code>Double.POSITIVE_INFINITY</code> if any of these distances do not
* exist.
*
* @see #diameter(Hypergraph, Distance, boolean)
*/
public static <V, E> double diameter(Hypergraph<V, E> g, Distance<V> d) {
return diameter(g, d, false);
}
/**
* Returns the diameter of <code>g</code>, ignoring edge weights.
*
* @see #diameter(Hypergraph, Distance, boolean)
*/
public static <V, E> double diameter(Hypergraph<V, E> g) {
return diameter(g, new UnweightedShortestPath<V, E>(g));
}
}