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

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

Individuazione del miglioramento del taglio: tentativi.

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