source: src/main/java/weka/clusterers/forMetisMQI/MQI.java @ 11

Last change on this file since 11 was 11, checked in by gnappo, 14 years ago

Un po' di refactoring e implementazione dell'algoritmo di raffinamento.

File size: 5.4 KB
Line 
1package weka.clusterers.forMetisMQI;
2
3import java.awt.Dimension;
4import java.util.HashMap;
5import java.util.Iterator;
6import java.util.Map;
7import java.util.Set;
8
9import javax.swing.JFrame;
10
11import org.apache.commons.collections15.Factory;
12import org.apache.commons.collections15.Transformer;
13
14import weka.clusterers.forMetisMQI.graph.Bisection;
15import weka.clusterers.forMetisMQI.graph.Edge;
16import weka.clusterers.forMetisMQI.graph.Node;
17import weka.clusterers.forMetisMQI.graph.Subgraph;
18import weka.clusterers.forMetisMQI.graph.UndirectedGraph;
19import edu.uci.ics.jung.algorithms.flows.EdmondsKarpMaxFlow;
20import edu.uci.ics.jung.algorithms.layout.KKLayout;
21import edu.uci.ics.jung.algorithms.layout.Layout;
22import edu.uci.ics.jung.graph.DirectedGraph;
23import edu.uci.ics.jung.graph.DirectedSparseGraph;
24import edu.uci.ics.jung.graph.Graph;
25import edu.uci.ics.jung.visualization.BasicVisualizationServer;
26import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
27
28public class MQI {
29       
30        static int i = -1;
31       
32        public static void viewGraph(Graph<Node, Edge> g){
33                Layout<Node, Edge> layout = new KKLayout<Node, Edge>(g);
34                layout.setSize(new Dimension(800,600)); // sets the initial size of the space
35                // The BasicVisualizationServer<V,E> is parameterized by the edge types
36                BasicVisualizationServer<Node,Edge> vv =
37                new BasicVisualizationServer<Node,Edge>(layout);
38                vv.setPreferredSize(new Dimension(800,600)); //Sets the viewing area size
39                vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller<Node>());
40                vv.getRenderContext().setEdgeLabelTransformer(new ToStringLabeller<Edge>());
41
42                JFrame frame = new JFrame("Simple Graph View");
43                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
44                frame.getContentPane().add(vv);
45                frame.pack();
46                frame.setVisible(true);
47        }
48
49        /**
50         * Given a bisection, returns the cardinality of the larger subgraph.
51         * @param b
52         * @return
53         */
54        static private int getMaxCardinality(Bisection b) {
55                Subgraph A = null;
56                if(b.getSubgraph().getVertexCount() > b.getComplement().getVertexCount()) {
57                        A = b.getSubgraph();
58                }
59                else {
60                        A = b.getComplement();
61                }
62                return A.getVertexCount();
63        }
64       
65        static private DirectedGraph<Node,       Edge> prepareDirectedGraph(Bisection partition, Node source, Node sink) {
66                Subgraph A = null;
67                Subgraph B = null;
68                if(partition.getSubgraph().getVertexCount() > partition.getComplement().getVertexCount()) {
69                        A = partition.getSubgraph();
70                        B = partition.getComplement();
71                }
72                else {
73                        A = partition.getComplement();
74                        B = partition.getSubgraph();
75                }
76                int a = A.getVertexCount();
77                int c = partition.edgeCut() / 2;
78               
79               
80                DirectedGraph<Node,Edge> g = new DirectedSparseGraph<Node, Edge>();
81                Iterator<Node> nodes =  A.iterator();
82                while(nodes.hasNext()) {
83                        Node u = nodes.next();
84                        g.addVertex(u);
85                }
86               
87                nodes =  A.iterator();
88                int id = 0;
89                while(nodes.hasNext()) {
90                        Node u = nodes.next();
91                        Iterator<Node> neighbors = A.getNeighbors(u).iterator();
92                        while(neighbors.hasNext()) {
93                                Node v = neighbors.next();
94                                g.addEdge(new Edge(Integer.toString(id),A.getWeight(u, v),a),u,v);
95                                id++;
96                        }
97                }
98               
99                g.addVertex(source);
100                g.addVertex(sink);
101               
102               
103                nodes =  B.iterator();
104                while(nodes.hasNext()) {
105                        Node u = nodes.next();
106                        Iterator<Node> neighbors = B.getGraph().getNeighbors(u).iterator();
107                        while(neighbors.hasNext()) {
108                                Node v = neighbors.next();
109                                if(A.contains(v)) {
110                                        g.addEdge(new Edge(Integer.toString(id),1,a),source,v);
111                                        id++;
112                                }
113                        }
114                }
115               
116                nodes =  A.iterator();
117                while(nodes.hasNext()) {
118                        Node u = nodes.next();
119                        g.addEdge(new Edge(Integer.toString(id),1,c),u,sink);
120                        id++;
121                }
122                return g;
123        }
124       
125        static public Bisection mqi(Bisection partition) {
126                boolean finished = false;
127                Bisection bisection = partition;
128                int maxFlowThreshold = Integer.MAX_VALUE;
129                while (!finished) {
130                        UndirectedGraph startingGraph = partition.getGraph();
131                        Node source = new Node("S");
132                        Node sink = new Node("T");
133                        DirectedGraph<Node, Edge> g = prepareDirectedGraph(bisection, source, sink);
134                        Transformer<Edge, Number> capTransformer = new Transformer<Edge, Number>() {
135                                public Double transform(Edge e) {
136                                        return (double) e.getCapacity();
137                                }
138                        };
139                        Map<Edge, Number> edgeFlowMap = new HashMap<Edge, Number>();
140                        // This Factory produces new edges for use by the algorithm
141                        i=-1;
142                        Factory<Edge> edgeFactory = new Factory<Edge>() {
143                                public Edge create() {
144                                        i++;
145                                        return new Edge(Integer.toString(i), 1, 1);
146                                }
147                        };
148                        EdmondsKarpMaxFlow<Node, Edge> alg = new EdmondsKarpMaxFlow<Node, Edge>(
149                                        g, source, sink, capTransformer, edgeFlowMap, edgeFactory);
150                       
151                        maxFlowThreshold = getMaxCardinality(bisection) * bisection.edgeCut() / 2; 
152                        alg.evaluate();
153                        if(alg.getMaxFlow() < maxFlowThreshold) {
154                                Set<Node> sinkPartition = alg.getNodesInSinkPartition();
155                                Set<Node> sourcePartition = alg.getNodesInSourcePartition();
156                                bisection = prepareBisection(startingGraph, sourcePartition, sinkPartition);
157                        } else
158                                finished = true;
159                }
160                return bisection;
161        }
162       
163        private static Bisection prepareBisection(UndirectedGraph g, Set<Node> sourcePartition, Set<Node> sinkPartition) {
164                Bisection b = null;
165                Subgraph sourceSubgraph = new Subgraph(g, sourcePartition);
166                Subgraph sinkSubgraph = new Subgraph(g, sinkPartition);
167                Subgraph subgraph = null;
168                if(sourceSubgraph.getVertexCount() > sinkSubgraph.getVertexCount())
169                        subgraph =sourceSubgraph;
170                else
171                        subgraph = sinkSubgraph;
172                b = new Bisection(subgraph);
173                return b;
174        }
175       
176}
Note: See TracBrowser for help on using the repository browser.