org.jgrapht.Graphs Maven / Gradle / Ivy
/* ==========================================
* JGraphT : a free Java graph-theory library
* ==========================================
*
* Project Info: http://jgrapht.sourceforge.net/
* Project Creator: Barak Naveh (http://sourceforge.net/users/barak_naveh)
*
* (C) Copyright 2003-2008, by Barak Naveh and Contributors.
*
* This program and the accompanying materials are dual-licensed under
* either
*
* (a) the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation, or (at your option) any
* later version.
*
* or (per the licensee's choosing)
*
* (b) the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation.
*/
/* ----------------
* Graphs.java
* ----------------
* (C) Copyright 2003-2008, by Barak Naveh and Contributors.
*
* Original Author: Barak Naveh
* Contributor(s): Christian Hammer
* Mikael Hansen
*
* $Id$
*
* Changes
* -------
* 10-Jul-2003 : Initial revision (BN);
* 06-Nov-2003 : Change edge sharing semantics (JVS);
* 11-Mar-2004 : Made generic (CH);
* 07-May-2006 : Changed from List to Set (JVS);
* 28-May-2006 : Moved connectivity info from edge to graph (JVS);
*
*/
package org.jgrapht;
import java.util.*;
import org.jgrapht.graph.*;
/**
* A collection of utilities to assist with graph manipulation.
*
* @author Barak Naveh
* @since Jul 31, 2003
*/
public abstract class Graphs
{
/**
* Creates a new edge and adds it to the specified graph similarly to the
* {@link Graph#addEdge(Object, Object)} method.
*
* @param g the graph for which the edge to be added.
* @param sourceVertex source vertex of the edge.
* @param targetVertex target vertex of the edge.
* @param weight weight of the edge.
*
* @return The newly created edge if added to the graph, otherwise
* null
.
*
* @see Graph#addEdge(Object, Object)
*/
public static E addEdge(
Graph g,
V sourceVertex,
V targetVertex,
double weight)
{
EdgeFactory ef = g.getEdgeFactory();
E e = ef.createEdge(sourceVertex, targetVertex);
// we first create the edge and set the weight to make sure that
// listeners will see the correct weight upon addEdge.
assert (g instanceof WeightedGraph, ?>) : g.getClass();
((WeightedGraph) g).setEdgeWeight(e, weight);
return g.addEdge(sourceVertex, targetVertex, e) ? e : null;
}
/**
* Adds the specified source and target vertices to the graph, if not
* already included, and creates a new edge and adds it to the specified
* graph similarly to the {@link Graph#addEdge(Object, Object)} method.
*
* @param g the graph for which the specified edge to be added.
* @param sourceVertex source vertex of the edge.
* @param targetVertex target vertex of the edge.
*
* @return The newly created edge if added to the graph, otherwise
* null
.
*/
public static E addEdgeWithVertices(
Graph g,
V sourceVertex,
V targetVertex)
{
g.addVertex(sourceVertex);
g.addVertex(targetVertex);
return g.addEdge(sourceVertex, targetVertex);
}
/**
* Adds the specified edge to the graph, including its vertices if not
* already included.
*
* @param targetGraph the graph for which the specified edge to be added.
* @param sourceGraph the graph in which the specified edge is already
* present
* @param edge edge to add
*
* @return true if the target graph did not already contain the
* specified edge.
*/
public static boolean addEdgeWithVertices(
Graph targetGraph,
Graph sourceGraph,
E edge)
{
V sourceVertex = sourceGraph.getEdgeSource(edge);
V targetVertex = sourceGraph.getEdgeTarget(edge);
targetGraph.addVertex(sourceVertex);
targetGraph.addVertex(targetVertex);
return targetGraph.addEdge(sourceVertex, targetVertex, edge);
}
/**
* Adds the specified source and target vertices to the graph, if not
* already included, and creates a new weighted edge and adds it to the
* specified graph similarly to the {@link Graph#addEdge(Object, Object)}
* method.
*
* @param g the graph for which the specified edge to be added.
* @param sourceVertex source vertex of the edge.
* @param targetVertex target vertex of the edge.
* @param weight weight of the edge.
*
* @return The newly created edge if added to the graph, otherwise
* null
.
*/
public static E addEdgeWithVertices(
Graph g,
V sourceVertex,
V targetVertex,
double weight)
{
g.addVertex(sourceVertex);
g.addVertex(targetVertex);
return addEdge(g, sourceVertex, targetVertex, weight);
}
/**
* Adds all the vertices and all the edges of the specified source graph to
* the specified destination graph. First all vertices of the source graph
* are added to the destination graph. Then every edge of the source graph
* is added to the destination graph. This method returns true
* if the destination graph has been modified as a result of this operation,
* otherwise it returns false
.
*
* The behavior of this operation is undefined if any of the specified
* graphs is modified while operation is in progress.
*
* @param destination the graph to which vertices and edges are added.
* @param source the graph used as source for vertices and edges to add.
*
* @return true
if and only if the destination graph has been
* changed as a result of this operation.
*/
public static boolean addGraph(
Graph super V, ? super E> destination,
Graph source)
{
boolean modified = addAllVertices(destination, source.vertexSet());
modified |= addAllEdges(destination, source, source.edgeSet());
return modified;
}
/**
* Adds all the vertices and all the edges of the specified source digraph
* to the specified destination digraph, reversing all of the edges. If you
* want to do this as a linked view of the source graph (rather than by
* copying to a destination graph), use {@link EdgeReversedGraph} instead.
*
* The behavior of this operation is undefined if any of the specified
* graphs is modified while operation is in progress.
*
* @param destination the graph to which vertices and edges are added.
* @param source the graph used as source for vertices and edges to add.
*
* @see EdgeReversedGraph
*/
public static void addGraphReversed(
DirectedGraph super V, ? super E> destination,
DirectedGraph source)
{
addAllVertices(destination, source.vertexSet());
for (E edge : source.edgeSet()) {
destination.addEdge(
source.getEdgeTarget(edge),
source.getEdgeSource(edge));
}
}
/**
* Adds a subset of the edges of the specified source graph to the specified
* destination graph. The behavior of this operation is undefined if either
* of the graphs is modified while the operation is in progress. {@link
* #addEdgeWithVertices} is used for the transfer, so source vertexes will
* be added automatically to the target graph.
*
* @param destination the graph to which edges are to be added
* @param source the graph used as a source for edges to add
* @param edges the edges to be added
*
* @return true if this graph changed as a result of the call
*/
public static boolean addAllEdges(
Graph super V, ? super E> destination,
Graph source,
Collection extends E> edges)
{
boolean modified = false;
for (E e : edges) {
V s = source.getEdgeSource(e);
V t = source.getEdgeTarget(e);
destination.addVertex(s);
destination.addVertex(t);
modified |= destination.addEdge(s, t, e);
}
return modified;
}
/**
* Adds all of the specified vertices to the destination graph. The behavior
* of this operation is undefined if the specified vertex collection is
* modified while the operation is in progress. This method will invoke the
* {@link Graph#addVertex(Object)} method.
*
* @param destination the graph to which edges are to be added
* @param vertices the vertices to be added to the graph.
*
* @return true if graph changed as a result of the call
*
* @throws NullPointerException if the specified vertices contains one or
* more null vertices, or if the specified vertex collection is
* null.
*
* @see Graph#addVertex(Object)
*/
public static boolean addAllVertices(
Graph super V, ? super E> destination,
Collection extends V> vertices)
{
boolean modified = false;
for (V v : vertices) {
modified |= destination.addVertex(v);
}
return modified;
}
/**
* Returns a list of vertices that are the neighbors of a specified vertex.
* If the graph is a multigraph vertices may appear more than once in the
* returned list.
*
* @param g the graph to look for neighbors in.
* @param vertex the vertex to get the neighbors of.
*
* @return a list of the vertices that are the neighbors of the specified
* vertex.
*/
public static List neighborListOf(Graph g,
V vertex)
{
List neighbors = new ArrayList();
for (E e : g.edgesOf(vertex)) {
neighbors.add(getOppositeVertex(g, e, vertex));
}
return neighbors;
}
/**
* Returns a list of vertices that are the direct predecessors of a
* specified vertex. If the graph is a multigraph, vertices may appear more
* than once in the returned list.
*
* @param g the graph to look for predecessors in.
* @param vertex the vertex to get the predecessors of.
*
* @return a list of the vertices that are the direct predecessors of the
* specified vertex.
*/
public static List predecessorListOf(
DirectedGraph g,
V vertex)
{
List predecessors = new ArrayList();
Set extends E> edges = g.incomingEdgesOf(vertex);
for (E e : edges) {
predecessors.add(getOppositeVertex(g, e, vertex));
}
return predecessors;
}
/**
* Returns a list of vertices that are the direct successors of a specified
* vertex. If the graph is a multigraph vertices may appear more than once
* in the returned list.
*
* @param g the graph to look for successors in.
* @param vertex the vertex to get the successors of.
*
* @return a list of the vertices that are the direct successors of the
* specified vertex.
*/
public static List successorListOf(
DirectedGraph g,
V vertex)
{
List successors = new ArrayList();
Set extends E> edges = g.outgoingEdgesOf(vertex);
for (E e : edges) {
successors.add(getOppositeVertex(g, e, vertex));
}
return successors;
}
/**
* Returns an undirected view of the specified graph. If the specified graph
* is directed, returns an undirected view of it. If the specified graph is
* already undirected, just returns it.
*
* @param g the graph for which an undirected view is to be returned.
*
* @return an undirected view of the specified graph, if it is directed, or
* or the specified graph itself if it is already undirected.
*
* @throws IllegalArgumentException if the graph is neither DirectedGraph
* nor UndirectedGraph.
*
* @see AsUndirectedGraph
*/
public static UndirectedGraph undirectedGraph(Graph g)
{
if (g instanceof DirectedGraph, ?>) {
return new AsUndirectedGraph((DirectedGraph) g);
} else if (g instanceof UndirectedGraph, ?>) {
return (UndirectedGraph) g;
} else {
throw new IllegalArgumentException(
"Graph must be either DirectedGraph or UndirectedGraph");
}
}
/**
* Tests whether an edge is incident to a vertex.
*
* @param g graph containing e and v
* @param e edge in g
* @param v vertex in g
*
* @return true iff e is incident on v
*/
public static boolean testIncidence(Graph g, E e, V v)
{
return (g.getEdgeSource(e).equals(v))
|| (g.getEdgeTarget(e).equals(v));
}
/**
* Gets the vertex opposite another vertex across an edge.
*
* @param g graph containing e and v
* @param e edge in g
* @param v vertex in g
*
* @return vertex opposite to v across e
*/
public static V getOppositeVertex(Graph g, E e, V v)
{
V source = g.getEdgeSource(e);
V target = g.getEdgeTarget(e);
if (v.equals(source)) {
return target;
} else if (v.equals(target)) {
return source;
} else {
throw new IllegalArgumentException(
"no such vertex: " + v.toString());
}
}
/**
* Gets the list of vertices visited by a path.
*
* @param path path of interest
*
* @return corresponding vertex list
*/
public static List getPathVertexList(GraphPath path)
{
Graph g = path.getGraph();
List list = new ArrayList();
V v = path.getStartVertex();
list.add(v);
for (E e : path.getEdgeList()) {
v = getOppositeVertex(g, e, v);
list.add(v);
}
return list;
}
}
// End Graphs.java