From bb5d76e6180695604645d39c5ded5abe83bb22d9 Mon Sep 17 00:00:00 2001 From: jvanzyl Date: Mon, 12 Nov 2001 16:05:16 +0000 Subject: [PATCH] Initial revision git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/sandbox/graph/trunk@144575 13f79535-47bb-0310-9956-ffa450edef68 --- .cvsignore | 2 + LICENSE | 54 ++ PROPOSAL | 12 + README.txt | 17 + build.properties | 21 + build.xml | 174 +++++ src/conf/MANIFEST.MF | 6 + src/java/org/apache/commons/graph/BFS.java | 149 ++++ .../org/apache/commons/graph/BFSVisitor.java | 103 +++ .../org/apache/commons/graph/Constants.java | 80 +++ src/java/org/apache/commons/graph/DFS.java | 142 ++++ .../org/apache/commons/graph/DFSVisitor.java | 98 +++ .../commons/graph/DaVinciVisualizer.java | 165 +++++ .../apache/commons/graph/DefaultVisitor.java | 79 ++ src/java/org/apache/commons/graph/Edge.java | 128 ++++ .../apache/commons/graph/GMLVisualizer.java | 156 ++++ src/java/org/apache/commons/graph/Graph.java | 678 ++++++++++++++++++ .../apache/commons/graph/GraphAlgorithms.java | 149 ++++ .../org/apache/commons/graph/GraphError.java | 63 ++ .../apache/commons/graph/GraphVisualizer.java | 165 +++++ .../org/apache/commons/graph/LabeledEdge.java | 83 +++ .../apache/commons/graph/LabeledVertex.java | 82 +++ .../apache/commons/graph/PrintVisitor.java | 93 +++ .../org/apache/commons/graph/SCCVisitor.java | 169 +++++ .../org/apache/commons/graph/Sequential.java | 112 +++ .../apache/commons/graph/TraversalOrder.java | 115 +++ .../apache/commons/graph/VCGVisualizer.java | 138 ++++ src/java/org/apache/commons/graph/VQueue.java | 77 ++ src/java/org/apache/commons/graph/VStack.java | 75 ++ src/java/org/apache/commons/graph/Vertex.java | 192 +++++ .../org/apache/commons/graph/Visitor.java | 74 ++ .../apache/commons/graph/WeightedEdge.java | 89 +++ 32 files changed, 3740 insertions(+) create mode 100644 .cvsignore create mode 100644 LICENSE create mode 100644 PROPOSAL create mode 100644 README.txt create mode 100644 build.properties create mode 100644 build.xml create mode 100644 src/conf/MANIFEST.MF create mode 100644 src/java/org/apache/commons/graph/BFS.java create mode 100644 src/java/org/apache/commons/graph/BFSVisitor.java create mode 100644 src/java/org/apache/commons/graph/Constants.java create mode 100644 src/java/org/apache/commons/graph/DFS.java create mode 100644 src/java/org/apache/commons/graph/DFSVisitor.java create mode 100644 src/java/org/apache/commons/graph/DaVinciVisualizer.java create mode 100644 src/java/org/apache/commons/graph/DefaultVisitor.java create mode 100644 src/java/org/apache/commons/graph/Edge.java create mode 100644 src/java/org/apache/commons/graph/GMLVisualizer.java create mode 100644 src/java/org/apache/commons/graph/Graph.java create mode 100644 src/java/org/apache/commons/graph/GraphAlgorithms.java create mode 100644 src/java/org/apache/commons/graph/GraphError.java create mode 100644 src/java/org/apache/commons/graph/GraphVisualizer.java create mode 100644 src/java/org/apache/commons/graph/LabeledEdge.java create mode 100644 src/java/org/apache/commons/graph/LabeledVertex.java create mode 100644 src/java/org/apache/commons/graph/PrintVisitor.java create mode 100644 src/java/org/apache/commons/graph/SCCVisitor.java create mode 100644 src/java/org/apache/commons/graph/Sequential.java create mode 100644 src/java/org/apache/commons/graph/TraversalOrder.java create mode 100644 src/java/org/apache/commons/graph/VCGVisualizer.java create mode 100644 src/java/org/apache/commons/graph/VQueue.java create mode 100644 src/java/org/apache/commons/graph/VStack.java create mode 100644 src/java/org/apache/commons/graph/Vertex.java create mode 100644 src/java/org/apache/commons/graph/Visitor.java create mode 100644 src/java/org/apache/commons/graph/WeightedEdge.java diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 0000000..d9860d5 --- /dev/null +++ b/.cvsignore @@ -0,0 +1,2 @@ +*~ +target diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..cbe4f26 --- /dev/null +++ b/LICENSE @@ -0,0 +1,54 @@ +/* + * 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 acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" 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" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * 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 + * . + */ + diff --git a/PROPOSAL b/PROPOSAL new file mode 100644 index 0000000..1d34fa5 --- /dev/null +++ b/PROPOSAL @@ -0,0 +1,12 @@ +-------------------------------------------------------------------------- + J A K A R T A C O M M O N S G R A P H P A C K A G E +-------------------------------------------------------------------------- + +Abstract: + +Todo + +Initial commiters: + +Markus Dahm +Jason van Zyl diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..9101452 --- /dev/null +++ b/README.txt @@ -0,0 +1,17 @@ +-------------------------------------------------------------------------- +J A K A R T A C O M M O N S U T I L I T I E S +-------------------------------------------------------------------------- + +o Building + +To build, you must have ant installed. Just type 'ant' -- the default +target will build the jar. + +There are also a few other targets like 'javadoc'. Look in build.xml + + +o Use in your application + +To use the Commons Utility package, build a commons-util.jar file, +import the desired classes from org.apache.commons.util and and +compile your code with cup.jar in the CLASSPATH. diff --git a/build.properties b/build.properties new file mode 100644 index 0000000..7ff3dc4 --- /dev/null +++ b/build.properties @@ -0,0 +1,21 @@ +# Component delcarations +component.name = commons-graph +component.title = Jakarta Graph Utilties +component.version = 0.1-dev +component.jar = ${component.name}.jar + +# Paths +build.home = target +dist.home = dist +source.home = src +test.home = ${source.home}/test +build.dir = . + +# Compiler defaults +compile.debug = false +compile.deprecation = true +compile.optimize = true + +# Test defaults +test.failonerror = true +test.runner = junit.textui.TestRunner diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..be1ed97 --- /dev/null +++ b/build.xml @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/conf/MANIFEST.MF b/src/conf/MANIFEST.MF new file mode 100644 index 0000000..fa970e4 --- /dev/null +++ b/src/conf/MANIFEST.MF @@ -0,0 +1,6 @@ +Extension-Name: @name@ +Specification-Vendor: Apache Software Foundation +Specification-Version: 1.0 +Implementation-Vendor: Apache Software Foundation +Implementation-Title: commons-graph +Implementation-Version: 0.1-dev diff --git a/src/java/org/apache/commons/graph/BFS.java b/src/java/org/apache/commons/graph/BFS.java new file mode 100644 index 0000000..552c216 --- /dev/null +++ b/src/java/org/apache/commons/graph/BFS.java @@ -0,0 +1,149 @@ +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 + * "Apache BCEL" 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", + * "Apache BCEL", 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 + * . + */ + +import java.util.Vector; + +/** + * Visit graph with breadth first search and compute the predecessor + * during traversal for all vertices. The algorithm could be modified + * so that it performs Dijkstra's shortest-path algorithm, for + * instance, if you extend the VQueue class to a Priority Queue. + * + * @version $Id: BFS.java,v 1.1 2001/11/12 16:05:17 jvanzyl Exp $ + * @author M. Dahm + */ +public class BFS extends TraversalOrder { + private VQueue q; + + /** + * Breadth first search algorithm. + * + * @param v visitor object to apply when discovering and finishing a vertex + */ + public BFS(Visitor v) { + this(v, null); + } + + /** + * Breadth first search algorithm. + * + * @param v visitor object to apply when discovering and finishing a vertex + * @param q queue to use during traversal + */ + public BFS(Visitor v, VQueue q) { + super(v); + this.q = q; + } + + /** + * Run breadth first search (BFS) algorithm. + * + * @param g graph to traverse + * @param start vertex to start at (or null, starts at some vertex then) + */ + public void start(Graph g, Vertex start) { + int size = g.getNoVertices(); + Vertex[] vertices = g.getVertexArray(); + + visitor.discoverGraph(g); + + /* Initially mark all vertices as WHITE + */ + for(int i=0; i < size; i++) { + vertices[i].setColor(WHITE); + vertices[i].setPredecessor(null); + } + + if(start == null || !g.contains(start)) // Start BFS at (white) start vertex + start = vertices[0]; + + if(q == null) // No queue supplied + q = new VQueue(size); + + visitor.discoverVertex(start); // Initialization + + start.setColor(GRAY); + q.enqueue(start); + + while(!q.empty() && !stopped) { + Vertex u = q.head(); + + vertices = g.getVertexArray(u); // Get adjacent vertices and edges + Edge[] edges = g.getEdgeArray(u); + size = vertices.length; // reuse var + + for(int i=0; (i < size) && !stopped; i++) { // Explore all edges, same length + visitor.discoverEdge(edges[i]); + + Vertex v = vertices[i]; + if(v.getColor() == WHITE) { // Unvisited vertex? + visitor.discoverVertex(v); + + v.setColor(GRAY); + q.enqueue(v); + } + + visitor.finishEdge(edges[i]); + } + + visitor.finishVertex(u); + q.dequeue(); + u.setColor(BLACK); + } + + visitor.finishGraph(g); + } +} diff --git a/src/java/org/apache/commons/graph/BFSVisitor.java b/src/java/org/apache/commons/graph/BFSVisitor.java new file mode 100644 index 0000000..5e21b40 --- /dev/null +++ b/src/java/org/apache/commons/graph/BFSVisitor.java @@ -0,0 +1,103 @@ +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 + * "Apache BCEL" 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", + * "Apache BCEL", 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 + * . + */ + +/** + * Visit graph with BFS and compute predecessors during traversal as + * well as the "distance" to the source node (number of edges in between). + * + * @version $Id: BFSVisitor.java,v 1.1 2001/11/12 16:05:17 jvanzyl Exp $ + * @author M. Dahm + * @see BFS + */ +public class BFSVisitor extends DefaultVisitor implements Constants { + private VStack stack; // Stack to remember predecessors + + public BFSVisitor() {} + + public void discoverGraph(Graph g) { + int size = g.getNoVertices(); + Vertex[] vertices = g.getVertexArray(); + + for(int i=0; i < size; i++) { + vertices[i].setDistance(INFINITE); + vertices[i].setPredecessor(null); + } + + stack = new VStack(size); + } + + public void discoverVertex(Vertex v) { + if(stack.empty()) { // At start vertex, v == start + v.setPredecessor(null); + v.setDistance(0); + } + else { + Vertex pred = stack.top(); + v.setPredecessor(pred); + v.setDistance(pred.getDistance() + 1); + } + + stack.push(v); + } + + public void finishVertex(Vertex v) { + stack.pop(); + } + + public void visit(Graph g, Vertex start) { + new BFS(this).start(g, start); + } +} diff --git a/src/java/org/apache/commons/graph/Constants.java b/src/java/org/apache/commons/graph/Constants.java new file mode 100644 index 0000000..43622d3 --- /dev/null +++ b/src/java/org/apache/commons/graph/Constants.java @@ -0,0 +1,80 @@ +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 + * "Apache BCEL" 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", + * "Apache BCEL", 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 + * . + */ + +/** + * Constants useful for graph algorithms. + * + * @version $Id: Constants.java,v 1.1 2001/11/12 16:05:17 jvanzyl Exp $ + * @author M. Dahm + */ + +public interface Constants { + public static final int WHITE = 0; + public static final int GRAY = 1; + public static final int BLACK = 2; + + public static final int INFINITE = Integer.MAX_VALUE; + + /** + * Modes for toString(int verbose), three seem sufficient, but you can use your own + */ + public static final int PLAIN = 0; // Simple output + public static final int VERBOSE = 1; // Verbose output + public static final int TALKATIVE = 2; // Even more verbose output + public static final int V_PLAIN = 3; // Simple output for graph layout + public static final int V_VERBOSE = 4; // Verbose output for graph layout + public static final int V_TALKATIVE = 5; // Even more verbose output for graph layout +} diff --git a/src/java/org/apache/commons/graph/DFS.java b/src/java/org/apache/commons/graph/DFS.java new file mode 100644 index 0000000..9efe70d --- /dev/null +++ b/src/java/org/apache/commons/graph/DFS.java @@ -0,0 +1,142 @@ +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 + * "Apache BCEL" 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", + * "Apache BCEL", 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 + * . + */ + +/** + * Visit graph with depth first search and mark discovery and finishing time in all + * vertices. + * + * @version $Id: DFS.java,v 1.1 2001/11/12 16:05:18 jvanzyl Exp $ + * @author M. Dahm + */ +public class DFS extends TraversalOrder { + /** + * Depth first search algorithm. + * + * @param v visitor object to apply when discovering and finishing a vertex or edge + */ + public DFS(Visitor v) { + super(v); + } + + /** + * Depth first search algorithm. + * + * @param v visitor object to apply when discovering and finishing a vertex or edge + * @param traverse_all traverse the complete graph or stop after finishing all nodes reachable + * from the start + */ + public DFS(Visitor v, boolean traverse_all) { + super(v, traverse_all); + } + + /** + * Run depth first search (DFS) algorithm. + * + * @param g graph to traverse + * @param start vertex to start at (or null, starts at some vertex then) + */ + public void start(Graph g, Vertex start) { + int size = g.getNoVertices(); + Vertex[] vertices = g.getVertexArray(); + + graph = g; + + visitor.discoverGraph(g); + + /* Initially mark all vertices as WHITE + */ + for(int i=0; i < size; i++) + vertices[i].setColor(WHITE); + + if(start != null && g.contains(start)) // Start DFS at (white) start vertex + DFS_Visit(start); + + if(traverse_complete_graph) { + for(int i=0; (i < size) && !stopped; i++) { + Vertex v = vertices[i]; + + if(v.getColor() == WHITE) // Unvisited vertex? + DFS_Visit(v); + } + } + + visitor.finishGraph(g); + } + + private final void DFS_Visit(Vertex u) { + u.setColor(GRAY); // Mark as visited + visitor.discoverVertex(u); + + Vertex[] vertices = graph.getVertexArray(u); // Get adjacent vertices + Edge[] edges = graph.getEdgeArray(u); // and edges + int size = vertices.length; + //System.out.println(java.util.Arrays.asList(edges)); + + for(int i=0; (i < size) && !stopped; i++) { // Explore all edges + visitor.discoverEdge(edges[i]); + + Vertex v = vertices[i]; + + if(v.getColor() == WHITE) + DFS_Visit(v); + + visitor.finishEdge(edges[i]); + } + + u.setColor(BLACK); // Mark as finished + visitor.finishVertex(u); + } +} diff --git a/src/java/org/apache/commons/graph/DFSVisitor.java b/src/java/org/apache/commons/graph/DFSVisitor.java new file mode 100644 index 0000000..c05a896 --- /dev/null +++ b/src/java/org/apache/commons/graph/DFSVisitor.java @@ -0,0 +1,98 @@ +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 + * "Apache BCEL" 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", + * "Apache BCEL", 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 + * . + */ + +/** + * Visit graph with DFS and compute predecessors during traversal as + * well as discovery and finishing time of all vertices. Instances of + * this class (and of course its descendants) may be passed to a DFS + * object. + * + * @version $Id: DFSVisitor.java,v 1.1 2001/11/12 16:05:18 jvanzyl Exp $ + * @author M. Dahm + * @see DFS + */ +public class DFSVisitor extends DefaultVisitor { + private int time; // Global time + private VStack stack; // Stack to remember predecessors + + public DFSVisitor() {} + + public void discoverGraph(Graph g) { + int size = g.getNoVertices(); + Vertex[] vertices = g.getVertexArray(); + + for(int i=0; i < size; i++) + vertices[i].setPredecessor(null); + + time = 0; // Reset timer + stack = new VStack(size); + } + + public void discoverVertex(Vertex v) { + if(stack.empty()) // First node + v.setPredecessor(null); + else + v.setPredecessor(stack.top()); + + stack.push(v); + v.setDiscoveryTime(time++); + } + + public void finishVertex(Vertex v) { + v.setFinishingTime(time++); + stack.pop(); + } +} diff --git a/src/java/org/apache/commons/graph/DaVinciVisualizer.java b/src/java/org/apache/commons/graph/DaVinciVisualizer.java new file mode 100644 index 0000000..ce946e0 --- /dev/null +++ b/src/java/org/apache/commons/graph/DaVinciVisualizer.java @@ -0,0 +1,165 @@ +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 + * "Apache BCEL" 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", + * "Apache BCEL", 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 + * . + */ + +import java.io.OutputStream; + +/** + * Visualizes directed graphs into the + * + * DaVinci format. It can only be used for directed graphs and does not support + * labeled edges very well, unfortunately. They have to be simulated via dummy vertices. + * + * Traverses graph with the Sequential visitor, since it uses invariants of that algorithm. + * + * @version $Id: DaVinciVisualizer.java,v 1.1 2001/11/12 16:05:18 jvanzyl Exp $ + * @author M. Dahm + */ +public class DaVinciVisualizer extends GraphVisualizer implements Constants { + private Graph graph; + private int no_edges, edges; + private int no_vertices, vertices; + + /** + * @param out stream to print output to + * @param verbose toggle verbosity of output + */ + public DaVinciVisualizer(OutputStream out, int verbose) { + super(out, verbose); + } + + public void discoverGraph(Graph g) { + graph = g; + + no_vertices = g.getNoVertices(); + vertices = 0; + out.println("["); + } + + public void finishGraph(Graph g) { + out.println("]"); + out.close(); + } + + public void discoverVertex(Vertex v) { + String label = convertString(v.toString(verbose)); + //System.out.println("vertex:" + v.getIdent() + ":" + v); + + println(1, "l(\"" + v.getIdent() + "\","); + println(1, "n(\"anything\", ["); + println(2, "a(\"OBJECT\", \"" + label + "\"),"); + println(2, "a(\"FONTSTYLE\", \"bold\"),"); + println(2, "a(\"FONTFAMILY\", \"courier\")],"); + println(1, "["); // array of successor nodes + + no_edges = graph.getNoEdges(v); + edges = 0; + } + + public void finishVertex(Vertex v) { + String str = (vertices < no_vertices - 1)? "]))," : "]))"; + println(1, str); + vertices++; + } + + private static int label_counter=0; + + private final String getEdgeAttribute() { + if(graph.isDirected()) + return ""; + else + return "a(\"_DIR\", \"none\""; + } + + public void discoverEdge(Edge e) { + int u = graph.getSource(e).getIdent(); + int v = graph.getTarget(e).getIdent(); + String label = convertString(e.toString(verbose)); + + if(label.equals("")) { + print(2, "l(\"" + u + "->" + v + "\", e(\"\", [" + getEdgeAttribute() + + "], r(\"" + v + "\")))"); + } else { // Simulate labeled edge with intermediate node + String dummy = "label" + label_counter++; // Dummy name for intermediate node + + print(2, "l(\"" + u + "->" + dummy + "\", e(\"\", [a(\"_DIR\", \"none\")], " + + "l(\"" + dummy + "\", n(\"anything\",[a(\"OBJECT\", \"" + label + + "\"), a(\"_GO\", \"text\")], [l(\"" + dummy + "->" + v + + "\", e(\"\",[" + getEdgeAttribute() + "], r(\"" + v + "\")))]))))"); + //System.out.println(graph.getTarget(e).getIdent() + ":" + graph.getTarget(e)); + } + } + + public void finishEdge(Edge e) { + if(edges < no_edges - 1) + out.println(", "); + else + out.print('\n'); + + edges++; + } + + /** + * Visualize graph g with this Visualizer. + * + * @param g graph to visualize + * @param start node to start at + */ + public void visualize(Graph g, Vertex start) { + new Sequential(this).start(g); + } +} + + diff --git a/src/java/org/apache/commons/graph/DefaultVisitor.java b/src/java/org/apache/commons/graph/DefaultVisitor.java new file mode 100644 index 0000000..44db502 --- /dev/null +++ b/src/java/org/apache/commons/graph/DefaultVisitor.java @@ -0,0 +1,79 @@ +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 + * "Apache BCEL" 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", + * "Apache BCEL", 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 + * . + */ + +/** + * Empty Visitor, i.e. all visit methods do nothing. + * + * @version $Id: DefaultVisitor.java,v 1.1 2001/11/12 16:05:18 jvanzyl Exp $ + * @author M. Dahm + */ +public class DefaultVisitor implements Visitor { + protected DFS dfs; + + public DefaultVisitor() {} + + public void discoverGraph(Graph g) {} + public void finishGraph(Graph g) {} + public void discoverVertex(Vertex v) {} + public void finishVertex(Vertex v) { } + public void discoverEdge(Edge e) {} + public void finishEdge(Edge e) {} + + public void visit(Graph g, Vertex start) { + dfs = new DFS(this); + dfs.start(g, start); + } +} diff --git a/src/java/org/apache/commons/graph/Edge.java b/src/java/org/apache/commons/graph/Edge.java new file mode 100644 index 0000000..371fca8 --- /dev/null +++ b/src/java/org/apache/commons/graph/Edge.java @@ -0,0 +1,128 @@ +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 + * "Apache BCEL" 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", + * "Apache BCEL", 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 + * . + */ + +/** + * Describes an edge between two vertices of a graph, i.e. a relation between + * two arbitrary vertices. + * + * @version $Id: Edge.java,v 1.1 2001/11/12 16:05:18 jvanzyl Exp $ + * @author M. Dahm + */ +public class Edge implements Cloneable, Constants, java.io.Serializable { + private int ident; // unique number, i.e. identifier + private static int counter; // produce default numbers + + /** + * Create edge. + */ + public Edge() { + ident = counter++; + } + + /** + * @return ident, i.e. identifier of this node + */ + public final int getIdent() { return ident; } + + /** + * @return number of created edges + */ + public static final int getCounter() { return counter; } + + /** + * @return String representation. + */ + public String toString() { + return toString(PLAIN); + } + + /** + * @param verbose toggle output format + * @return String representation. + */ + public String toString(int verbose) { + if((verbose == TALKATIVE) || (verbose == V_TALKATIVE)) + return "Edge(" + ident + ")"; + + return ""; + } + + /** + * Access for visitor patterns + */ + public void accept(Visitor v) { v.discoverEdge(this); } + + /** + * @return deep copy + */ + public Edge copy() { + try { + return (Edge)clone(); + } catch(CloneNotSupportedException e) {} + + return null; + } + + /** Check for equality. + */ + public boolean equals(Object o) { + if(!(o instanceof Edge)) + return false; + + Edge e = (Edge)o; + return e.ident == ident; + } +} diff --git a/src/java/org/apache/commons/graph/GMLVisualizer.java b/src/java/org/apache/commons/graph/GMLVisualizer.java new file mode 100644 index 0000000..10bf8ee --- /dev/null +++ b/src/java/org/apache/commons/graph/GMLVisualizer.java @@ -0,0 +1,156 @@ +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 + * "Apache BCEL" 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", + * "Apache BCEL", 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 + * . + */ +import java.io.OutputStream; + +/** + * Visualizes graphs into the GML + * format. + * + * @version $Id: GMLVisualizer.java,v 1.1 2001/11/12 16:05:18 jvanzyl Exp $ + * @author M. Dahm + */ +public class GMLVisualizer extends GraphVisualizer { + private Graph graph; + + /** + * @param out stream to print output to + * @param verbose toggle verbosity of output + */ + public GMLVisualizer(OutputStream out, int verbose) { + super(out, verbose); + } + + public void discoverGraph(Graph g) { + String d = g.isDirected()? "1" : "0"; + + graph = g; + + println(0, "graph ["); + println(1, "Creator\t \"GMLVisualizer\""); + println(1, "id\t " + Vertex.getCounter()); // Make sure this is a unique number + println(1, "directed\t " + d + "\n"); + } + + public void finishGraph(Graph g) { + println(0, "]\n"); + out.close(); + } + + public void discoverVertex(Vertex v) { + println(1, "node ["); + println(2, "id\t " + v.getIdent()); + println(2, "label"); + + out.println("\"" + v.toString(verbose) + "\""); + + println(2, "graphics ["); + println(3, "type\t\t \"rectangle\""); + println(3, "fill\t\t \"white\""); + println(3, "outline\t\t \"black\""); + println(3, "background\t \"blue\""); + println(3, "foreground\t \"green\""); + println(2, "]\n"); + + println(2, "LabelGraphics ["); + println(3, "type\t \"text\""); + println(3, "fill\t \"black\""); + println(3, "justify\t \"left\""); + println(2, "]\n"); + + println(1, "]\n"); + } + + public void finishVertex(Vertex v) {} + + public void discoverEdge(Edge e) { + int src = graph.getSource(e).getIdent(); + int target = graph.getTarget(e).getIdent(); + + println(1, "edge ["); + println(2, "source\t " + src); + println(2, "target\t " + target); + + println(2, "label"); + out.println("\"" + e.toString(verbose) + "\""); + + println(2, "graphics ["); + + println(3, "fill\t \"black\""); + //println(3, "fill\t\t \"white\""); + + println(3, "arrow\t \"last\""); + println(2, "]\n"); + + println(2, "LabelGraphics ["); + println(3, "type\t \"text\""); + println(3, "fill\t \"black\""); + println(2, "]\n"); + + println(1, "]\n"); + } + + public void finishEdge(Edge e) {} + + /** + * Visualize graph g with this Visualizer. + * + * @param g graph to visualize + * @param start node to start at + */ + public void visualize(Graph g, Vertex start) { + new DFS(this).start(g, start); + } +} diff --git a/src/java/org/apache/commons/graph/Graph.java b/src/java/org/apache/commons/graph/Graph.java new file mode 100644 index 0000000..d1a1ae3 --- /dev/null +++ b/src/java/org/apache/commons/graph/Graph.java @@ -0,0 +1,678 @@ +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 + * "Apache BCEL" 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", + * "Apache BCEL", 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 + * . + */ + +import java.util.*; +import java.util.zip.*; +import java.io.*; + +/** + * Describes a generic graph G = (V, E), i.e. a set of vertices and edges. + * + * @version $Id: Graph.java,v 1.1 2001/11/12 16:05:19 jvanzyl Exp $ + * @author M. Dahm + */ +public class Graph implements Cloneable, Constants, Serializable { + private boolean directed = true; + + /* Map Vertex to VertexWrapper and Edge to EdgeWrapper, + * respectively. Wrapper objects carry the necessary information + * about associations between vertices. VertexWrappers contain the + * edges coming from and leading to a vertex (if the graph is undirected both + * vertices "have" this edge, otherwise the source vertex only "has" it). + * EdgeWrappers contain references to the source and target vertices. + */ + private Map vmap = new HashMap(); + private Map emap = new HashMap(); + + /** + * Create empty directed graph. + */ + public Graph() {} + + /** + * Create directed graph initialized with a set of subgraphs. + */ + public Graph(Graph[] graphs) { + for(int i=0; i < graphs.length; i++) { + addGraph(graphs[i]); + } + } + + /** + * Create empty graph. + * @param d graph is directed? + */ + public Graph(boolean d) { + directed = d; + } + + /** + * Read graph from file using Serializable. + * + * @param name file name to read from + */ + public Graph(String name) throws IOException, ClassNotFoundException + { + this(new FileInputStream(name)); + } + + /** + * Read graph from input stream using Serializable. + * + * @param stream stream to read from + */ + public Graph(InputStream stream) throws IOException, ClassNotFoundException + { + ObjectInputStream oi = new ObjectInputStream(new GZIPInputStream(stream)); + Graph g = (Graph)oi.readObject(); + + this.directed = g.directed; + this.vmap = g.vmap; + this.emap = g.emap; + } + + /* Add sub graph to this graph. + */ + public void addGraph(Graph g) { + Vertex[] vertices = g.getVertexArray(); + for(int j=0; j < vertices.length; j++) + addVertex(vertices[j]); + + Edge[] edges = g.getEdgeArray(); + for(int j=0; j < edges.length; j++) + addEdge(g.getSource(edges[j]), g.getTarget(edges[j]), edges[j]); + } + + /** + * Add a vertex to the graph. + * @param v vertex to add + */ + public void addVertex(Vertex v) { + if(v == null) + throw new GraphError("Vertex must not be null"); + + vmap.put(v, new VertexWrapper(v)); + } + + /** + * Add a (default) edge between two vertices to the graph. + * + * @param u source vertex. + * @param v target vertex. + */ + public void addEdge(Vertex u, Vertex v) { + addEdge(u, v, new Edge()); + } + + /** + * Add an edge between two vertices to the graph. + * + * @param u source vertex. + * @param v target vertex. + * @param e edge between + */ + public void addEdge(Vertex u, Vertex v, Edge e) { + VertexWrapper uw = getWrapper(u); + VertexWrapper vw = getWrapper(v); + + if(e == null) + throw new GraphError("Edge must not be null"); + + emap.put(e, new EdgeWrapper(e, u, v)); + uw.addEdge(e); + + if(!directed) // Add edge to the other side, too + vw.addEdge(e); + + vw.addPredecessorEdge(e); + } + + /** + * Remove given vertex and the edges that connect it to other vertices. + * + * @param v abandoned vertex. + */ + public void removeVertex(Vertex v) { + VertexWrapper vw = getWrapper(v); + + Edge[] edges = vw.getEdges(); // Remove all adjacent edges + + if(!directed) { // Inform other side of the edge that it has to be removed + for(int i=0; i < edges.length; i++) { + EdgeWrapper ew = getWrapper(edges[i]); + Vertex u = (ew.src == v)? ew.target : ew.src; + VertexWrapper uw = getWrapper(u); + uw.removeEdge(edges[i]); + } + } else { + for(int i=0; i < edges.length; i++) { + VertexWrapper uw = getWrapper(getWrapper(edges[i]).target); + uw.removePredecessorEdge(edges[i]); + } + } + + vmap.remove(v); // Remove vertex from the hash map + + // Finally remove the edges from the hash map + for(int i=0; i < edges.length; i++) + emap.remove(edges[i]); + } + + /** + * Remove given edge from the graph. + * + * @param e abandoned edge. + */ + public void removeEdge(Edge e) { + EdgeWrapper ew = getWrapper(e); + emap.remove(e); // Remove edge from the hash map + + // Update source vertex + VertexWrapper vw = getWrapper(ew.src); + vw.removeEdge(e); + + if(!directed) { // Inform other node, too + vw = getWrapper(ew.target); + vw.removeEdge(e); + } + } + + /** + * Get source vertex of edge. Order between source and target doesn't + * really matter if this graph is undirected. + * + * @param e edge. + */ + public final Vertex getSource(Edge e) { return getWrapper(e).src; } + + /** + * Get target vertex of edge. Order between source and target doesn't + * really matter if this graph is undirected. + * + * @param e edge. + */ + public final Vertex getTarget(Edge e) { return getWrapper(e).target; } + + /** + * @return number of vertices. + */ + public final int getNoVertices() { return vmap.size(); } + + /** + * @return number of edges. + */ + public final int getNoEdges() { return emap.size(); } + + /** + * @return all vertices of the graph. + */ + public Collection getVertices() { return vmap.keySet(); } + + /** + * @return all edges of the graph. + */ + public Collection getEdges() { return emap.keySet(); } + + /** + * @return all vertices of the graph. + */ + public final Vertex[] getVertexArray() { + return (Vertex[])getVertices().toArray(new Vertex[getNoVertices()]); + } + + /** + * @return all edges of the graph. + */ + public final Edge[] getEdgeArray() { + return (Edge[])getEdges().toArray(new Edge[getNoEdges()]); + } + + /** + * @return all edges between source and target + */ + public Edge[] getEdgeArray(Vertex source, Vertex target) { + Collection c = getEdges(source, target); + return (Edge[])c.toArray(new Edge[c.size()]); + } + + /** + * @return all edges between source and target + */ + public Collection getEdges(Vertex source, Vertex target) { + Edge[] edges = getEdgeArray(source); + List list = new ArrayList(); + + for(int i=0; i < edges.length; i++) + if(getTarget(edges[i]) == target) + list.add(edges[i]); + + return list; + } + + /** + * @return all vertices adjacent to v. + */ + public Vertex[] getVertexArray(Vertex v) { + Edge[] edges = getEdgeArray(v); + int size = edges.length; + Vertex[] vertices = new Vertex[size]; + + /* Take the other side of the edge, no matter if directed or not + */ + for(int i=0; i < size; i++) { + EdgeWrapper ew = getWrapper(edges[i]); + vertices[i] = (ew.src == v)? ew.target : ew.src; + } + + return vertices; + } + + /** + * @return number of vertices adjacent to v. + */ + public int getNoVertices(Vertex v) { + VertexWrapper vw = getWrapper(v); + return vw.edges.size(); + } + + /** + * @return number of edges adjacent to v. + */ + public final int getNoEdges(Vertex v) { + return getNoVertices(v); + } + + /** + * @return all edges adjacent to v. + */ + public Edge[] getEdgeArray(Vertex v) { + VertexWrapper vw = getWrapper(v); + return vw.getEdges(); + } + + /** + * @return all vertices adjacent to v. + */ + public Collection getVertices(Vertex v) { + return Arrays.asList(getVertexArray(v)); + } + + /** + * @return all edges adjacent to v. + */ + public Collection getEdges(Vertex v) { + return Arrays.asList(getEdgeArray(v)); + } + + /** + * Get all vertices from which v may be reached directly, in an undirected + * graph, this is identical to getVertexArray(v) + * + * @return all predecessor vertices of v + */ + public Vertex[] getPredecessorArray(Vertex v) { + if(!directed) + return getVertexArray(v); + + Collection c = getPredecessors(v); + return (Vertex[])c.toArray(new Vertex[c.size()]); + } + + /** + * Get all vertices from which v may be reached directly, in an undirected + * graph, this is identical to getVertices(v) + * + * @return all predecessor vertices of v + */ + public Collection getPredecessors(Vertex v) { + if(!directed) + return getVertices(v); + + List list = new ArrayList(); + Collection edges = getWrapper(v).pred_edges; + + for(Iterator i = edges.iterator(); i.hasNext(); ) + list.add(getWrapper(((Edge)i.next())).src); + + return list; + } + + public Edge[] getPredecessorEdgeArray(Vertex v) { + if(!directed) + return getEdgeArray(v); + + Collection edges = getWrapper(v).pred_edges; + + return (Edge[])edges.toArray(new Edge[edges.size()]); + } + + /** + * Get all edges pointing to v, in an undirected + * graph, this is identical to getEdges(v) + * + * @return all predecessor vertices of v + */ + public Collection getPredecessorEdges(Vertex v) { + if(!directed) + return getEdges(v); + + return (Collection)((ArrayList)getWrapper(v).pred_edges).clone(); + } + + /** + * Is v in this graph? + */ + public final boolean contains(Vertex v) { + return vmap.containsKey(v); + } + + /** + * Is e in this graph? + */ + public final boolean contains(Edge e) { + return emap.containsKey(e); + } + + /** + * Check, if v is a vertex of graph g. + */ + public static final boolean contains(Graph g, Vertex v) { + return g.contains(v); + } + + /** + * Check, if e is an edge of graph g. + */ + public static final boolean contains(Graph g, Edge e) { + return g.contains(e); + } + + /** + * Check, if g is a subgraph of super_g, i.e. if all vertices and edges of g are + * contained in super_g, too. + * + * @param super_g the super graph + * @param g the subgraph + */ + public static final boolean contains(Graph super_g, Graph g) { + for(Iterator i = g.getVertices().iterator(); i.hasNext();) { + Vertex v = (Vertex)i.next(); + if(!contains(super_g, v)) + return false; + } + + for(Iterator i = g.getEdges().iterator(); i.hasNext();) { + Edge e = (Edge)i.next(); + if(!contains(super_g, e)) + return false; + } + + return true; + } + + /** + * Check, if g is a subgraph of this graph. Tests for object equivalence (==). + */ + public final boolean contains(Graph g) { + return contains(this, g); + } + + /** + * Access for visitor patterns + */ + public void accept(Visitor v) { v.discoverGraph(this); } + + /** + * Is this graph directed? + */ + public final boolean isDirected() { return directed; } + + /** + * @return wrapper object corresponding to vertex or throw an exception. + */ + private final VertexWrapper getWrapper(Vertex v) { + VertexWrapper vw = (VertexWrapper)vmap.get(v); + + if(vw == null) + throw new GraphError("Vertex not contained in this graph: " + v); + + return vw; + } + + /** + * @return wrapper object corresponding to edge or throw an exception. + */ + private final EdgeWrapper getWrapper(Edge e) { + EdgeWrapper ew = (EdgeWrapper)emap.get(e); + + if(ew == null) + throw new GraphError("Edge not contained in this graph: " + e); + + return ew; + } + + public String toString() { + return toString(PLAIN); + } + + /** + * @return graph contents traversed with DFS + */ + public String toString(int verbose) { + if(verbose == PLAIN) + return printArray(getVertexArray()); + else { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + PrintWriter out = new PrintWriter(bos); + + new DFS(new PrintVisitor(out, VERBOSE)).start(this); + out.close(); + + return bos.toString(); + } + } + + /** + * All vertices and edges are copied deeply, i.e. copy() will be called on + * them recursively. + * + * @return deep copy of this graph. + */ + public Graph copy() { + Graph g = new Graph(directed); + + for(Iterator i = getVertices().iterator(); i.hasNext();) { + Vertex v = ((Vertex)i.next()).copy(); + g.addVertex(v); + } + + for(Iterator i = getEdges().iterator(); i.hasNext();) { + Edge e = (Edge)i.next(); + EdgeWrapper ew = getWrapper(e); + + g.addEdge(ew.src, ew.target, e.copy()); + } + + return g; + } + + public Graph copy(Vertex start) { + final Graph g = new Graph(directed); + + new DFS(new DefaultVisitor() { + public void discoverVertex(Vertex v) { + g.addVertex(v); + } + + public void finishEdge(Edge e) { + EdgeWrapper ew = getWrapper(e); + + g.addEdge(ew.src, ew.target, e); + } + }, false).start(this, start); + + return g; + } + + /** + * @return shallow copy of this graph, i.e. all vertices and edges keep their + * object identity + */ + public Object clone() { + Graph g = new Graph(directed); + + for(Iterator i = getVertices().iterator(); i.hasNext();) { + Vertex v = ((Vertex)i.next()); + g.addVertex(v); + } + + for(Iterator i = getEdges().iterator(); i.hasNext();) { + Edge e = (Edge)i.next(); + EdgeWrapper ew = getWrapper(e); + + g.addEdge(ew.src, ew.target, e); + } + + return g; + } + + /* Wrap association information into class, s.a. + */ + private static final class VertexWrapper implements Serializable { + Vertex vertex; + List edges = new ArrayList(3); + List pred_edges = new ArrayList(3); + + final void addEdge(Edge e) { edges.add(e); } + final void addPredecessorEdge(Edge e) { pred_edges.add(e); } + final void removeEdge(Edge e) { edges.remove(e); } + final void removePredecessorEdge(Edge e) { pred_edges.remove(e); } + + final Edge[] getEdges() { + return (Edge[])edges.toArray(new Edge[edges.size()]); + } + + VertexWrapper(Vertex v) { + vertex = v; + } + } + + /* Wrap association information into class, s.a. + */ + private static final class EdgeWrapper implements Serializable { + Edge edge; + Vertex src, target; + + EdgeWrapper(Edge e, Vertex u, Vertex v) { + edge = e; + src = u; + target = v; + } + } + + /** Clear all vertex attributes like color, distance, ... + */ + public void clearVertices() { + for(Iterator i = getVertices().iterator(); i.hasNext();) { + Vertex v = ((Vertex)i.next()); + v.setColor(-1); + v.setDistance(-1); + v.setDiscoveryTime(-1); + v.setFinishingTime(-1); + v.setPredecessor(null); + } + } + + /** + * Dump graph to file using Serializable. + * + * @param name file name to dump to + */ + public void dump(String name) throws IOException { + dump(new FileOutputStream(name)); + } + + /** + * Dump graph to output stream using Serializable. + * + * @param stream stream to dump to + */ + public void dump(OutputStream stream) throws IOException { + ObjectOutputStream oo = new ObjectOutputStream(new GZIPOutputStream(stream)); + oo.writeObject(this); + oo.close(); + } + + /** + * Print the given array using toString() where appropiate. + */ + private static final String printArray(Object[] obj) { + StringBuffer buf = new StringBuffer("{"); + + for(int i=0; i < obj.length; i++) { + if(obj[i] != null) + buf.append(obj[i].toString()); + else + buf.append("null"); + + if(i < obj.length - 1) + buf.append(", "); + } + buf.append('}'); + + return buf.toString(); + } +} diff --git a/src/java/org/apache/commons/graph/GraphAlgorithms.java b/src/java/org/apache/commons/graph/GraphAlgorithms.java new file mode 100644 index 0000000..336e96d --- /dev/null +++ b/src/java/org/apache/commons/graph/GraphAlgorithms.java @@ -0,0 +1,149 @@ +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 + * "Apache BCEL" 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", + * "Apache BCEL", 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 + * . + */ + +import java.util.*; + +/** + * Collection of graph algorithms such as transposeGraph. + * + * @version $Id: GraphAlgorithms.java,v 1.1 2001/11/12 16:05:18 jvanzyl Exp $ + * @author M. Dahm + */ +public abstract class GraphAlgorithms implements Constants { + /** + * Compute the inverse of a graph, i.e. with all edges reverted + */ + public static final Graph transposeGraph(Graph g) { + if(!g.isDirected()) + throw new GraphError("Can only transpose directed graphs"); + + Graph graph = new Graph(true); + + for(Iterator i=g.getVertices().iterator(); i.hasNext();) + graph.addVertex((Vertex)i.next()); + + for(Iterator i=g.getEdges().iterator(); i.hasNext();) { + Edge f = (Edge)i.next(); + + graph.addEdge(g.getTarget(f), g.getSource(f), f); + } + + return graph; + } + + /** + * Test whether the SCC g is a loop. + * + * @param super_g super graph containing the subset of vertices + * @param g subset of super_g (g must be SCC of super_g) + */ + public static final boolean isLoop(Graph super_g, Graph loop) { + return findLoopEntry(super_g, loop) != null; + } + + /** + * Test whether the SCC g is a loop. + * + * @param super_g super graph containing the subset of vertices + * @param g subset of super_g (g must be SCC of super_g) + * @return root node of loop, i.e. the entry point, or null if this is no loop + */ + public static final Vertex findLoopEntry(Graph super_g, Graph loop) { + switch(loop.getNoVertices()) { + case 0: + return null; // certainly not a loop + + case 1: // singleton must point to itself, i.e. be a self-loop + Vertex v = loop.getVertexArray()[0]; + Vertex[] edges = loop.getVertexArray(v); + + for(int i=0; i < edges.length; i++) + if(edges[i] == v) + return v; + + return null; + } + + /* Make sure that the root node is the only entry point to the + * SCC, i.e. there is no way from a node v \in (super_g \ g) into + * a node in g except via the root node. + * + * So we have to find the root node first ... + */ + Vertex root = null; + Vertex[] vertices = super_g.getVertexArray(); + + for(int i=0; i < vertices.length; i++) { + Vertex v = vertices[i]; + + if(loop.contains(v)) // v is in the SCC, no check needed + continue; + + Vertex[] edges = super_g.getVertexArray(v); // All nodes reachable from v + for(int j=0; j < edges.length; j++) { + Vertex u = edges[j]; + + if(loop.contains(u)) + if(root == null) + root = u; + else + return null; // Can't be a loop then, i.e. has more than one root node + } + } + + return root; // Has loop a root node at all !? + } +} diff --git a/src/java/org/apache/commons/graph/GraphError.java b/src/java/org/apache/commons/graph/GraphError.java new file mode 100644 index 0000000..c2f3cfc --- /dev/null +++ b/src/java/org/apache/commons/graph/GraphError.java @@ -0,0 +1,63 @@ +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 + * "Apache BCEL" 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", + * "Apache BCEL", 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 + * . + */ + +/** + * @version $Id: GraphError.java,v 1.1 2001/11/12 16:05:18 jvanzyl Exp $ + * @author M. Dahm + */ +public class GraphError extends RuntimeException { + public GraphError(String s) { super(s); } +} diff --git a/src/java/org/apache/commons/graph/GraphVisualizer.java b/src/java/org/apache/commons/graph/GraphVisualizer.java new file mode 100644 index 0000000..ab764c6 --- /dev/null +++ b/src/java/org/apache/commons/graph/GraphVisualizer.java @@ -0,0 +1,165 @@ +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 + * "Apache BCEL" 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", + * "Apache BCEL", 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 + * . + */ +import java.io.*; +import java.util.StringTokenizer; + +/** + * Abstract super class for drivers that visualize graphs + * in different graph formats such as + * GML or + * + * daVinci or + * VCG. + * + * By default graphs are dumped in the native Java format, i.e. by using the + * Serialization feature. + * + * @version $Id: GraphVisualizer.java,v 1.1 2001/11/12 16:05:19 jvanzyl Exp $ + * @author M. Dahm + * @see DaVinciVisualizer + * @see GMLVisualizer + * @see VCGVisualizer + */ +public class GraphVisualizer implements Visitor { + protected OutputStream orig_out; + protected PrintWriter out; + protected int verbose; + + /** + * @param out stream to print output to + * @param verbose toggle verbosity + */ + public GraphVisualizer(OutputStream out, int verbose) { + orig_out = out; + this.out = new PrintWriter(out, true); + this.verbose = verbose; + } + + /** + * Print string using ident tab as prefix, used for nested calls + * + * @param indent how many tabs + * @param s string to print + */ + protected final void print(int indent, String s) { + for(int i=0; i < indent; i++) + out.print('\t'); + + out.print(s); + } + + /** + * Print string using ident tab as prefix, used for nested calls + * + * @param indent how many tabs + * @param s string to print + */ + protected final void println(int indent, String s) { + print(indent, s); + out.print('\n'); + } + + + /** + * Escape all occurences of newline chars '\n' and quotes \" + */ + protected static final String convertString(String label) { + char[] ch = label.toCharArray(); + StringBuffer buf = new StringBuffer(); + + for(int i=0; i < ch.length; i++) { + switch(ch[i]) { + case '\n': + buf.append("\\n"); break; + case '\"': + buf.append("\\\""); break; + case '\\': + buf.append("\\\\"); break; + default: + buf.append(ch[i]); break; + } + } + + return buf.toString(); + } + + /** + * Visualize graph g with this Visualizer. + * + * @param g graph to visualize + * @param start node to start at + */ + public void visualize(Graph g, Vertex start) { + try { + g.dump(orig_out); + } catch(IOException e) { + System.err.println(e); + } + + out.close(); + } + + public void discoverGraph(Graph g) {} + public void finishGraph(Graph g) {} + public void discoverVertex(Vertex v) {} + public void finishVertex(Vertex v) {} + public void discoverEdge(Edge e) {} + public void finishEdge(Edge e) {} + + public void visit(Graph g, Vertex start) { + visualize(g, start); + } +} diff --git a/src/java/org/apache/commons/graph/LabeledEdge.java b/src/java/org/apache/commons/graph/LabeledEdge.java new file mode 100644 index 0000000..b3e920e --- /dev/null +++ b/src/java/org/apache/commons/graph/LabeledEdge.java @@ -0,0 +1,83 @@ +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 + * "Apache BCEL" 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", + * "Apache BCEL", 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 + * . + */ + +/** + * Describes a labeled edge between two vertices of a graph. + * + * @version $Id: LabeledEdge.java,v 1.1 2001/11/12 16:05:19 jvanzyl Exp $ + * @author M. Dahm + */ +public class LabeledEdge extends Edge { + private String label; + + /** + * Create edge with label. + */ + public LabeledEdge(String l) { + label = l; + } + + /** + * @param verbose toggle output format + * @return String representation. + */ + public String toString(int verbose) { + return label; + } + + public final String getLabel() { return label; } + public final void setLabel(String l) { label = l; } +} diff --git a/src/java/org/apache/commons/graph/LabeledVertex.java b/src/java/org/apache/commons/graph/LabeledVertex.java new file mode 100644 index 0000000..dd7b70d --- /dev/null +++ b/src/java/org/apache/commons/graph/LabeledVertex.java @@ -0,0 +1,82 @@ +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 + * "Apache BCEL" 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", + * "Apache BCEL", 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 + * . + */ + +/** + * Describes a labeled vertex of a graph. + * + * @version $Id: LabeledVertex.java,v 1.1 2001/11/12 16:05:19 jvanzyl Exp $ + * @author M. Dahm + */ +public class LabeledVertex extends Vertex { + private String label; + + /** + * Create vertex with label l + */ + public LabeledVertex(String l) { + label = l; + } + + /** + * @param verbose toggle output format + * @return String representation. + */ + public String toString(int verbose) { + return label; + } + + public final String getLabel() { return label; } +} diff --git a/src/java/org/apache/commons/graph/PrintVisitor.java b/src/java/org/apache/commons/graph/PrintVisitor.java new file mode 100644 index 0000000..bb6d883 --- /dev/null +++ b/src/java/org/apache/commons/graph/PrintVisitor.java @@ -0,0 +1,93 @@ +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 + * "Apache BCEL" 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", + * "Apache BCEL", 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 + * . + */ +import java.io.PrintWriter; + +/** + * Visit graph with depth first search and simply prints the current + * vertices and edges as they are discovered. May be used with DFS, BFS, + * Sequential or any other visitor. Uses DFS by default. + * + * @version $Id: PrintVisitor.java,v 1.1 2001/11/12 16:05:19 jvanzyl Exp $ + * @author M. Dahm +*/ +public class PrintVisitor implements Visitor { + private PrintWriter out; + private int verbose; + + /** + * Simply print vertex and edge contents, when visiting them. + * + * @param o stream to print to + * @param v toggle verbosity of output + * @see Constants + */ + public PrintVisitor(PrintWriter o, int v) { + out = o; + verbose = v; + } + + public void discoverGraph(Graph g) {} + public void finishGraph(Graph g) {} + public void finishVertex(Vertex v) {} + public void finishEdge(Edge e) {} + + public void discoverVertex(Vertex v) { out.println(v.toString(verbose)); } + public void discoverEdge(Edge e) { out.println(e.toString(verbose)); } + + public void visit(Graph g, Vertex start) { + new DFS(this).start(g, start); + } +} diff --git a/src/java/org/apache/commons/graph/SCCVisitor.java b/src/java/org/apache/commons/graph/SCCVisitor.java new file mode 100644 index 0000000..20d6ef1 --- /dev/null +++ b/src/java/org/apache/commons/graph/SCCVisitor.java @@ -0,0 +1,169 @@ +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 + * "Apache BCEL" 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", + * "Apache BCEL", 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 + * . + */ + +import java.util.Vector; + +/** + * Visit graph computing its "Strongly Connected Components" (SCC). + * + * @version $Id: SCCVisitor.java,v 1.1 2001/11/12 16:05:20 jvanzyl Exp $ + * @author M. Dahm + * @see DFS + */ +public class SCCVisitor implements Visitor { + private int time; // Global time + private VStack stack; // Stack to remember members of a SCC + private Vector sccs; // Forest of SCCs + private Graph graph; + private Graph[] graphs; + private int size; + + public SCCVisitor() {} + + public void discoverGraph(Graph g) { + graph = g; + size = g.getNoVertices(); + Vertex[] vertices = g.getVertexArray(); + + for(int i=0; i < size; i++) { + vertices[i].setDiscoveryTime(0); + /* Should rather be setMyMinTime(), "abused" to remember local minimum + */ + vertices[i].setFinishingTime(size * 2); // Invalidate + } + + time = 0; // Reset timer + stack = new VStack(size); + sccs = new Vector(); + } + + + public void discoverVertex(Vertex v) { + int min = time++; // Clock tick + v.setDiscoveryTime(min); // Remember time of discovery + v.setFinishingTime(min); // Remember local minimum + stack.push(v); // Push current node on stack + } + + public void discoverEdge(Edge e) {} + + public void finishEdge(Edge e) { + Vertex src = graph.getSource(e); + Vertex target = graph.getTarget(e); + int m = target.getFinishingTime(); + + /* After recursion, test if the (white) vertex just visited has now a smaller + * minium than the local one, i.e. if target.min < src.min && !target.isBlack(). + */ + if((m < src.getFinishingTime()) && (target.getDiscoveryTime() < size + 1)) + src.setFinishingTime(m); + } + + public void finishVertex(Vertex v) { + /* If the local minimum hasn't changed, i.e. if no vertices with smaller minimums + * have been reached, this must be the root vertex of a SCC. + */ + if(v.getFinishingTime() == v.getDiscoveryTime()) { // Root of SCC? + Graph scc = new Graph(); // Gather nodes in subgraph + Vertex p; + + do { // Pop all nodes belonging to this SCC subgraph + p = stack.pop(); + scc.addVertex(p); // May have no edges, so put it first in there + p.setDiscoveryTime(size * 2); // Invalidate, i.e. mark vertex as black + } while(p != v); + + Vertex[] vertices = scc.getVertexArray(); + for(int j=0; j < vertices.length; j++) { + p = vertices[j]; + + Edge[] edges = graph.getEdgeArray(p); + for(int i=0; i < edges.length; i++) { // Build up subgraph + Edge e = edges[i]; + Vertex src = graph.getSource(e); + Vertex target = graph.getTarget(e); + + // Add only edges that are within the subgraph + if(scc.contains(src) && scc.contains(target)) + scc.addEdge(src, target, e); + } + } + + sccs.addElement(scc); // Add subgraph vectorto forest of subgraphs + } + } + + public void finishGraph(Graph g) { + graphs = new Graph[sccs.size()]; + sccs.copyInto(graphs); + } + + /** + * @return all strongly connected components found during traversal + */ + public final Graph[] getSCCs() { return graphs; } + + /** + * Visit graph with DFS and find all its strongly connected components + * which may be obtained with getSCCs(). + * + * @param g graph to traverse + * @param start where to start traversal + */ + public void visit(Graph g, Vertex start) { + new DFS(this).start(g, start); + } +} diff --git a/src/java/org/apache/commons/graph/Sequential.java b/src/java/org/apache/commons/graph/Sequential.java new file mode 100644 index 0000000..96f9d75 --- /dev/null +++ b/src/java/org/apache/commons/graph/Sequential.java @@ -0,0 +1,112 @@ +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 + * "Apache BCEL" 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", + * "Apache BCEL", 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 + * . + */ + +/** + * Visit graph in sequential order, i.e. in the order returned by Graph.getVertices(). + * + * @version $Id: Sequential.java,v 1.1 2001/11/12 16:05:20 jvanzyl Exp $ + * @author M. Dahm + */ +public final class Sequential extends TraversalOrder { + /** + * Depth first search algorithm. + * + * @param v visitor object to apply when discovering and finishing a vertex or edge + */ + public Sequential(Visitor v) { + super(v); + } + + /** + * Visit graph in sequential order + * + * @param g graph to traverse + * @param start vertex to start at (or null, starts at first vertex then) + */ + public void start(Graph g, Vertex start) { + int size = g.getNoVertices(); + Vertex[] vertices = g.getVertexArray(); + int index = 0; + + visitor.discoverGraph(g); + + /* Initially mark all vertices as WHITE + */ + for(int i=0; i < size; i++) { + vertices[i].setColor(WHITE); + if(vertices[i] == start) + index = i; + } + + for(int i=0; (i < size) && !stopped; i++) { + Vertex v = vertices[index++ % size]; + + visitor.discoverVertex(v); + v.setColor(GRAY); + + Edge[] edges = g.getEdgeArray(v); + for(int j=0; j < edges.length; j++) { + visitor.discoverEdge(edges[j]); + visitor.finishEdge(edges[j]); + } + + visitor.finishVertex(v); + v.setColor(BLACK); + } + + visitor.finishGraph(g); + } +} diff --git a/src/java/org/apache/commons/graph/TraversalOrder.java b/src/java/org/apache/commons/graph/TraversalOrder.java new file mode 100644 index 0000000..de4d45b --- /dev/null +++ b/src/java/org/apache/commons/graph/TraversalOrder.java @@ -0,0 +1,115 @@ +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 + * "Apache BCEL" 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", + * "Apache BCEL", 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 + * . + */ + +/** + * Class takes a visitor "piggy-backed" and applies it to all nodes + * and edges. The traversal order implemented by children of this + * class may be Depth-first or Breadth-first search, e.g.. + * + * This relates to the "Strategy" design pattern. + * + * @version $Id: TraversalOrder.java,v 1.1 2001/11/12 16:05:20 jvanzyl Exp $ + * @author M. Dahm + * @see DFS + * @see BFS + * @see Sequential +*/ +public abstract class TraversalOrder implements Constants { + protected Visitor visitor; + protected Graph graph; + protected boolean stopped; + protected boolean traverse_complete_graph; + + /** + * Depth first search algorithm. + * + * @param v visitor object to apply when discovering and finishing a vertex or edge + * @param traverse_all traverse the complete graph or stop after finishing all nodes reachable + * from the start + */ + public TraversalOrder(Visitor v, boolean traverse_all) { + visitor = v; + traverse_complete_graph = traverse_all; + } + + public TraversalOrder(Visitor v) { + this(v, true); + } + + /** + * Start traversal. + * + * @param g graph to traverse + * @param start vertex to start at (or null, starts at some vertex then) + * @param all_vertices visit all vertices or just those reache from start + */ + public abstract void start(Graph g, Vertex start); + + /** May be called to stop traversal, e.g. if a searched node has been found. + */ + public void stop() { + stopped = true; + } + + /** + * Depth first search algorithm starting at some vertex. + * + * @param g graph to traverse + */ + public void start(Graph g) { + start(g, null); + } +} diff --git a/src/java/org/apache/commons/graph/VCGVisualizer.java b/src/java/org/apache/commons/graph/VCGVisualizer.java new file mode 100644 index 0000000..dc5e13e --- /dev/null +++ b/src/java/org/apache/commons/graph/VCGVisualizer.java @@ -0,0 +1,138 @@ +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 + * "Apache BCEL" 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", + * "Apache BCEL", 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 + * . + */ +import java.io.OutputStream; + +/** + * Visualizes graphs into the VCG + * format. + * + * @version $Id: VCGVisualizer.java,v 1.1 2001/11/12 16:05:20 jvanzyl Exp $ + * @author M. Dahm + */ +public class VCGVisualizer extends GraphVisualizer { + private Graph graph; + + /** + * @param out stream to print output to + * @param verbose toggle verbosity of output + */ + public VCGVisualizer(OutputStream out, int verbose) { + super(out, verbose); + } + + public void discoverGraph(Graph g) { + String d = g.isDirected()? "1" : "0"; + + graph = g; + + println(0, "/* Created by VCGVisualizer */\n"); + println(0, "graph: {"); + println(1, "display_edge_labels: yes"); + println(1, "port_sharing: no"); + println(1, "manhattan_edges: yes"); + println(1, "straight_phase: yes"); + println(1, "priority_phase: yes"); + println(1, "node.color: white"); + println(1, "node.bordercolor: black"); + println(1, "node.textcolor: black"); + println(1, "node.shape: box"); + println(1, "node.textmode: left_justify"); + println(1, "edge.textcolor: black"); + println(1, "edge.color: black\n"); + } + + public void finishGraph(Graph g) { + println(0, "}"); + out.close(); + } + + public void discoverVertex(Vertex v) { + String label = convertString(v.toString(verbose)); + + println(1, "node: {"); + println(2, "title: \"" + v.getIdent() + "\""); + println(2, "label: \"" + label + "\""); + println(1, "}"); + } + + public void finishVertex(Vertex v) {} + + public void discoverEdge(Edge e) { + int src = graph.getSource(e).getIdent(); + int target = graph.getTarget(e).getIdent(); + String label = convertString(e.toString(verbose)); + + println(1, "edge: {"); + println(2, "sourcename: \"" + src + "\""); + println(2, "targetname: \"" + target + "\""); + if(!label.equals("")) + println(2, "label: \"" + label + "\""); + println(1, "}"); + } + + public void finishEdge(Edge e) {} + + /** + * Visualize graph g with this Visualizer. + * + * @param g graph to visualize + * @param start node to start at + */ + public void visualize(Graph g, Vertex start) { + new DFS(this).start(g, start); + } +} diff --git a/src/java/org/apache/commons/graph/VQueue.java b/src/java/org/apache/commons/graph/VQueue.java new file mode 100644 index 0000000..e00e692 --- /dev/null +++ b/src/java/org/apache/commons/graph/VQueue.java @@ -0,0 +1,77 @@ +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 + * "Apache BCEL" 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", + * "Apache BCEL", 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 + * . + */ + +/** + * Implements a simple first-in, first-out queue of vertices of fixed size. + * Can be extended, e.g., to implement a priority queue, so that the traversal + * order of the BFS algorithm may be influenced. + * + * @version $Id: VQueue.java,v 1.1 2001/11/12 16:05:20 jvanzyl Exp $ + * @author M. Dahm + */ +public class VQueue { + protected Vertex[] vertices; + protected int left, right; + + public VQueue(int s) { + vertices = new Vertex[s]; + } + + public void enqueue(Vertex v) { vertices[right++] = v; } + public Vertex dequeue() { return vertices[left++]; } + public Vertex head() { return vertices[left]; } + public boolean empty() { return right <= left; } +} diff --git a/src/java/org/apache/commons/graph/VStack.java b/src/java/org/apache/commons/graph/VStack.java new file mode 100644 index 0000000..eb563cc --- /dev/null +++ b/src/java/org/apache/commons/graph/VStack.java @@ -0,0 +1,75 @@ +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 + * "Apache BCEL" 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", + * "Apache BCEL", 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 + * . + */ + +/** + * Implements a simple first-in, last-out stack of vertices of fixed size. + * + * @version $Id: VStack.java,v 1.1 2001/11/12 16:05:20 jvanzyl Exp $ + * @author M. Dahm + */ +final class VStack { + private Vertex[] vertices; + private int top; + + VStack(int s) { + vertices = new Vertex[s]; + } + + final void push(Vertex v) { vertices[top++] = v; } + final Vertex pop() { return vertices[--top]; } + final Vertex top() { return vertices[top - 1]; } + final boolean empty() { return top <= 0; } +} diff --git a/src/java/org/apache/commons/graph/Vertex.java b/src/java/org/apache/commons/graph/Vertex.java new file mode 100644 index 0000000..bb22719 --- /dev/null +++ b/src/java/org/apache/commons/graph/Vertex.java @@ -0,0 +1,192 @@ +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 + * "Apache BCEL" 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", + * "Apache BCEL", 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 + * . + */ + +/** + * Describes a vertex of a graph. + * + * @version $Id: Vertex.java,v 1.1 2001/11/12 16:05:20 jvanzyl Exp $ + * @author M. Dahm + */ +public class Vertex implements Cloneable, Constants, java.io.Serializable { + private int ident; // unique number, i.e. identifier + private static int counter; // produce default numbers + + /** Useful variables for graph algorithms, calculated by DFS. + * @see DFS + */ + private int dtime, ftime; + private int color; // Color of vertex during traversal + private Vertex pred; // Predecessor of vertex + private int distance; // (Shortest) path to given root node (BFS) + + /** + * Create vertex with default identifier. + */ + public Vertex() { + ident = counter++; + } + + /** + * @return ident, i.e. identifier of this node + */ + public final int getIdent() { return ident; } + + /** + * @return number of created vertices + */ + public static final int getCounter() { return counter; } + + /** + * @return String representation. + */ + public String toString() { + return toString(PLAIN); + } + + /** + * @param verbose toggle output format + * @return String representation. + */ + public String toString(int verbose) { + switch(verbose) { + case VERBOSE: case TALKATIVE: + return "Vertex(" + ident + ", pred=" + + ((pred == null)? "null" : ("" + pred.ident)) + + ", discovery=" + dtime + ", finishing=" + ftime + + ", distance=" + distance + ")"; + + case V_VERBOSE: case V_TALKATIVE: + return "Vertex(" + ident + ")\npred=" + + ((pred == null)? "null" : ("" + pred.ident)) + + "\ndiscovery=" + dtime + "\nfinishing=" + ftime + + "\ndistance=" + distance; + + case PLAIN: case V_PLAIN: default: + return "Vertex(" + ident + ")"; + } + } + + /** + * Computed by DFS, BFS or other visitors + * @see Visitor + */ + public int getDiscoveryTime() { return dtime; } + + /** + * Computed by DFS, BFS or other visitors + * @see Visitor + */ + public int getFinishingTime() { return ftime; } + + /** + * Computed by DFS, BFS or other visitors + * @see Visitor + * @deprecated use Graph.getPredecessors + */ + public Vertex getPredecessor() { return pred; } + + /** + * Computed by DFS, BFS or other visitors + * @see Visitor + * @return distance from start vertex (No. edges in between) + * @see BFSVisitor + */ + public int getDistance() { return distance; } + + /** + * May be set only by classes of this package, Visitor in particular. + */ + public void setDistance(int d) { distance = d; } + public void setDiscoveryTime(int d) { dtime = d; } + public void setFinishingTime(int f) { ftime = f; } + public void setColor(int c) { color = c; } + public int getColor() { return color; } + public void setPredecessor(Vertex p) { pred = p; } + + /** + * Access for visitors + */ + public void accept(Visitor v) { v.discoverVertex(this); } + + /** + * @return deep copy + */ + public Vertex copy() { + try { + return (Vertex)clone(); + } + catch(CloneNotSupportedException e) {} + + return null; + } + + /** Check for equality. + */ + public boolean equals(Object o) { + if(!(o instanceof Vertex)) + return false; + + Vertex v = (Vertex)o; + return v.ident == ident; + } + +// private void readObject(java.io.ObjectInputStream in) +// throws java.io.IOException, ClassNotFoundException +// { +// counter++; // Adjust counter, since a new object has been created +// in.defaultReadObject(); +// } +} diff --git a/src/java/org/apache/commons/graph/Visitor.java b/src/java/org/apache/commons/graph/Visitor.java new file mode 100644 index 0000000..2027f33 --- /dev/null +++ b/src/java/org/apache/commons/graph/Visitor.java @@ -0,0 +1,74 @@ +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 + * "Apache BCEL" 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", + * "Apache BCEL", 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 + * . + */ + +/** + * Interface for visitor patterns. + * + * @version $Id: Visitor.java,v 1.1 2001/11/12 16:05:20 jvanzyl Exp $ + * @author M. Dahm + */ +public interface Visitor { + public void discoverGraph(Graph g); // may be also used as "visitGraph" + public void finishGraph(Graph g); + + public void discoverVertex(Vertex v); // same as above + public void finishVertex(Vertex v); + + public void discoverEdge(Edge e); // same as above + public void finishEdge(Edge e); + + public void visit(Graph g, Vertex v); // Start visiting graph g beginning at start +} diff --git a/src/java/org/apache/commons/graph/WeightedEdge.java b/src/java/org/apache/commons/graph/WeightedEdge.java new file mode 100644 index 0000000..076c4d2 --- /dev/null +++ b/src/java/org/apache/commons/graph/WeightedEdge.java @@ -0,0 +1,89 @@ +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 + * "Apache BCEL" 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", + * "Apache BCEL", 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 + * . + */ + +/** + * Describes an edge with a weight. + * + * @version $Id: WeightedEdge.java,v 1.1 2001/11/12 16:05:20 jvanzyl Exp $ + * @author M. Dahm + */ +public class WeightedEdge extends Edge { + private int weight; + + /** + * Create edge with a weight. + */ + public WeightedEdge(int w) { + weight = w; + } + + /** + * @param verbose toggle output format + * @return String representation. + */ + public String toString(int verbose) { + switch(verbose) { + case TALKATIVE: case V_TALKATIVE: + return "WeightedEdge(" + getIdent() + "\nweight=" + weight + ")"; + default: + return "" + weight; + } + } + + public void addToWeight(int w) { weight += w; } + public void setWeight(int weight) { this.weight = weight; } + public int getWeight() { return weight; } +}