Files
commons-graph/src/test/org/apache/commons/graph/GraphTest.java
T
2003-01-01 02:19:03 +00:00

1025 lines
24 KiB
Java

package org.apache.commons.graph;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Commons" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Commons", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/**
* GraphTest This is a superclass of other tests to provide some utilities in
* verifying graphs. This test will provide Undirected and Directed Graphs as
* well. We will implement the following graphs. Undirected Graphs
* ------------------- () No Vertex, No Edges @ One Vertex, No Edges @ @ Two
* Vertices, No Edges @-@ Two Vertices, One edge /-\ @ @ Two Vertices, Two Edges
* (Parallel Edges) \-/ @ / \ Three Vertices, Three Edges (Cycle) @---@ @--@--@
* Three Vertices, Two Edges (No Cycle) @ / \ @ @ 5 Vertices, 4 Edges (Tree) / \
* @ @ @-@ @-@ 4 Vertices, 2 Edges (Disconnected)
*/
import java.util.Set;
import java.util.HashSet;
import java.util.Iterator;
import junit.framework.*;
import org.apache.commons.graph.domain.basic.*;
import org.apache.commons.graph.exception.*;
/**
* Description of the Class
*/
public class GraphTest extends TestCase
{
/**
* Description of the Class
*/
public class VertexImpl
implements Vertex
{
private String name = null;
/**
* Constructor for the VertexImpl object
*
* @param name
*/
public VertexImpl(String name)
{
this.name = name;
}
/**
* Description of the Method
*/
public String toString()
{
return name;
}
}
/**
* Description of the Class
*/
public class EdgeImpl
implements Edge
{
private Vertex start;
private Vertex end;
/**
* Constructor for the EdgeImpl object
*
* @param start
* @param end
*/
public EdgeImpl(Vertex start,
Vertex end)
{
this.start = start;
this.end = end;
}
/**
* Gets the otherVertex attribute of the EdgeImpl object
*/
public Vertex getOtherVertex(Vertex v)
{
if (v == start)
{
return end;
}
if (v == end)
{
return start;
}
return null;
}
/**
* Gets the vertices attribute of the EdgeImpl object
*/
public Set getVertices()
{
Set RC = new HashSet();
RC.add(start);
RC.add(end);
return RC;
}
/**
* Gets the source attribute of the EdgeImpl object
*/
public Vertex getSource()
{
return start;
}
/**
* Gets the target attribute of the EdgeImpl object
*/
public Vertex getTarget()
{
return end;
}
/**
* Description of the Method
*/
public String toString()
{
return start.toString() + " <-> " + end.toString();
}
}
/**
* Description of the Field
*/
public Vertex V1 = new VertexImpl("V1");
/**
* Description of the Field
*/
public Vertex V2 = new VertexImpl("V2");
/**
* Description of the Field
*/
public Vertex V3 = new VertexImpl("V3");
/**
* Description of the Field
*/
public Vertex V4 = new VertexImpl("V4");
/**
* Description of the Field
*/
public Vertex V5 = new VertexImpl("V5");
/**
* Description of the Field
*/
public EdgeImpl V1_V1 = new EdgeImpl(V1, V1);// For Self-Loops.
/**
* Description of the Field
*/
public EdgeImpl V1_V2 = new EdgeImpl(V1, V2);
/**
* Description of the Field
*/
public EdgeImpl V1_V2_ = new EdgeImpl(V1, V2);// For Parallel
/**
* Description of the Field
*/
public EdgeImpl V1_V2__ = new EdgeImpl(V1, V2);// For Parallel #2
public EdgeImpl V1_V2_V3 = new EdgeImpl(V1, V2); // HyperEdge. . .
/**
* Description of the Field
*/
public EdgeImpl V1_V3 = new EdgeImpl(V1, V3);
/**
* Description of the Field
*/
public EdgeImpl V1_V4 = new EdgeImpl(V1, V4);
/**
* Description of the Field
*/
public EdgeImpl V1_V5 = new EdgeImpl(V1, V5);
/**
* Description of the Field
*/
public EdgeImpl V2_V1 = new EdgeImpl(V2, V1);
/**
* Description of the Field
*/
public EdgeImpl V2_V3 = new EdgeImpl(V2, V3);
/**
* Description of the Field
*/
public EdgeImpl V2_V4 = new EdgeImpl(V2, V4);
/**
* Description of the Field
*/
public EdgeImpl V2_V5 = new EdgeImpl(V2, V5);
/**
* Description of the Field
*/
public EdgeImpl V3_V1 = new EdgeImpl(V3, V1);
/**
* Description of the Field
*/
public EdgeImpl V3_V2 = new EdgeImpl(V3, V2);
/**
* Description of the Field
*/
public EdgeImpl V3_V4 = new EdgeImpl(V3, V4);
/**
* Description of the Field
*/
public EdgeImpl V3_V5 = new EdgeImpl(V3, V5);
/**
* Description of the Field
*/
public EdgeImpl V4_V1 = new EdgeImpl(V4, V1);
/**
* Description of the Field
*/
public EdgeImpl V4_V2 = new EdgeImpl(V4, V2);
/**
* Description of the Field
*/
public EdgeImpl V4_V3 = new EdgeImpl(V4, V3);
/**
* Description of the Field
*/
public EdgeImpl V4_V5 = new EdgeImpl(V4, V5);
/**
* Description of the Field
*/
public EdgeImpl V5_V1 = new EdgeImpl(V5, V1);
/**
* Description of the Field
*/
public EdgeImpl V5_V2 = new EdgeImpl(V5, V2);
/**
* Description of the Field
*/
public EdgeImpl V5_V3 = new EdgeImpl(V5, V3);
/**
* Description of the Field
*/
public EdgeImpl V5_V4 = new EdgeImpl(V5, V4);
/**
* Constructor for the GraphTest object
*
* @param name
*/
public GraphTest(String name)
{
super(name);
this.testName = name;
}
private String testName = null;
/**
* Return this graph: ()
*/
public UndirectedGraph makeNullGraph()
throws GraphException
{
return new UndirectedGraphImpl();
}
/**
* Description of the Method
*/
public DirectedGraph makeDirNullGraph()
throws GraphException
{
return new DirectedGraphImpl();
}
/**
* Return this graph: v1
*/
public UndirectedGraph makeSingleVertex()
throws GraphException
{
UndirectedGraphImpl RC = new UndirectedGraphImpl();
RC.addVertex(V1);
return RC;
}
/**
* Description of the Method
*/
public DirectedGraph makeDirSingleVertex()
throws GraphException
{
DirectedGraphImpl RC = new DirectedGraphImpl();
RC.addVertex(V1);
return RC;
}
/**
* /--\ v1 | ^--/
*/
public DirectedGraph makeSelfLoop()
throws GraphException
{
DirectedGraphImpl RC = new DirectedGraphImpl();
RC.addVertex(V1);
RC.addEdge(V1_V1, V1, V1);
return RC;
}
/**
* v1 v2 Two Vertices, No Edges
*/
public UndirectedGraph makeDoubleVertex()
throws GraphException
{
UndirectedGraphImpl RC = new UndirectedGraphImpl();
RC.addVertex(V1);
RC.addVertex(V2);
return RC;
}
/**
* Description of the Method
*/
public DirectedGraph makeDirDoubleVertex()
throws GraphException
{
DirectedGraphImpl RC = new DirectedGraphImpl();
RC.addVertex(V1);
RC.addVertex(V2);
return RC;
}
/**
* v1-v2 Two Vertices, One edge
*/
public UndirectedGraph makeSingleEdge()
throws GraphException
{
UndirectedGraphImpl RC = new UndirectedGraphImpl();
RC.addVertex(V1);
RC.addVertex(V2);
RC.addEdge(V1_V2, V1_V2.getVertices());
return RC;
}
/**
* v1 -> v2 Directed Edge
*/
public DirectedGraph makeDirectedEdge()
throws GraphException
{
DirectedGraphImpl RC = new DirectedGraphImpl();
RC.addVertex(V1);
RC.addVertex(V2);
RC.addEdge(V1_V2,
V1, V2);
return RC;
}
/**
* /-\ v1 v2 Two Vertices, Two Edges (Parallel Edges) \-/
*/
public UndirectedGraph makeParallelEdges()
throws GraphException
{
UndirectedGraphImpl RC = new UndirectedGraphImpl();
RC.addVertex(V1);
RC.addVertex(V2);
RC.addEdge(V1_V2, V1_V2.getVertices());
RC.addEdge(V1_V2_, V1_V2_.getVertices());
return RC;
}
/**
* /--->\ @ @ \--->/
*/
public DirectedGraph makeDirParallelEdges()
throws GraphException
{
DirectedGraphImpl RC = new DirectedGraphImpl();
RC.addVertex(V1);
RC.addVertex(V2);
RC.addEdge(V1_V2, V1, V2);
// Second edge must be distinct. . .
RC.addEdge(V1_V2_, V1, V2);
return RC;
}
/**
* v1 / \ Three Vertices, Three Edges (Cycle) v2---v3
*/
public UndirectedGraph makeCycle()
throws GraphException
{
UndirectedGraphImpl RC = new UndirectedGraphImpl();
RC.addVertex(V1);
RC.addVertex(V2);
RC.addVertex(V3);
RC.addEdge(V1_V2, V1_V2.getVertices());
RC.addEdge(V2_V3, V2_V3.getVertices());
RC.addEdge(V3_V1, V3_V1.getVertices());
return RC;
}
/**
* /--->\ v1 v2 \<---/
*/
public DirectedGraph makeTwoCycle()
throws GraphException
{
DirectedGraphImpl RC = new DirectedGraphImpl();
RC.addVertex(V1);
RC.addVertex(V2);
RC.addEdge(V1_V2, V1, V2);
RC.addEdge(V2_V1, V2, V1);
return RC;
}
/**
* v1 / ^ v \ v2 ---> v3
*/
public DirectedGraph makeDirectedCycle()
throws GraphException
{
DirectedGraphImpl RC = new DirectedGraphImpl();
RC.addVertex(V1);
RC.addVertex(V2);
RC.addVertex(V3);
RC.addEdge(V1_V2, V1, V2);
RC.addEdge(V2_V3, V2, V3);
RC.addEdge(V3_V1, V3, V1);
return RC;
}
/**
* v1 / ^ v \ v2 ---> v3
*/
public DirectedGraph makeDirected4Cycle()
throws GraphException
{
DirectedGraphImpl RC = new DirectedGraphImpl();
RC.addVertex(V1);
RC.addVertex(V2);
RC.addVertex(V3);
RC.addVertex(V4);
RC.addEdge(V1_V2, V1, V2);
RC.addEdge(V2_V3, V2, V3);
RC.addEdge(V3_V4, V3, V4);
RC.addEdge(V4_V1, V4, V1);
return RC;
}
/**
* v1--v2--v3 Three Vertices, Two Edges (No Cycle)
*/
public UndirectedGraph makeNoCycle()
throws GraphException
{
UndirectedGraphImpl RC = new UndirectedGraphImpl();
RC.addVertex(V1);
RC.addVertex(V2);
RC.addVertex(V3);
RC.addEdge(V1_V2, V1_V2.getVertices());
RC.addEdge(V2_V3, V2_V3.getVertices());
return RC;
}
/**
* v1 --> v2 --> v3
*/
public DirectedGraph makePipe()
throws GraphException
{
DirectedGraphImpl RC = new DirectedGraphImpl();
RC.addVertex(V1);
RC.addVertex(V2);
RC.addVertex(V3);
RC.addEdge(V1_V2, V1, V2);
RC.addEdge(V2_V3, V2, V3);
return RC;
}
/**
* v1 / \ v v v2 v3 \ / v v v4
*/
public DirectedGraph makeDiamond()
throws GraphException
{
DirectedGraphImpl RC = new DirectedGraphImpl();
RC.addVertex(V1);
RC.addVertex(V2);
RC.addVertex(V3);
RC.addVertex(V4);
RC.addEdge(V1_V2, V1, V2);
RC.addEdge(V1_V3, V1, V3);
RC.addEdge(V2_V4, V2, V4);
RC.addEdge(V3_V4, V3, V4);
return RC;
}
/**
* v1 / \ v v v2 v3 ^ ^ \ / v4
*/
public DirectedGraph makePipelessCycle()
throws GraphException
{
DirectedGraphImpl RC = new DirectedGraphImpl();
RC.addVertex(V1);
RC.addVertex(V2);
RC.addVertex(V3);
RC.addVertex(V4);
RC.addEdge(V1_V2, V1, V2);
RC.addEdge(V1_V3, V1, V3);
RC.addEdge(V4_V2, V4, V2);
RC.addEdge(V4_V3, V4, V3);
return RC;
}
/**
* v1 / \ v2 v3 5 Vertices, 4 Edges (Tree) / \ v4 v5
*/
public UndirectedGraph makeTree()
throws GraphException
{
UndirectedGraphImpl RC = new UndirectedGraphImpl();
RC.addVertex(V1);
RC.addVertex(V2);
RC.addVertex(V3);
RC.addVertex(V4);
RC.addVertex(V5);
RC.addEdge(V1_V2, V1_V2.getVertices());
RC.addEdge(V1_V3, V1_V3.getVertices());
RC.addEdge(V3_V4, V3_V4.getVertices());
RC.addEdge(V3_V5, V3_V5.getVertices());
return RC;
}
/**
* Description of the Method
*/
public DirectedGraph makeParentTree()
throws GraphException
{
DirectedGraphImpl RC = new DirectedGraphImpl();
RC.addVertex(V1);
RC.addVertex(V2);
RC.addVertex(V3);
RC.addVertex(V4);
RC.addVertex(V5);
RC.addEdge(V2_V1, V2, V1);
RC.addEdge(V3_V1, V3, V1);
RC.addEdge(V4_V3, V4, V3);
RC.addEdge(V5_V3, V5, V3);
return RC;
}
/**
* Description of the Method
*/
public DirectedGraph makeChildTree()
throws GraphException
{
DirectedGraphImpl RC = new DirectedGraphImpl();
RC.addVertex(V1);
RC.addVertex(V2);
RC.addVertex(V3);
RC.addVertex(V4);
RC.addVertex(V5);
RC.addEdge(V1_V2, V1, V2);
RC.addEdge(V1_V3, V1, V3);
RC.addEdge(V3_V4, V3, V4);
RC.addEdge(V3_V5, V3, V5);
return RC;
}
/**
* v1-v2 v3-v4 4 Vertices, 2 Edges (Disconnected)
*/
public UndirectedGraph makeDisconnected()
throws GraphException
{
UndirectedGraphImpl RC = new UndirectedGraphImpl();
RC.addVertex(V1);
RC.addVertex(V2);
RC.addVertex(V3);
RC.addVertex(V4);
RC.addEdge(V1_V2, V1_V2.getVertices());
RC.addEdge(V3_V4, V3_V4.getVertices());
return RC;
}
/**
* makeHyperEdgeGraph
*
* This makes a graph which has more than one Vertex on an Edge.
*
* V1
* |
* *
* / \
* V2 V3
*
*/
public Graph makeHyperGraph() {
UndirectedGraphImpl RC = new UndirectedGraphImpl();
RC.addVertex( V1 );
RC.addVertex( V2 );
RC.addVertex( V3 );
RC.addEdge( V1_V2_V3 );
RC.connect( V1_V2_V3, V1 );
RC.connect( V1_V2_V3, V2 );
RC.connect( V1_V2_V3, V3 );
return RC;
}
/**
*
* V1 --> V2 --> V3 <--> V4
*/
public DirectedGraph makeCycleNoReturn()
throws GraphException
{
DirectedGraphImpl RC = new DirectedGraphImpl();
RC.addVertex(V1);
RC.addVertex(V2);
RC.addVertex(V3);
RC.addVertex(V4);
RC.addEdge(V1_V2, V1, V2);
RC.addEdge(V2_V3, V2, V3);
RC.addEdge(V3_V4, V3, V4);
RC.addEdge(V4_V3, V4, V3);
return RC;
}
/**
* A unit test for JUnit
*/
public void testNothing()
throws Throwable { }
/**
* Description of the Method
*/
public void verifyVertexEdgeCount(Graph IUT,
Vertex v,
int numEdge)
throws Throwable
{
assertEquals(v.toString() + " has wrong number of adjacent edges.",
IUT.getEdges(v).size(), numEdge);
}
/**
* Gets the outboundVertices attribute of the GraphTest object
*/
private Set getOutboundVertices(DirectedGraph IUT,
Vertex v)
{
Set RC = new HashSet();
Iterator edges = IUT.getOutbound(v).iterator();
while (edges.hasNext())
{
Edge e = (Edge) edges.next();
RC.add(IUT.getTarget(e));
}
return RC;
}
/**
* Gets the inboundVertices attribute of the GraphTest object
*/
private Set getInboundVertices(DirectedGraph IUT,
Vertex v)
{
Set RC = new HashSet();
Iterator edges = IUT.getInbound(v).iterator();
while (edges.hasNext())
{
Edge e = (Edge) edges.next();
RC.add(IUT.getSource(e));
}
return RC;
}
/**
* Gets the adjVertices attribute of the GraphTest object
*/
private Set getAdjVertices(Graph IUT,
Vertex v)
{
Set RC = new HashSet();
Iterator edges = IUT.getEdges(v).iterator();
while (edges.hasNext())
{
Edge e = (Edge) edges.next();
Set verts = IUT.getVertices(e);
RC.addAll(verts);
}
return RC;
}
/**
* Description of the Method
*/
public Set makeSet()
{
return new HashSet();
}
/**
* Description of the Method
*/
public Set makeSet(Object v)
{
Set RC = new HashSet();
RC.add(v);
return RC;
}
/**
* Description of the Method
*/
public Set makeSet(Object v1,
Object v2)
{
Set RC = makeSet(v1);
RC.add(v2);
return RC;
}
/**
* Description of the Method
*/
public Set makeSet(Set s1,
Set s2)
{
Set RC = new HashSet();
RC.addAll(s1);
RC.addAll(s2);
return RC;
}
/**
* Description of the Method
*/
public Set makeSet(Object v1,
Object v2,
Object v3)
{
return makeSet(makeSet(v1, v2),
makeSet(v3));
}
/**
* Description of the Method
*/
public Set makeSet(Object v1,
Object v2,
Object v3,
Object v4)
{
return makeSet(makeSet(v1, v2),
makeSet(v3, v4));
}
/**
* Description of the Method
*/
public void verifyAdjVertices(DirectedGraph IUT,
Vertex v,
Set inExpect,
Set outExpect)
{
Set inbound = getInboundVertices(IUT, v);
Set outbound = getOutboundVertices(IUT, v);
Iterator verts;
// inbound is a subset of inExpect
verts = inbound.iterator();
while (verts.hasNext())
{
Vertex curr = (Vertex) verts.next();
assertTrue(curr.toString() + " is not supposed to be " +
"next to " + v.toString(),
inExpect.contains(curr));
}
// inExpect is a subset of inbound
verts = inExpect.iterator();
while (verts.hasNext())
{
Vertex curr = (Vertex) verts.next();
assertTrue(curr.toString() + " is supposed to be next to " +
v.toString(),
inbound.contains(curr));
}
// outbound is a subset of outExpect
verts = outbound.iterator();
while (verts.hasNext())
{
Vertex curr = (Vertex) verts.next();
assertTrue(curr.toString() + " is not supposed to be " +
"next to " + v.toString(),
outExpect.contains(curr));
}
// outExpect is a subset of outbound
verts = outExpect.iterator();
while (verts.hasNext())
{
Vertex curr = (Vertex) verts.next();
assertTrue(curr.toString() + " is supposed to be next to " +
v.toString(),
outbound.contains(curr));
}
}
/**
* Description of the Method
*/
public void verifyAdjVertices(Graph IUT,
Vertex v,
Set expected)
throws Throwable
{
Set adjacent = getAdjVertices(IUT, v);
Iterator adjV = adjacent.iterator();
while (adjV.hasNext())
{
Vertex curr = (Vertex) adjV.next();
assertTrue(curr.toString() + " is not supposed to be " +
"next to " + v.toString(),
expected.contains(curr));
}
Iterator expect = expected.iterator();
while (expect.hasNext())
{
Vertex curr = (Vertex) expect.next();
assertTrue(curr.toString() + " is supposed to be next to " +
v.toString(),
adjacent.contains(curr));
}
}
/**
* Description of the Method
*/
public void verifyGraph(Graph g, int numVertex, int numEdge)
throws Throwable
{
assertEquals("Incorrect Number of Vertices.",
numVertex, g.getVertices().size());
assertEquals("Incorrect Number of Edges.",
numEdge, g.getEdges().size());
}
/**
* Description of the Method
*/
public void printGraph(Throwable t,
DirectedGraph IUT)
{
System.err.println(testName + ": " + t.toString());
System.err.println("VERTICES: " + IUT.getVertices());
System.err.println("EDGES: " + IUT.getEdges());
Iterator verts = IUT.getVertices().iterator();
while (verts.hasNext())
{
Vertex vert = (Vertex) verts.next();
System.err.println("[ " + vert + " ]");
Iterator inbounds = IUT.getInbound(vert).iterator();
while (inbounds.hasNext())
{
Edge inbound = (Edge) inbounds.next();
System.err.println("\tI [" + inbound + "]");
}
Iterator outbounds = IUT.getOutbound(vert).iterator();
while (outbounds.hasNext())
{
Edge outbound = (Edge) outbounds.next();
System.err.println("\tO [" + outbound + "]");
}
}
}
}