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  package edu.uci.ics.jung.algorithms.transformation;
11  
12  import java.util.Collection;
13  import java.util.HashMap;
14  import java.util.HashSet;
15  import java.util.Map;
16  import java.util.Set;
17  
18  import com.google.common.base.Function;
19  import com.google.common.base.Functions;
20  import com.google.common.base.Supplier;
21  
22  import edu.uci.ics.jung.algorithms.blockmodel.VertexPartition;
23  import edu.uci.ics.jung.graph.Graph;
24  
25  /**
26   * This class transforms a graph with a known vertex partitioning into a graph whose 
27   * vertices correspond to the input graph's partitions.  Two vertices in the output graph
28   * are connected if and only if there exists at least one edge between vertices in the 
29   * corresponding partitions of the input graph.  If the output graph permits parallel edges,
30   * there will be an edge connecting two vertices in the new graph for each such 
31   * edge connecting constituent vertices in the input graph.
32   * 
33   * <p>Concept based on Danyel Fisher's <code>GraphCollapser</code> in JUNG 1.x.
34   * 
35   */
36  public class VertexPartitionCollapser<V,E,CV,CE> 
37  {
38      protected Supplier<Graph<CV,CE>> graph_factory;
39      protected Supplier<CV> vertex_factory;
40      protected Supplier<CE> edge_factory;
41      protected Map<Set<V>, CV> set_collapsedv;
42      
43      /**
44       * Creates an instance with the specified graph and element factories.
45       * @param vertex_factory used to construct the vertices of the new graph
46       * @param edge_factory used to construct the edges of the new graph
47       * @param graph_factory used to construct the new graph
48       */
49      public VertexPartitionCollapser(Supplier<Graph<CV,CE>> graph_factory, 
50              Supplier<CV> vertex_factory, Supplier<CE> edge_factory)
51      {
52          this.graph_factory = graph_factory;
53          this.vertex_factory = vertex_factory;
54          this.edge_factory = edge_factory;
55          this.set_collapsedv = new HashMap<Set<V>, CV>();
56      }
57  
58      /**
59       * Creates a new graph whose vertices correspond to the partitions of the supplied graph.
60       * @param partitioning a vertex partition of a graph
61       * @return a new graph whose vertices correspond to the partitions of the supplied graph
62       */
63      public Graph<CV,CE> collapseVertexPartitions(VertexPartition<V,E> partitioning)
64      {
65          Graph<V,E> original = partitioning.getGraph();
66          Graph<CV, CE> collapsed = graph_factory.get();
67          
68          // create vertices in new graph corresponding to equivalence sets in the original graph
69          for (Set<V> set : partitioning.getVertexPartitions())
70          {
71              CV cv = vertex_factory.get();
72              collapsed.addVertex(vertex_factory.get());
73              set_collapsedv.put(set, cv);
74          }
75  
76          // create edges in new graph corresponding to edges in original graph
77          for (E e : original.getEdges())
78          {
79              Collection<V> incident = original.getIncidentVertices(e);
80              Collection<CV> collapsed_vertices = new HashSet<CV>();
81              Map<V, Set<V>> vertex_partitions = partitioning.getVertexToPartitionMap();
82              // collect the collapsed vertices corresponding to the original incident vertices
83              for (V v : incident)
84                  collapsed_vertices.add(set_collapsedv.get(vertex_partitions.get(v))); 
85              // if there's only one collapsed vertex, continue (no edges to create)
86              if (collapsed_vertices.size() > 1)
87              {
88                  CE ce = edge_factory.get();
89                  collapsed.addEdge(ce, collapsed_vertices);
90              }
91          }
92          return collapsed;
93      }
94      
95      /**
96       * @return a Function from vertex sets in the original graph to collapsed vertices
97       * in the transformed graph.
98       */
99      public Function<Set<V>, CV> getSetToCollapsedVertexTransformer()
100     {
101         return Functions.forMap(set_collapsedv);
102     }
103 }