1 /*
2 * Copyright (c) 2003, The JUNG Authors
3 *
4 * All rights reserved.
5 *
6 * This software is open-source under the BSD license; see either
7 * "license.txt" or
8 * https://github.com/jrtom/jung/blob/master/LICENSE for a description.
9 */
10 package edu.uci.ics.jung.algorithms.shortestpath;
11 import java.util.Collection;
12
13 import com.google.common.base.Function;
14
15 import edu.uci.ics.jung.algorithms.scoring.ClosenessCentrality;
16 import edu.uci.ics.jung.algorithms.scoring.util.VertexScoreTransformer;
17 import edu.uci.ics.jung.graph.Hypergraph;
18
19 /**
20 * Statistics relating to vertex-vertex distances in a graph.
21 *
22 * <p>Formerly known as <code>GraphStatistics</code> in JUNG 1.x.
23 *
24 * @author Scott White
25 * @author Joshua O'Madadhain
26 */
27 public class DistanceStatistics
28 {
29 /**
30 * For each vertex <code>v</code> in <code>graph</code>,
31 * calculates the average shortest path length from <code>v</code>
32 * to all other vertices in <code>graph</code> using the metric
33 * specified by <code>d</code>, and returns the results in a
34 * <code>Map</code> from vertices to <code>Double</code> values.
35 * If there exists an ordered pair <code><u,v></code>
36 * for which <code>d.getDistance(u,v)</code> returns <code>null</code>,
37 * then the average distance value for <code>u</code> will be stored
38 * as <code>Double.POSITIVE_INFINITY</code>).
39 *
40 * <p>Does not include self-distances (path lengths from <code>v</code>
41 * to <code>v</code>).
42 *
43 * <p>To calculate the average distances, ignoring edge weights if any:
44 * <pre>
45 * Map distances = DistanceStatistics.averageDistances(g, new UnweightedShortestPath(g));
46 * </pre>
47 * To calculate the average distances respecting edge weights:
48 * <pre>
49 * DijkstraShortestPath dsp = new DijkstraShortestPath(g, nev);
50 * Map distances = DistanceStatistics.averageDistances(g, dsp);
51 * </pre>
52 * where <code>nev</code> is an instance of <code>Transformer</code> that
53 * is used to fetch the weight for each edge.
54 *
55 * @see edu.uci.ics.jung.algorithms.shortestpath.UnweightedShortestPath
56 * @see edu.uci.ics.jung.algorithms.shortestpath.DijkstraDistance
57 *
58 * @param graph the graph for which distances are to be calculated
59 * @param d the distance metric to use for the calculation
60 * @param <V> the vertex type
61 * @param <E> the edge type
62 * @return a map from each vertex to the mean distance to each other (reachable) vertex
63 */
64 public static <V,E> Function<V,Double> averageDistances(Hypergraph<V,E> graph, Distance<V> d)
65 {
66 final ClosenessCentrality<V,E> cc = new ClosenessCentrality<V,E>(graph, d);
67 return new VertexScoreTransformer<V, Double>(cc);
68 }
69
70 /**
71 * For each vertex <code>v</code> in <code>g</code>,
72 * calculates the average shortest path length from <code>v</code>
73 * to all other vertices in <code>g</code>, ignoring edge weights.
74 * @see #diameter(Hypergraph)
75 * @see edu.uci.ics.jung.algorithms.scoring.ClosenessCentrality
76 *
77 * @param g the graph for which distances are to be calculated
78 * @param <V> the vertex type
79 * @param <E> the edge type
80 * @return a map from each vertex to the mean distance to each other (reachable) vertex
81 */
82 public static <V,E> Function<V, Double> averageDistances(Hypergraph<V,E> g)
83 {
84 final ClosenessCentrality<V,E> cc = new ClosenessCentrality<V,E>(g,
85 new UnweightedShortestPath<V,E>(g));
86 return new VertexScoreTransformer<V, Double>(cc);
87 }
88
89 /**
90 * Returns the diameter of <code>g</code> using the metric
91 * specified by <code>d</code>. The diameter is defined to be
92 * the maximum, over all pairs of vertices <code>u,v</code>,
93 * of the length of the shortest path from <code>u</code> to
94 * <code>v</code>. If the graph is disconnected (that is, not
95 * all pairs of vertices are reachable from one another), the
96 * value returned will depend on <code>use_max</code>:
97 * if <code>use_max == true</code>, the value returned
98 * will be the the maximum shortest path length over all pairs of <b>connected</b>
99 * vertices; otherwise it will be <code>Double.POSITIVE_INFINITY</code>.
100 *
101 * @param g the graph for which distances are to be calculated
102 * @param d the distance metric to use for the calculation
103 * @param use_max if {@code true}, return the maximum shortest path length for all graphs;
104 * otherwise, return {@code Double.POSITIVE_INFINITY} for disconnected graphs
105 * @param <V> the vertex type
106 * @param <E> the edge type
107 * @return the longest distance from any vertex to any other
108 */
109 public static <V, E> double diameter(Hypergraph<V,E> g, Distance<V> d, boolean use_max)
110 {
111 double diameter = 0;
112 Collection<V> vertices = g.getVertices();
113 for(V v : vertices) {
114 for(V w : vertices) {
115
116 if (v.equals(w) == false) // don't include self-distances
117 {
118 Number dist = d.getDistance(v, w);
119 if (dist == null)
120 {
121 if (!use_max)
122 return Double.POSITIVE_INFINITY;
123 }
124 else
125 diameter = Math.max(diameter, dist.doubleValue());
126 }
127 }
128 }
129 return diameter;
130 }
131
132 /**
133 * Returns the diameter of <code>g</code> using the metric
134 * specified by <code>d</code>. The diameter is defined to be
135 * the maximum, over all pairs of vertices <code>u,v</code>,
136 * of the length of the shortest path from <code>u</code> to
137 * <code>v</code>, or <code>Double.POSITIVE_INFINITY</code>
138 * if any of these distances do not exist.
139 * @see #diameter(Hypergraph, Distance, boolean)
140 *
141 * @param g the graph for which distances are to be calculated
142 * @param d the distance metric to use for the calculation
143 * @param <V> the vertex type
144 * @param <E> the edge type
145 * @return the longest distance from any vertex to any other
146 */
147 public static <V, E> double diameter(Hypergraph<V,E> g, Distance<V> d)
148 {
149 return diameter(g, d, false);
150 }
151
152 /**
153 * Returns the diameter of <code>g</code>, ignoring edge weights.
154 * @see #diameter(Hypergraph, Distance, boolean)
155 *
156 * @param g the graph for which distances are to be calculated
157 * @param <V> the vertex type
158 * @param <E> the edge type
159 * @return the longest distance from any vertex to any other
160 */
161 public static <V, E> double diameter(Hypergraph<V,E> g)
162 {
163 return diameter(g, new UnweightedShortestPath<V,E>(g));
164 }
165 }