source: src/main/java/weka/clusterers/forMetisMQI/Coarse.java @ 7

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

Implementazione di Metis: aggiunta fase di uncoarsing e algoritmo di bisezione. Un po' di refactoring.

File size: 5.4 KB
Line 
1package weka.clusterers.forMetisMQI;
2
3import java.io.PrintStream;
4import java.util.ArrayList;
5import java.util.HashSet;
6import java.util.Iterator;
7import java.util.List;
8import java.util.Set;
9import java.util.Stack;
10
11public class Coarse {
12       
13        private static boolean debug = true;
14        private static PrintStream debugStream = System.err;
15        private static int nodesContracted = 5;
16
17        /**
18         * Return true if the vertex v is matched
19         *
20         * @param g graph
21         * @param v
22         *            the index of the vertex
23         * @return true if the vertex v is matched, false o.w.
24         */
25        private static boolean isMatched(Graph g, List<Integer> match, int v) {
26                return match.get(g.getIndex(v)) != g.getIndex(v);
27        }
28
29        private static void RMMatch(Graph g, List<Integer> match, List<Integer> map) {
30                int labelCounter = 0;
31                for (int i = 0; i < g.size(); i++) {
32                        match.add(i);
33                        map.add(i);
34                }
35                g.adjncyPermutation();
36                Iterator<Integer> nodeIterator = g.vtxsPermutation().iterator();
37                while (nodeIterator.hasNext()) {
38                        int u = nodeIterator.next();
39                        if (debug)
40                                debugStream.println("Visiting node " + u + " Matched = " + isMatched(g,match,u));
41                        if (!isMatched(g,match,u)) {
42                                boolean foundMatch = false;
43                                int matchedNode = -1;
44                                Iterator<Integer> iterator = g.getNeighbors(u).iterator();
45                                while(iterator.hasNext() && !foundMatch){
46                                        int v = iterator.next();
47                                        if (!isMatched(g,match,v)) {
48                                                matchedNode = v;
49                                                foundMatch = true;
50                                                if (debug)
51                                                        debugStream.println("Found a match with node "
52                                                                        + matchedNode);
53                                        }
54                                }
55                                if (debug && !foundMatch)
56                                        debugStream.println("There aren't unmatched neighbors.");
57                                if(foundMatch) {
58                                        match.set(g.getIndex(u), g.getIndex(matchedNode));
59                                        match.set(g.getIndex(matchedNode), g.getIndex(u));
60                                        map.set(g.getIndex(u), labelCounter);
61                                        map.set(g.getIndex(matchedNode), labelCounter);
62                                        if(debug) debugStream.println("Contracting node " + u + " with " + matchedNode + ". Node id: " + getMappedNode(g, map, u));
63                                } else
64                                        map.set(g.getIndex(u), labelCounter);
65                                labelCounter++;
66                        }
67                }
68        }
69       
70        private static int getMatchedNode(Graph g, List<Integer> match, int u) {
71                return g.getLabel(match.get(g.getIndex(u)));
72        }
73       
74        private static int getMappedNode(Graph g, List<Integer> map, int u) {
75                return map.get(g.getIndex(u));
76        }
77       
78        /**
79         * Return a new contracted graph.
80         */
81        private static Graph contract(Graph g, List<Integer> match, List<Integer> map) {
82                Graph output = new Graph();
83                Iterator<Integer> iterator = g.iterator();
84                while(iterator.hasNext()) {
85                        int u = iterator.next();
86                        output.addNode(getMappedNode(g,map,u));
87                        Iterator<Integer> it = g.getNeighbors(u).iterator();
88                        Set<Integer> neighbors = new HashSet<Integer>();
89                        while(it.hasNext()) {
90                                int v = it.next();
91                                neighbors.add(getMappedNode(g,map,v));
92                        }
93                        it = g.getNeighbors(getMatchedNode(g,match,u)).iterator();
94                        while(it.hasNext()) {
95                                int v = it.next();
96                                neighbors.add(getMappedNode(g,map,v));
97                        }
98                        neighbors.remove(getMappedNode(g,map,u));
99                        it = neighbors.iterator();
100                        while(it.hasNext()) {
101                                int v = it.next();
102                                output.addNode(v);
103                                output.addEdgeUndirected(getMappedNode(g,map,u), v, 0);
104                        }
105                }       
106                //calcolo dei pesi del nuovo grafo: per ogni arco (u,v) && u < v.
107                //w(map(u),map(v)) += w(u,v).
108                for(int u=0; u < g.size(); u++) {
109                        Iterator<Integer> it = g.getNeighbors(u).iterator();
110                        while(it.hasNext()) {
111                                int v = it.next();
112                                if(getMappedNode(g,map,u) != getMappedNode(g,map,v) && output.isEdge(getMappedNode(g,map,u), getMappedNode(g,map,v)) && u < v) {
113                                        output.setWeight(getMappedNode(g,map,u), getMappedNode(g,map,v), output.getWeight(getMappedNode(g,map,u), getMappedNode(g,map,v)) + g.getWeight(u, v));
114                                }
115                        }
116                }
117                for(int u = 0; u < g.size(); u++) {
118                        if(isMatched(g,match,u)) {
119                                int v = getMatchedNode(g,match,u);
120                                if(u < v) {
121                                        output.getNode(getMappedNode(g,map,u)).vwgt = g.getNode(u).vwgt + g.getNode(v).vwgt;
122                                        output.getNode(getMappedNode(g,map,u)).cewgt = g.getNode(u).cewgt + g.getNode(v).cewgt +
123                                        g.getWeight(u, v);
124                                        output.getNode(getMappedNode(g,map,u)).adjwgt = g.getNode(u).adjwgt + g.getNode(v).adjwgt - 2 *
125                                        g.getWeight(u, v);
126                                }
127                        } else {
128                                output.getNode(getMappedNode(g,map,u)).vwgt = g.getNode(u).vwgt;
129                                output.getNode(getMappedNode(g,map,u)).cewgt = g.getNode(u).cewgt;
130                                output.getNode(getMappedNode(g,map,u)).adjwgt = g.getNode(u).adjwgt;
131                        }
132                }
133                return output;
134        }
135
136        /**
137         * Performs the first stage of the METIS algorithm, using RM.
138         */
139        public static CoarserGraphElement coarseOneStep(Graph g) {
140                Graph projected = g;
141                Graph contracted = null;
142                List<Integer> match = new ArrayList<Integer>();
143                List<Integer> map = new ArrayList<Integer>();
144                RMMatch(g,match,map);
145                contracted = contract(g,match,map);
146                return new CoarserGraphElement(contracted, projected, match, map);
147        }
148       
149        public static Stack<CoarserGraphElement> coarse(Graph g) {
150                Stack<CoarserGraphElement> stack = new Stack<CoarserGraphElement>();
151                CoarserGraphElement e;
152                Graph curr = g;
153            do {
154                if(debug)
155                        debugStream.println("-----------------------------------------------------");
156                e = coarseOneStep(curr);
157                stack.push(e);
158                curr = e.getContracted();
159                if(debug)
160                        debugStream.println("-----------------------------------------------------");
161            } while(e.getProjected().size() > e.getContracted().size() && e.getContracted().size() > nodesContracted);
162            return stack;
163        }
164}
Note: See TracBrowser for help on using the repository browser.