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 }