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

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

Visualizzazione dei cluster. (da spostare)

File size: 9.0 KB
Line 
1package weka.clusterers.forMetisMQI;
2
3import java.awt.Color;
4import java.awt.Dimension;
5import java.awt.Paint;
6import java.util.Collection;
7import java.util.HashMap;
8import java.util.HashSet;
9import java.util.Iterator;
10import java.util.Map;
11import java.util.Set;
12import java.util.Stack;
13
14import javax.swing.JFrame;
15
16import org.apache.commons.collections15.Factory;
17import org.apache.commons.collections15.Transformer;
18
19import weka.clusterers.forMetisMQI.graph.Bisection;
20import weka.clusterers.forMetisMQI.graph.Edge;
21import weka.clusterers.forMetisMQI.graph.Node;
22import weka.clusterers.forMetisMQI.graph.Subgraph;
23import weka.clusterers.forMetisMQI.graph.UndirectedGraph;
24import edu.uci.ics.jung.algorithms.flows.EdmondsKarpMaxFlow;
25import edu.uci.ics.jung.algorithms.layout.KKLayout;
26import edu.uci.ics.jung.algorithms.layout.Layout;
27import edu.uci.ics.jung.graph.DirectedGraph;
28import edu.uci.ics.jung.graph.DirectedSparseGraph;
29import edu.uci.ics.jung.graph.Graph;
30import edu.uci.ics.jung.visualization.BasicVisualizationServer;
31import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
32
33public class MQI {
34       
35        static int i = -1;
36       
37        public static void viewClusters(Graph<Node, Edge> g, Set<Set<Node>> clusters) {
38                Layout<Node, Edge> layout = new KKLayout<Node, Edge>(g);
39                layout.setSize(new Dimension(800, 600)); // sets the initial size of the space
40                // The BasicVisualizationServer<V,E> is parameterized by the edge types
41                BasicVisualizationServer<Node, Edge> vv = new BasicVisualizationServer<Node, Edge>(
42                                layout);
43
44                class VertexPaintTransformer implements Transformer<Node, Paint> {
45                        Set<Set<Node>> clusters = null;
46                        Map<Set<Node>, Color> clustersColor = null;
47
48                        public Set<Node> getCluster(Node node) {
49                                Iterator<Set<Node>> clusterIterator = clusters.iterator();
50                                while (clusterIterator.hasNext()) {
51                                        Set<Node> cluster = clusterIterator.next();
52                                        if (cluster.contains(node))
53                                                return cluster;
54                                }
55                                return null;
56                        }
57
58                        public VertexPaintTransformer(Set<Set<Node>> clusters) {
59                                this.clusters = clusters;
60                                clustersColor = new HashMap<Set<Node>, Color>(clusters.size());
61                                Iterator<Set<Node>> clusterIterator = clusters.iterator();
62                                while (clusterIterator.hasNext()) {
63                                        Set<Node> cluster = clusterIterator.next();
64                                        clustersColor.put(cluster, new Color(Random.instance()
65                                                        .nextInt(256), Random.instance().nextInt(256),
66                                                        Random.instance().nextInt(256)));
67                                }
68                        }
69
70                        public Paint transform(Node i) {
71                                Set<Node> cluster = getCluster(i);
72                                if (cluster == null)
73                                        return Color.RED;
74                                else
75                                        return clustersColor.get(getCluster(i));
76                        }
77                }
78
79                Transformer<Node, Paint> vertexPaint = new VertexPaintTransformer(
80                                clusters);
81                vv.setPreferredSize(new Dimension(800, 600)); // Sets the viewing area
82                                                                                                                // size
83                vv.getRenderContext().setVertexLabelTransformer(
84                                new ToStringLabeller<Node>());
85                vv.getRenderContext().setEdgeLabelTransformer(
86                                new ToStringLabeller<Edge>());
87                vv.getRenderContext().setVertexFillPaintTransformer(vertexPaint);
88                JFrame frame = new JFrame("Graph View");
89                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
90                frame.getContentPane().add(vv);
91                frame.pack();
92                frame.setVisible(true);
93        }
94       
95        public static void viewGraph(Graph<Node, Edge> g){
96                Layout<Node, Edge> layout = new KKLayout<Node, Edge>(g);
97                layout.setSize(new Dimension(800,600)); // sets the initial size of the space
98                // The BasicVisualizationServer<V,E> is parameterized by the edge types
99                BasicVisualizationServer<Node,Edge> vv =
100                new BasicVisualizationServer<Node,Edge>(layout);
101                vv.setPreferredSize(new Dimension(800,600)); //Sets the viewing area size
102                vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller<Node>());
103                vv.getRenderContext().setEdgeLabelTransformer(new ToStringLabeller<Edge>());
104
105                JFrame frame = new JFrame("Simple Graph View");
106                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
107                frame.getContentPane().add(vv);
108                frame.pack();
109                frame.setVisible(true);
110        }
111
112        static private Set<Node> BFSReversed(Node sink, DirectedGraph<Node, Edge> g, Map<Edge, Number> edgeFlowMap) {
113                Set<Node> result = new HashSet<Node>();
114                Set<Node> visitedNodes = new HashSet<Node>();
115                Stack<Node> nodesToVisit = new Stack<Node>();
116                result.add(sink);
117                nodesToVisit.push(sink);
118                while(!nodesToVisit.empty()) {
119                        Node currentNode = nodesToVisit.pop();
120                        visitedNodes.add(currentNode);
121                        Collection<Edge> inEdges = g.getInEdges(currentNode);
122                        Iterator<Edge> inEdgesIterator = inEdges.iterator();
123                        while(inEdgesIterator.hasNext()) {
124                                Edge edge = inEdgesIterator.next();
125                                Node src = g.getSource(edge);
126                                Edge reverseEdge = g.findEdge(src, currentNode);
127                                if((reverseEdge != null) && ((Integer)edgeFlowMap.get(reverseEdge) < reverseEdge.getCapacity())) {
128                                        if(!nodesToVisit.contains(src) && !visitedNodes.contains(src)) {
129                                                nodesToVisit.push(src);
130                                        }
131                                        result.add(src);
132                                }
133                        }
134                }
135                return result;
136        }
137       
138        static private DirectedGraph<Node,       Edge> prepareDirectedGraph(Bisection partition, Node source, Node sink) {
139                Subgraph A = null;
140                Subgraph B = null;
141                if(partition.getSubgraph().getVertexCount() < partition.getComplement().getVertexCount()) {
142                        A = partition.getSubgraph();
143                        B = partition.getComplement();
144                }
145                else {
146                        A = partition.getComplement();
147                        B = partition.getSubgraph();
148                }
149                int a = A.getVertexCount();
150                int c = partition.edgeCut() / 2;
151               
152               
153                DirectedGraph<Node,Edge> g = new DirectedSparseGraph<Node, Edge>();
154                Iterator<Node> nodes =  A.iterator();
155                while(nodes.hasNext()) {
156                        Node u = nodes.next();
157                        g.addVertex(u);
158                }
159               
160                nodes =  A.iterator();
161                int id = 0;
162                while(nodes.hasNext()) {
163                        Node u = nodes.next();
164                        Iterator<Node> neighbors = A.getNeighbors(u).iterator();
165                        while(neighbors.hasNext()) {
166                                Node v = neighbors.next();
167                                g.addEdge(new Edge(Integer.toString(id),A.getWeight(u, v),a),u,v);
168                                id++;
169                        }
170                }
171               
172                g.addVertex(source);
173                g.addVertex(sink);
174               
175               
176                nodes =  B.iterator();
177                while(nodes.hasNext()) {
178                        Node u = nodes.next();
179                        Iterator<Node> neighbors = B.getGraph().getNeighbors(u).iterator();
180                        while(neighbors.hasNext()) {
181                                Node v = neighbors.next();
182                                if(A.contains(v)) {
183                                        g.addEdge(new Edge(Integer.toString(id),1,a),source,v);
184                                        id++;
185                                }
186                        }
187                }
188               
189                nodes =  A.iterator();
190                while(nodes.hasNext()) {
191                        Node u = nodes.next();
192                        g.addEdge(new Edge(Integer.toString(id),1,c),u,sink);
193                        id++;
194                }
195                return g;
196        }
197       
198        /**
199         * Given a partion of a graph, execute the Max-Flow Quotient-cut Improvement algorithm,
200         * to find an improved cut and then returns the cluster which yields the best quotient cut.
201         * @param partition
202         * @return
203         */
204        static public Set<Node> mqi(Bisection partition) {
205                System.out.println("INITIAL BISECTION: " + partition.toString());
206                boolean finished = false;
207                Bisection bisection = partition;
208                Set<Node> cluster = new HashSet<Node>(partition.getSubgraph().createInducedSubgraph().getVertices());
209                int maxFlowThreshold = Integer.MAX_VALUE;
210                while (!finished) {
211                        Node source = new Node("S");
212                        Node sink = new Node("T");
213                        DirectedGraph<Node, Edge> directedGraph = prepareDirectedGraph(bisection, source, sink);
214                        Transformer<Edge, Number> capTransformer = new Transformer<Edge, Number>() {
215                                public Double transform(Edge e) {
216                                        return (double) e.getCapacity();
217                                }
218                        };
219                        Map<Edge, Number> edgeFlowMap = new HashMap<Edge, Number>();
220                        // This Factory produces new edges for use by the algorithm
221                        i=-1;
222                        Factory<Edge> edgeFactory = new Factory<Edge>() {
223                                public Edge create() {
224                                        i++;
225                                        return new Edge(Integer.toString(i), 1, 1);
226                                }
227                        };
228                        EdmondsKarpMaxFlow<Node, Edge> alg = new EdmondsKarpMaxFlow<Node, Edge>(
229                                        directedGraph, source, sink, capTransformer, edgeFlowMap, edgeFactory);
230                       
231                        maxFlowThreshold = bisection.getSmallerSubgraph().getVertexCount() * bisection.edgeCut() / 2; 
232                        alg.evaluate();
233                        System.out.println("MAX FLOW: " + alg.getMaxFlow() + " THRESHOLD: " + maxFlowThreshold);
234                        if(alg.getMaxFlow() < maxFlowThreshold) {
235                                Set<Node> sinkPartition = alg.getNodesInSinkPartition();
236                                System.out.println(sinkPartition);
237                                Set<Node> sourcePartition = alg.getNodesInSourcePartition();
238                                System.out.println(sourcePartition);
239                                bisection = prepareBisection(bisection.getSmallerSubgraph().createInducedSubgraph(), sourcePartition, sinkPartition);
240//                              bisection = new Bisection(new Subgraph(bisection.getSmallerSubgraph().createInducedSubgraph(), BFSReversed(sink, directedGraph, edgeFlowMap)));
241                                System.out.println("NEW BISECTION: " + bisection.toString());
242                                cluster = sinkPartition;
243                        } else
244                                finished = true;
245                }
246                return cluster;
247        }
248       
249        private static Bisection prepareBisection(UndirectedGraph g, Set<Node> sourcePartition, Set<Node> sinkPartition) {
250                Bisection b = null;
251                Subgraph sourceSubgraph = new Subgraph(g, sourcePartition);
252                Subgraph sinkSubgraph = new Subgraph(g, sinkPartition);
253                Subgraph subgraph = null;
254                if(sourceSubgraph.getVertexCount() > sinkSubgraph.getVertexCount())
255                        subgraph =sourceSubgraph;
256                else
257                        subgraph = sinkSubgraph;
258                b = new Bisection(subgraph);
259                return b;
260        }
261       
262}
Note: See TracBrowser for help on using the repository browser.