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

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

Implementato raffinamento KL in metis; implementata ottimizzazione di mqi sulla conduttanza.

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