/* ==========================================
* JGraphT : a free Java graph-theory library
* ==========================================
*
* Project Info: http://jgrapht.sourceforge.net/
* Project Creator: Barak Naveh (http://sourceforge.net/users/barak_naveh)
*
* (C) Copyright 2003-2008, by Barak Naveh and Contributors.
*
* This program and the accompanying materials are dual-licensed under
* either
*
* (a) the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation, or (at your option) any
* later version.
*
* or (per the licensee's choosing)
*
* (b) the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation.
*/
/* -----------------------
* GraphGeneratorTest.java
* -----------------------
* (C) Copyright 2003-2008, by John V. Sichi and Contributors.
*
* Original Author: John V. Sichi
* Contributor(s): -
*
* $Id$
*
* Changes
* -------
* 17-Sep-2003 : Initial revision (JVS);
* 07-May-2006 : Changed from List<Edge> to Set<Edge> (JVS);
*
*/
package org.jgrapht.generate;
import java.util.*;
import junit.framework.*;
import org.jgrapht.*;
import org.jgrapht.alg.*;
import org.jgrapht.graph.*;
/**
* .
*
* @author John V. Sichi
* @since Sep 17, 2003
*/
public class GraphGeneratorTest
extends TestCase
{
//~ Static fields/initializers ---------------------------------------------
private static final int SIZE = 10;
//~ Instance fields --------------------------------------------------------
private VertexFactory<Object> vertexFactory =
new VertexFactory<Object>() {
private int i;
public Object createVertex()
{
return new Integer(++i);
}
};
//~ Methods ----------------------------------------------------------------
/**
* .
*/
public void testEmptyGraphGenerator()
{
GraphGenerator<Object, DefaultEdge, Object> gen =
new EmptyGraphGenerator<Object, DefaultEdge>(SIZE);
DirectedGraph<Object, DefaultEdge> g =
new DefaultDirectedGraph<Object, DefaultEdge>(DefaultEdge.class);
Map<String, Object> resultMap = new HashMap<String, Object>();
gen.generateGraph(g, vertexFactory, resultMap);
assertEquals(SIZE, g.vertexSet().size());
assertEquals(0, g.edgeSet().size());
assertTrue(resultMap.isEmpty());
}
/**
* .
*/
public void testLinearGraphGenerator()
{
GraphGenerator<Object, DefaultEdge, Object> gen =
new LinearGraphGenerator<Object, DefaultEdge>(SIZE);
DirectedGraph<Object, DefaultEdge> g =
new DefaultDirectedGraph<Object, DefaultEdge>(DefaultEdge.class);
Map<String, Object> resultMap = new HashMap<String, Object>();
gen.generateGraph(g, vertexFactory, resultMap);
assertEquals(SIZE, g.vertexSet().size());
assertEquals(SIZE - 1, g.edgeSet().size());
Object startVertex = resultMap.get(LinearGraphGenerator.START_VERTEX);
Object endVertex = resultMap.get(LinearGraphGenerator.END_VERTEX);
Iterator vertexIter = g.vertexSet().iterator();
while (vertexIter.hasNext()) {
Object vertex = vertexIter.next();
if (vertex == startVertex) {
assertEquals(0, g.inDegreeOf(vertex));
assertEquals(1, g.outDegreeOf(vertex));
continue;
}
if (vertex == endVertex) {
assertEquals(1, g.inDegreeOf(vertex));
assertEquals(0, g.outDegreeOf(vertex));
continue;
}
assertEquals(1, g.inDegreeOf(vertex));
assertEquals(1, g.outDegreeOf(vertex));
}
}
/**
* .
*/
public void testRingGraphGenerator()
{
GraphGenerator<Object, DefaultEdge, Object> gen =
new RingGraphGenerator<Object, DefaultEdge>(SIZE);
DirectedGraph<Object, DefaultEdge> g =
new DefaultDirectedGraph<Object, DefaultEdge>(DefaultEdge.class);
Map<String, Object> resultMap = new HashMap<String, Object>();
gen.generateGraph(g, vertexFactory, resultMap);
assertEquals(SIZE, g.vertexSet().size());
assertEquals(SIZE, g.edgeSet().size());
Object startVertex = g.vertexSet().iterator().next();
assertEquals(1, g.outDegreeOf(startVertex));
Object nextVertex = startVertex;
Set<Object> seen = new HashSet<Object>();
for (int i = 0; i < SIZE; ++i) {
DefaultEdge nextEdge =
g.outgoingEdgesOf(nextVertex).iterator().next();
nextVertex = g.getEdgeTarget(nextEdge);
assertEquals(1, g.inDegreeOf(nextVertex));
assertEquals(1, g.outDegreeOf(nextVertex));
assertTrue(!seen.contains(nextVertex));
seen.add(nextVertex);
}
// do you ever get the feeling you're going in circles?
assertTrue(nextVertex == startVertex);
assertTrue(resultMap.isEmpty());
}
/**
* .
*/
public void testCompleteGraphGenerator()
{
Graph<Object, DefaultEdge> completeGraph =
new SimpleGraph<Object, DefaultEdge>(DefaultEdge.class);
CompleteGraphGenerator<Object, DefaultEdge> completeGenerator =
new CompleteGraphGenerator<Object, DefaultEdge>(10);
completeGenerator.generateGraph(
completeGraph,
new ClassBasedVertexFactory<Object>(Object.class),
null);
// complete graph with 10 vertices has 10*(10-1)/2 = 45 edges
assertEquals(45, completeGraph.edgeSet().size());
}
/**
* .
*/
public void testScaleFreeGraphGenerator()
{
DirectedGraph<Object, DefaultEdge> graph =
new DefaultDirectedGraph<Object, DefaultEdge>(DefaultEdge.class);
ScaleFreeGraphGenerator<Object, DefaultEdge> generator =
new ScaleFreeGraphGenerator<Object, DefaultEdge>(500);
generator.generateGraph(graph, vertexFactory, null);
ConnectivityInspector<Object, DefaultEdge> inspector =
new ConnectivityInspector<Object, DefaultEdge>(graph);
assertTrue(
"generated graph is not connected",
inspector.isGraphConnected());
try {
generator = new ScaleFreeGraphGenerator<Object, DefaultEdge>(-50);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException e) {
}
try {
generator =
new ScaleFreeGraphGenerator<Object, DefaultEdge>(-50, 31337);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException e) {
}
generator = new ScaleFreeGraphGenerator<Object, DefaultEdge>(0);
DirectedGraph<Object, DefaultEdge> empty =
new DefaultDirectedGraph<Object, DefaultEdge>(DefaultEdge.class);
generator.generateGraph(empty, vertexFactory, null);
assertTrue("non-empty graph generated", empty.vertexSet().size() == 0);
}
/**
* .
*/
public void testCompleteBipartiteGraphGenerator()
{
Graph<Object, DefaultEdge> completeBipartiteGraph =
new SimpleGraph<Object, DefaultEdge>(
DefaultEdge.class);
CompleteBipartiteGraphGenerator<Object, DefaultEdge> completeBipartiteGenerator =
new CompleteBipartiteGraphGenerator<Object, DefaultEdge>(
10,
4);
completeBipartiteGenerator.generateGraph(
completeBipartiteGraph,
new ClassBasedVertexFactory<Object>(Object.class),
null);
// Complete bipartite graph with 10 and 4 vertices should have 14
// total vertices and 4*10=40 total edges
assertEquals(14, completeBipartiteGraph.vertexSet().size());
assertEquals(40, completeBipartiteGraph.edgeSet().size());
}
/**
* .
*/
public void testHyperCubeGraphGenerator()
{
Graph<Object, DefaultEdge> hyperCubeGraph =
new SimpleGraph<Object, DefaultEdge>(
DefaultEdge.class);
HyperCubeGraphGenerator<Object, DefaultEdge> hyperCubeGenerator =
new HyperCubeGraphGenerator<Object, DefaultEdge>(
4);
hyperCubeGenerator.generateGraph(
hyperCubeGraph,
new ClassBasedVertexFactory<Object>(Object.class),
null);
// Hypercube of 4 dimensions should have 2^4=16 vertices and
// 4*2^(4-1)=32 total edges
assertEquals(16, hyperCubeGraph.vertexSet().size());
assertEquals(32, hyperCubeGraph.edgeSet().size());
}
/**
* .
*/
public void testStarGraphGenerator()
{
Map<String, Object> map = new HashMap<String, Object>();
Graph<Object, DefaultEdge> starGraph =
new SimpleGraph<Object, DefaultEdge>(
DefaultEdge.class);
StarGraphGenerator<Object, DefaultEdge> starGenerator =
new StarGraphGenerator<Object, DefaultEdge>(
10);
starGenerator.generateGraph(
starGraph,
new ClassBasedVertexFactory<Object>(Object.class),
map);
// Star graph of order 10 should have 10 vertices and 9 edges
assertEquals(9, starGraph.edgeSet().size());
assertEquals(10, starGraph.vertexSet().size());
assertTrue(map.get(StarGraphGenerator.CENTER_VERTEX) != null);
}
/**
* .
*/
public void testGridGraphGenerator()
{
int rows = 3;
int cols = 4;
//the form of these two classes helps debugging
class StringVertexFactory
implements VertexFactory<String>
{
int index = 1;
@Override public String createVertex()
{
return String.valueOf(index++);
}
}
class StringEdgeFactory
implements EdgeFactory<String, String>
{
@Override public String createEdge(
String sourceVertex,
String targetVertex)
{
return new String(sourceVertex + '-' + targetVertex);
}
}
GridGraphGenerator<String, String> generator =
new GridGraphGenerator<String, String>(rows, cols);
Map<String, String> resultMap = new HashMap<String, String>();
//validating a directed and undirected graph
Graph<String, String> directedGridGraph =
new DefaultDirectedGraph<String, String>(new StringEdgeFactory());
generator.generateGraph(
directedGridGraph,
new StringVertexFactory(),
resultMap);
validateGridGraphGenerator(rows, cols, directedGridGraph, resultMap);
resultMap.clear();
Graph<String, String> undirectedGridGraph =
new SimpleGraph<String, String>(new StringEdgeFactory());
generator.generateGraph(
undirectedGridGraph,
new StringVertexFactory(),
resultMap);
validateGridGraphGenerator(rows, cols, undirectedGridGraph, resultMap);
}
public void validateGridGraphGenerator(
int rows,
int cols,
Graph<String, String> gridGraph,
Map<String, String> resultMap)
{
// graph structure validations
int expectedVerticeNum = rows * cols;
assertEquals(
"number of vertices is wrong (" + gridGraph
.vertexSet().size()
+ "), should be " + expectedVerticeNum,
expectedVerticeNum,
gridGraph.vertexSet().size());
int expectedEdgesNum =
(((rows - 1) * cols) + ((cols - 1) * rows))
* ((gridGraph instanceof UndirectedGraph) ? 1 : 2);
assertEquals(
"number of edges is wrong (" + gridGraph
.edgeSet().size()
+ "), should be " + expectedEdgesNum,
expectedEdgesNum,
gridGraph.edgeSet().size());
int cornerVertices = 0, borderVertices = 0, innerVertices = 0,
neighborsSize;
int expCornerVertices = 4;
int expBorderVertices =
Math.max(((rows - 2) * 2) + ((cols - 2) * 2), 0);
int expInnerVertices = Math.max((rows - 2) * (cols - 2), 0);
Set<String> neighbors = new HashSet<String>();
for (String v : gridGraph.vertexSet()) {
neighbors.clear();
neighbors.addAll(Graphs.neighborListOf(gridGraph, v));
neighborsSize = neighbors.size();
assertTrue(
"vertex with illegal number of neighbors (" + neighborsSize
+ ").",
(neighborsSize == 2)
|| (neighborsSize == 3)
|| (neighborsSize == 4));
if (neighborsSize == 2) {
cornerVertices++;
} else if (neighborsSize == 3) {
borderVertices++;
} else if (neighborsSize == 4) {
innerVertices++;
}
}
assertEquals(
"there should be exactly " + expCornerVertices
+ " corner (with two neighbors) vertices. "
+ " actual number is " + cornerVertices + ".",
expCornerVertices,
cornerVertices);
assertEquals(
"there should be exactly " + expBorderVertices
+ " border (with three neighbors) vertices. "
+ " actual number is " + borderVertices + ".",
expBorderVertices,
borderVertices);
assertEquals(
"there should be exactly " + expInnerVertices
+ " inner (with four neighbors) vertices. "
+ " actual number is " + innerVertices + ".",
expInnerVertices,
innerVertices);
// result map validations
Set<String> keys = resultMap.keySet();
assertEquals(
"result map contains should contains exactly 4 corner verices",
4,
keys.size());
for (String key : keys) {
neighbors.clear();
neighbors.addAll(
Graphs.neighborListOf(gridGraph, resultMap.get(key)));
neighborsSize = neighbors.size();
assertEquals(
"corner vertex should have exactly 2 neighbors",
2,
neighborsSize);
}
}
}
// End GraphGeneratorTest.java