/*
* Copyright (c) 2003, the JUNG Project and the Regents of the University
* of California
* All rights reserved.
*
* This software is open-source under the BSD license; see either
* "license.txt" or
* http://jung.sourceforge.net/license.txt for a description.
*/
/*
* Created on Apr 21, 2004
*/
package edu.uci.ics.jung.algorithms.transformation;
import org.apache.commons.collections15.Factory;
import edu.uci.ics.jung.graph.DirectedGraph;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.UndirectedGraph;
import edu.uci.ics.jung.graph.util.EdgeType;
import edu.uci.ics.jung.graph.util.Pair;
/**
* <p>
* Functions for transforming graphs into directed or undirected graphs.
* </p>
*
*
* @author Danyel Fisher
* @author Joshua O'Madadhain
*/
public class DirectionTransformer {
/**
* Transforms <code>graph</code> (which may be of any directionality) into
* an undirected graph. (This may be useful for visualization tasks).
* Specifically:
* <ul>
* <li/>Vertices are copied from <code>graph</code>.
* <li/>Directed edges are 'converted' into a single new undirected edge in
* the new graph.
* <li/>Each undirected edge (if any) in <code>graph</code> is 'recreated'
* with a new undirected edge in the new graph if <code>create_new</code> is
* true, or copied from <code>graph</code> otherwise.
* </ul>
*
* @param graph
* the graph to be transformed
* @param create_new
* specifies whether existing undirected edges are to be copied
* or recreated
* @param graph_factory
* used to create the new graph object
* @param edge_factory
* used to create new edges
* @return the transformed <code>Graph</code>
*/
public static <V, E> UndirectedGraph<V, E> toUndirected(Graph<V, E> graph,
Factory<UndirectedGraph<V, E>> graph_factory,
Factory<E> edge_factory, boolean create_new) {
UndirectedGraph<V, E> out = graph_factory.create();
for (V v : graph.getVertices()) {
out.addVertex(v);
}
for (E e : graph.getEdges()) {
Pair<V> endpoints = graph.getEndpoints(e);
V v1 = endpoints.getFirst();
V v2 = endpoints.getSecond();
E to_add;
if (graph.getEdgeType(e) == EdgeType.DIRECTED || create_new) {
to_add = edge_factory.create();
} else {
to_add = e;
}
out.addEdge(to_add, v1, v2, EdgeType.UNDIRECTED);
}
return out;
}
/**
* Transforms <code>graph</code> (which may be of any directionality) into a
* directed graph. Specifically:
* <ul>
* <li/>Vertices are copied from <code>graph</code>.
* <li/>Undirected edges are 'converted' into two new antiparallel directed
* edges in the new graph.
* <li/>Each directed edge (if any) in <code>graph</code> is 'recreated'
* with a new edge in the new graph if <code>create_new</code> is true, or
* copied from <code>graph</code> otherwise.
* </ul>
*
* @param graph
* the graph to be transformed
* @param create_new
* specifies whether existing directed edges are to be copied or
* recreated
* @param graph_factory
* used to create the new graph object
* @param edge_factory
* used to create new edges
* @return the transformed <code>Graph</code>
*/
public static <V, E> Graph<V, E> toDirected(Graph<V, E> graph,
Factory<DirectedGraph<V, E>> graph_factory, Factory<E> edge_factory,
boolean create_new) {
DirectedGraph<V, E> out = graph_factory.create();
for (V v : graph.getVertices()) {
out.addVertex(v);
}
for (E e : graph.getEdges()) {
Pair<V> endpoints = graph.getEndpoints(e);
if (graph.getEdgeType(e) == EdgeType.UNDIRECTED) {
V v1 = endpoints.getFirst();
V v2 = endpoints.getSecond();
out.addEdge(edge_factory.create(), v1, v2, EdgeType.DIRECTED);
out.addEdge(edge_factory.create(), v2, v1, EdgeType.DIRECTED);
} else // if the edge is directed, just add it
{
V source = graph.getSource(e);
V dest = graph.getDest(e);
E to_add = create_new ? edge_factory.create() : e;
out.addEdge(to_add, source, dest, EdgeType.DIRECTED);
}
}
return out;
}
}