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

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

Corretta la creazione del grafo per il calcolo del flusso massimo (errore logico); implementata DFS ricorsiva sul grafo.

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