/* * 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; } }