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

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

Ulteriori refactoring. Creato il clusterer metisMqi, con opzioni.

File size: 6.2 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.FRLayout;
26import edu.uci.ics.jung.algorithms.layout.KKLayout;
27import edu.uci.ics.jung.algorithms.layout.Layout;
28import edu.uci.ics.jung.graph.DirectedGraph;
29import edu.uci.ics.jung.graph.DirectedSparseGraph;
30import edu.uci.ics.jung.graph.Graph;
31import edu.uci.ics.jung.visualization.BasicVisualizationServer;
32import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
33
34public class MQI {
35       
36        static int i = -1;
37       
38        static private Set<Node> BFSReversed(Node sink, DirectedGraph<Node, Edge> g, Map<Edge, Number> edgeFlowMap) {
39                Set<Node> result = new HashSet<Node>();
40                Set<Node> visitedNodes = new HashSet<Node>();
41                Stack<Node> nodesToVisit = new Stack<Node>();
42                result.add(sink);
43                nodesToVisit.push(sink);
44                while(!nodesToVisit.empty()) {
45                        Node currentNode = nodesToVisit.pop();
46                        visitedNodes.add(currentNode);
47                        Collection<Edge> inEdges = g.getInEdges(currentNode);
48                        Iterator<Edge> inEdgesIterator = inEdges.iterator();
49                        while(inEdgesIterator.hasNext()) {
50                                Edge edge = inEdgesIterator.next();
51                                Node src = g.getSource(edge);
52                                Edge reverseEdge = g.findEdge(src, currentNode);
53                                if((reverseEdge != null) && ((Integer)edgeFlowMap.get(reverseEdge) < reverseEdge.getCapacity())) {
54                                        if(!nodesToVisit.contains(src) && !visitedNodes.contains(src)) {
55                                                nodesToVisit.push(src);
56                                        }
57                                        result.add(src);
58                                }
59                        }
60                }
61                return result;
62        }
63       
64        static private DirectedGraph<Node,       Edge> prepareDirectedGraph(Bisection partition, Node source, Node sink) {
65                Subgraph A = null;
66                Subgraph B = null;
67                if(partition.getSubgraph().getVertexCount() < partition.getComplement().getVertexCount()) {
68                        A = partition.getSubgraph();
69                        B = partition.getComplement();
70                }
71                else {
72                        A = partition.getComplement();
73                        B = partition.getSubgraph();
74                }
75                int a = A.getVertexCount();
76                int c = partition.edgeCut() / 2;
77               
78               
79                DirectedGraph<Node,Edge> g = new DirectedSparseGraph<Node, Edge>();
80                Iterator<Node> nodes =  A.iterator();
81                while(nodes.hasNext()) {
82                        Node u = nodes.next();
83                        g.addVertex(u);
84                }
85               
86                nodes =  A.iterator();
87                int id = 0;
88                while(nodes.hasNext()) {
89                        Node u = nodes.next();
90                        Iterator<Node> neighbors = A.getNeighbors(u).iterator();
91                        while(neighbors.hasNext()) {
92                                Node v = neighbors.next();
93                                g.addEdge(new Edge(Integer.toString(id),A.getWeight(u, v),a),u,v);
94                                id++;
95                        }
96                }
97               
98                g.addVertex(source);
99                g.addVertex(sink);
100               
101               
102                nodes =  B.iterator();
103                while(nodes.hasNext()) {
104                        Node u = nodes.next();
105                        Iterator<Node> neighbors = B.getGraph().getNeighbors(u).iterator();
106                        while(neighbors.hasNext()) {
107                                Node v = neighbors.next();
108                                if(A.contains(v)) {
109                                        g.addEdge(new Edge(Integer.toString(id),1,a),source,v);
110                                        id++;
111                                }
112                        }
113                }
114               
115                nodes =  A.iterator();
116                while(nodes.hasNext()) {
117                        Node u = nodes.next();
118                        g.addEdge(new Edge(Integer.toString(id),1,c),u,sink);
119                        id++;
120                }
121                return g;
122        }
123       
124        /**
125         * Given a partion of a graph, execute the Max-Flow Quotient-cut Improvement algorithm,
126         * to find an improved cut and then returns the cluster which yields the best quotient cut.
127         * @param partition
128         * @return
129         */
130        static public Set<Node> mqi(Bisection partition) {
131                System.out.println("INITIAL BISECTION: " + partition.toString());
132                boolean finished = false;
133                Bisection bisection = partition;
134                Set<Node> cluster = new HashSet<Node>(partition.getSubgraph().createInducedSubgraph().getVertices());
135                int maxFlowThreshold = Integer.MAX_VALUE;
136                while (!finished) {
137                        Node source = new Node("S");
138                        Node sink = new Node("T");
139                        DirectedGraph<Node, Edge> directedGraph = prepareDirectedGraph(bisection, source, sink);
140                        Transformer<Edge, Number> capTransformer = new Transformer<Edge, Number>() {
141                                public Double transform(Edge e) {
142                                        return (double) e.getCapacity();
143                                }
144                        };
145                        Map<Edge, Number> edgeFlowMap = new HashMap<Edge, Number>();
146                        // This Factory produces new edges for use by the algorithm
147                        i=-1;
148                        Factory<Edge> edgeFactory = new Factory<Edge>() {
149                                public Edge create() {
150                                        i++;
151                                        return new Edge(Integer.toString(i), 1, 1);
152                                }
153                        };
154                        EdmondsKarpMaxFlow<Node, Edge> alg = new EdmondsKarpMaxFlow<Node, Edge>(
155                                        directedGraph, source, sink, capTransformer, edgeFlowMap, edgeFactory);
156                       
157                        maxFlowThreshold = bisection.getSmallerSubgraph().getVertexCount() * bisection.edgeCut() / 2; 
158                        alg.evaluate();
159                        System.out.println("MAX FLOW: " + alg.getMaxFlow() + " THRESHOLD: " + maxFlowThreshold);
160                        if(alg.getMaxFlow() < maxFlowThreshold) {
161                                Set<Node> sinkPartition = alg.getNodesInSinkPartition();
162                                System.out.println(sinkPartition);
163                                Set<Node> sourcePartition = alg.getNodesInSourcePartition();
164                                System.out.println(sourcePartition);
165                                bisection = prepareBisection(bisection.getSmallerSubgraph().createInducedSubgraph(), sourcePartition, sinkPartition);
166//                              bisection = new Bisection(new Subgraph(bisection.getSmallerSubgraph().createInducedSubgraph(), BFSReversed(sink, directedGraph, edgeFlowMap)));
167                                System.out.println("NEW BISECTION: " + bisection.toString());
168                                cluster = sinkPartition;
169                        } else
170                                finished = true;
171                }
172                return cluster;
173        }
174       
175        private static Bisection prepareBisection(UndirectedGraph g, Set<Node> sourcePartition, Set<Node> sinkPartition) {
176                Bisection b = null;
177                Subgraph sourceSubgraph = new Subgraph(g, sourcePartition);
178                Subgraph sinkSubgraph = new Subgraph(g, sinkPartition);
179                Subgraph subgraph = null;
180                if(sourceSubgraph.getVertexCount() > sinkSubgraph.getVertexCount())
181                        subgraph =sourceSubgraph;
182                else
183                        subgraph = sinkSubgraph;
184                b = new Bisection(subgraph);
185                return b;
186        }
187       
188}
Note: See TracBrowser for help on using the repository browser.