View Javadoc
1   /*
2    * Copyright (c) 2003, The JUNG Authors
3    * All rights reserved.
4    * 
5    * This software is open-source under the BSD license; see either "license.txt"
6    * or https://github.com/jrtom/jung/blob/master/LICENSE for a description.
7    */
8   /*
9    * Created on Jul 2, 2003
10   *  
11   */
12  package edu.uci.ics.jung.graph.util;
13  
14  import java.util.ArrayList;
15  import java.util.HashSet;
16  import java.util.List;
17  import java.util.Set;
18  
19  import edu.uci.ics.jung.graph.DirectedGraph;
20  import edu.uci.ics.jung.graph.DirectedSparseMultigraph;
21  import edu.uci.ics.jung.graph.Graph;
22  import edu.uci.ics.jung.graph.SparseMultigraph;
23  import edu.uci.ics.jung.graph.UndirectedGraph;
24  import edu.uci.ics.jung.graph.UndirectedSparseMultigraph;
25  
26  /**
27   * Provides generators for several different test graphs.
28   */
29  public class TestGraphs {
30  
31  	/**
32  	 * A series of pairs that may be useful for generating graphs. The
33  	 * miniature graph consists of 8 edges, 10 nodes, and is formed of two
34  	 * connected components, one of 8 nodes, the other of 2.
35  	 *  
36  	 */
37  	public static String[][] pairs = { { "a", "b", "3" }, {
38  			"a", "c", "4" }, {
39  			"a", "d", "5" }, {
40  			"d", "c", "6" }, {
41  			"d", "e", "7" }, {
42  			"e", "f", "8" }, {
43  			"f", "g", "9" }, {
44  			"h", "i", "1" }
45  	};
46  
47  	/**
48  	 * Creates a small sample graph that can be used for testing purposes. The
49  	 * graph is as described in the section on {@link #pairs pairs}. If <code>isDirected</code>,
50  	 * the graph is a {@link DirectedSparseMultigraph DirectedSparseMultigraph},
51  	 * otherwise, it is an {@link UndirectedSparseMultigraph UndirectedSparseMultigraph}.
52  	 * 
53  	 * @param directed true iff the graph created is to have directed edges
54  	 * @return a graph consisting of eight edges and ten nodes.
55  	 */
56  	public static Graph<String, Number> createTestGraph(boolean directed) {
57  		Graph<String, Number> graph = null;
58  		if(directed) {
59  			graph = new DirectedSparseMultigraph<String,Number>();
60  		} else {
61  			graph = new UndirectedSparseMultigraph<String,Number>();
62  		}
63  
64  		for (int i = 0; i < pairs.length; i++) {
65  			String[] pair = pairs[i];
66  			graph.addEdge(Integer.parseInt(pair[2]), pair[0], pair[1]);
67  		}
68  		return graph;
69  	}
70  
71      /**
72       * @param chain_length the length of the chain of vertices to add to the returned graph
73       * @param isolate_count the number of isolated vertices to add to the returned graph
74       * @return a graph consisting of a chain of {@code chain_length} vertices
75       *     and {@code isolate_count} isolated vertices.
76       */
77      public static Graph<String,Number> createChainPlusIsolates(int chain_length, int isolate_count)
78      {
79      	Graph<String,Number> g = new UndirectedSparseMultigraph<String,Number>();
80          if (chain_length > 0)
81          {
82              String[] v = new String[chain_length];
83              v[0] = "v"+0;
84              g.addVertex(v[0]);
85              for (int i = 1; i < chain_length; i++)
86              {
87                  v[i] = "v"+i;
88                  g.addVertex(v[i]);
89                  g.addEdge(new Double(Math.random()), v[i], v[i-1]);
90              }
91          }
92          for (int i = 0; i < isolate_count; i++) {
93              String v = "v"+(chain_length+i);
94              g.addVertex(v);
95          }
96          return g;
97      }
98      
99  	/**
100 	 * Creates a sample directed acyclic graph by generating several "layers",
101 	 * and connecting nodes (randomly) to nodes in earlier (but never later)
102 	 * layers.  The number of vertices in each layer is a random value in the range
103 	 * [1, maxNodesPerLayer].
104 	 * 
105 	 * @param layers the number of layers of vertices to create in the graph
106 	 * @param maxNodesPerLayer the maximum number of vertices to put in any layer
107 	 * @param linkprob the probability that this method will add an edge from a vertex in layer
108 	 *     <i>k</i> to a vertex in layer <i>k+1</i>
109 	 * @return the created graph
110 	 */
111 	public static Graph<String,Number> createDirectedAcyclicGraph(
112 		int layers,
113 		int maxNodesPerLayer,
114 		double linkprob) {
115 
116 		DirectedGraph<String,Number> dag = new DirectedSparseMultigraph<String,Number>();
117 		Set<String> previousLayers = new HashSet<String>();
118 		Set<String> inThisLayer = new HashSet<String>();
119 		for (int i = 0; i < layers; i++) {
120 
121 			int nodesThisLayer = (int) (Math.random() * maxNodesPerLayer) + 1;
122 			for (int j = 0; j < nodesThisLayer; j++) {
123                 String v = i+":"+j;
124 				dag.addVertex(v);
125 				inThisLayer.add(v);
126 				// for each previous node...
127                 for(String v2 : previousLayers) {
128 					if (Math.random() < linkprob) {
129                         Double de = new Double(Math.random());
130 						dag.addEdge(de, v, v2);
131 					}
132 				}
133 			}
134 
135 			previousLayers.addAll(inThisLayer);
136 			inThisLayer.clear();
137 		}
138 		return dag;
139 	}
140 	
141 	private static void createEdge(
142 			Graph<String, Number> g,
143 			String v1Label,
144 			String v2Label,
145 			int weight) {
146 			g.addEdge(new Double(Math.random()), v1Label, v2Label);
147 	}
148 	
149 	/**
150 	 * Returns a bigger, undirected test graph with a just one component. This
151 	 * graph consists of a clique of ten edges, a partial clique (randomly
152 	 * generated, with edges of 0.6 probability), and one series of edges
153 	 * running from the first node to the last.
154 	 * 
155 	 * @return the testgraph
156 	 */
157 	public static Graph<String,Number> getOneComponentGraph() {
158 
159 		UndirectedGraph<String,Number> g = new UndirectedSparseMultigraph<String,Number>();
160 		// let's throw in a clique, too
161 		for (int i = 1; i <= 10; i++) {
162 			for (int j = i + 1; j <= 10; j++) {
163 				String i1 = "" + i;
164 				String i2 = "" + j;
165 				g.addEdge(Math.pow(i+2,j), i1, i2);
166 			}
167 		}
168 
169 		// and, last, a partial clique
170 		for (int i = 11; i <= 20; i++) {
171 			for (int j = i + 1; j <= 20; j++) {
172 				if (Math.random() > 0.6)
173 					continue;
174 				String i1 = "" + i;
175 				String i2 = "" + j;
176 				g.addEdge(Math.pow(i+2,j), i1, i2);
177 			}
178 		}
179 
180 		List<String> index = new ArrayList<String>();
181 		index.addAll(g.getVertices());
182 		// and one edge to connect them all
183 		for (int i = 0; i < index.size() - 1; i++) 
184 		    g.addEdge(new Integer(i), index.get(i), index.get(i+1));
185 
186 		return g;
187 	}
188 
189 	/**
190 	 * Returns a bigger test graph with a clique, several components, and other
191 	 * parts.
192 	 * 
193 	 * @return a demonstration graph of type <tt>UndirectedSparseMultigraph</tt>
194 	 *         with 28 vertices.
195 	 */
196 	public static Graph<String, Number> getDemoGraph() {
197 		UndirectedGraph<String, Number> g = 
198             new UndirectedSparseMultigraph<String, Number>();
199 
200 		for (int i = 0; i < pairs.length; i++) {
201 			String[] pair = pairs[i];
202 			createEdge(g, pair[0], pair[1], Integer.parseInt(pair[2]));
203 		}
204 
205 		// let's throw in a clique, too
206 		for (int i = 1; i <= 10; i++) {
207 			for (int j = i + 1; j <= 10; j++) {
208 				String i1 = "c" + i;
209 				String i2 = "c" + j;
210                 g.addEdge(Math.pow(i+2,j), i1, i2);
211 			}
212 		}
213 
214 		// and, last, a partial clique
215 		for (int i = 11; i <= 20; i++) {
216 			for (int j = i + 1; j <= 20; j++) {
217 				if (Math.random() > 0.6)
218 					continue;
219 				String i1 = "p" + i;
220 				String i2 = "p" + j;
221                 g.addEdge(Math.pow(i+2,j), i1, i2);
222 			}
223 		}
224 		return g;
225 	}
226 
227     /**
228      * @return a small graph with directed and undirected edges, and parallel edges.
229      */
230     public static Graph<String, Number> getSmallGraph() {
231         Graph<String, Number> graph = 
232             new SparseMultigraph<String, Number>();
233         String[] v = new String[3];
234         for (int i = 0; i < 3; i++) {
235             v[i] = String.valueOf(i);
236             graph.addVertex(v[i]);
237         }
238         graph.addEdge(new Double(0), v[0], v[1], EdgeType.DIRECTED);
239         graph.addEdge(new Double(.1), v[0], v[1], EdgeType.DIRECTED);
240         graph.addEdge(new Double(.2), v[0], v[1], EdgeType.DIRECTED);
241         graph.addEdge(new Double(.3), v[1], v[0], EdgeType.DIRECTED);
242         graph.addEdge(new Double(.4), v[1], v[0], EdgeType.DIRECTED);
243         graph.addEdge(new Double(.5), v[1], v[2]);
244         graph.addEdge(new Double(.6), v[1], v[2]);
245 
246         return graph;
247     }
248 }