View Javadoc
1   /*
2    * Copyright (c) 2003, The JUNG Authors 
3    *
4    * All rights reserved.
5    *
6    * This software is open-source under the BSD license; see either
7    * "license.txt" or
8    * https://github.com/jrtom/jung/blob/master/LICENSE for a description.
9    */
10  /*
11   * Created on Apr 21, 2004
12   */
13  package edu.uci.ics.jung.algorithms.transformation;
14  
15  import com.google.common.base.Supplier;
16  
17  import edu.uci.ics.jung.graph.DirectedGraph;
18  import edu.uci.ics.jung.graph.Graph;
19  import edu.uci.ics.jung.graph.UndirectedGraph;
20  import edu.uci.ics.jung.graph.util.EdgeType;
21  import edu.uci.ics.jung.graph.util.Pair;
22  
23  /**
24   * <p>Functions for transforming graphs into directed or undirected graphs.
25   * 
26   * 
27   * @author Danyel Fisher
28   * @author Joshua O'Madadhain
29   */
30  public class DirectionTransformer 
31  {
32  
33      /**
34       * Transforms <code>graph</code> (which may be of any directionality)
35       * into an undirected graph. (This may be useful for
36       * visualization tasks).
37       * Specifically:
38       * <ul>
39       * <li>Vertices are copied from <code>graph</code>.
40       * <li>Directed edges are 'converted' into a single new undirected edge in the new graph.
41       * <li>Each undirected edge (if any) in <code>graph</code> is 'recreated' with a new undirected edge in the new
42       * graph if <code>create_new</code> is true, or copied from <code>graph</code> otherwise.
43       * </ul>
44       * 
45       * @param graph     the graph to be transformed
46       * @param create_new specifies whether existing undirected edges are to be copied or recreated
47       * @param graph_factory used to create the new graph object
48       * @param edge_factory used to create new edges
49       * @param <V> the vertex type
50       * @param <E> the edge type
51       * @return          the transformed <code>Graph</code>
52       */
53      public static <V,E> UndirectedGraph<V,E> toUndirected(Graph<V,E> graph, 
54      		Supplier<UndirectedGraph<V,E>> graph_factory,
55              Supplier<E> edge_factory, boolean create_new)
56      {
57          UndirectedGraph<V,E> out = graph_factory.get();
58          
59          for (V v : graph.getVertices())
60              out.addVertex(v);
61          
62          for (E e : graph.getEdges())
63          {
64              Pair<V> endpoints = graph.getEndpoints(e);
65              V v1 = endpoints.getFirst();
66              V v2 = endpoints.getSecond();
67              E to_add;
68              if (graph.getEdgeType(e) == EdgeType.DIRECTED || create_new)
69                  to_add = edge_factory.get();
70              else
71                  to_add = e;
72              out.addEdge(to_add, v1, v2, EdgeType.UNDIRECTED);
73          }
74          return out;
75      }
76      
77      /**
78       * Transforms <code>graph</code> (which may be of any directionality)
79       * into a directed graph.  
80       * Specifically:
81       * <ul>
82       * <li>Vertices are copied from <code>graph</code>.
83       * <li>Undirected edges are 'converted' into two new antiparallel directed edges in the new graph.
84       * <li>Each directed edge (if any) in <code>graph</code> is 'recreated' with a new edge in the new
85       * graph if <code>create_new</code> is true, or copied from <code>graph</code> otherwise.
86       * </ul>
87       * 
88       * @param graph     the graph to be transformed
89       * @param create_new specifies whether existing directed edges are to be copied or recreated
90       * @param graph_factory used to create the new graph object
91       * @param edge_factory used to create new edges
92       * @param <V> the vertex type
93       * @param <E> the edge type
94       * @return          the transformed <code>Graph</code>
95       */
96      public static <V,E> Graph<V,E> toDirected(Graph<V,E> graph, Supplier<DirectedGraph<V,E>> graph_factory,
97              Supplier<E> edge_factory, boolean create_new)
98      {
99          DirectedGraph<V,E> out = graph_factory.get();
100         
101         for (V v : graph.getVertices())
102             out.addVertex(v);
103         
104         for (E e : graph.getEdges())
105         {
106             Pair<V> endpoints = graph.getEndpoints(e);
107             if (graph.getEdgeType(e) == EdgeType.UNDIRECTED)
108             {
109                 V v1 = endpoints.getFirst();
110                 V v2 = endpoints.getSecond();
111                 out.addEdge(edge_factory.get(), v1, v2, EdgeType.DIRECTED);
112                 out.addEdge(edge_factory.get(), v2, v1, EdgeType.DIRECTED);
113             }
114             else // if the edge is directed, just add it 
115             {
116                 V source = graph.getSource(e);
117                 V dest = graph.getDest(e);
118                 E to_add = create_new ? edge_factory.get() : e;
119                 out.addEdge(to_add, source, dest, EdgeType.DIRECTED);
120             }
121                 
122         }
123         return out;
124     }
125 }