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

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

Un po' di refactoring e implementazione dell'algoritmo di raffinamento.

File size: 6.2 KB
Line 
1package weka.clusterers.forMetisMQI.coarse;
2
3import java.io.PrintStream;
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 weka.clusterers.forMetisMQI.graph.Edge;
12import weka.clusterers.forMetisMQI.graph.Node;
13import weka.clusterers.forMetisMQI.graph.UndirectedGraph;
14
15import edu.uci.ics.jung.graph.util.Pair;
16
17public class Coarse {
18       
19        private static boolean debug = false;
20        private static PrintStream debugStream = System.err;
21        private static int finerSize = 5;
22
23        /**
24         * Return true if the vertex v is matched
25         *
26         * @param g graph
27         * @param v
28         *            the index of the vertex
29         * @return true if the vertex v is matched, false o.w.
30         */
31        private static boolean isMatched(Map<Node,Node> match, Node v) {
32                if(match.containsKey(v))
33                        return !match.get(v).equals(v);
34                else
35                        return false;
36        }
37
38        private static void RMMatch(UndirectedGraph g, Map<Node,Node> match, Map<Node,Node> map) {
39                int labelCounter = 0;
40                Iterator<Node> nodeIterator = g.vtxsPermutation().iterator();
41                while (nodeIterator.hasNext()) {
42                        Node u = nodeIterator.next();
43                        if (debug)
44                                debugStream.println("Visiting node " + u + " Matched = " + isMatched(match,u));
45                        if (!isMatched(match,u)) {
46                                boolean foundMatch = false;
47                                Node matchedNode = null;
48                                Iterator<Node> iterator = g.getNeighborsPermutation(u).iterator();
49                                while(iterator.hasNext() && !foundMatch){
50                                        Node v = iterator.next();
51                                        if (!isMatched(match,v)) {
52                                                matchedNode = v;
53                                                foundMatch = true;
54                                                if (debug)
55                                                        debugStream.println("Found a match with node "
56                                                                        + matchedNode);
57                                        }
58                                }
59                                if (debug && !foundMatch)
60                                        debugStream.println("There aren't unmatched neighbors.");
61                                Node newNode = new Node(Integer.toString(labelCounter));
62                                if(foundMatch) {
63                                        match.put(u, matchedNode);
64                                        match.put(matchedNode, u);
65                                        map.put(u, newNode);
66                                        map.put(matchedNode, newNode);
67                                        if(debug) debugStream.println("Contracting node " + u + " with " + matchedNode + ". Node id: " + getMappedNode(map, u));
68                                } else {
69                                        match.put(u, u);
70                                        map.put(u, newNode);
71                                        if(debug) debugStream.println("Node " + u + " with " + " new node id: " + getMappedNode(map, u));
72                                }
73                                labelCounter++;
74                        }
75                }
76        }
77       
78        private static Node getMatchedNode(Map<Node,Node> match, Node u) {
79                return match.get(u);
80        }
81       
82        private static Node getMappedNode(Map<Node,Node> map, Node u) {
83                return map.get(u);
84        }
85       
86        /**
87         * Return a new contracted graph.
88         */
89        private static UndirectedGraph contract(UndirectedGraph g, Map<Node,Node> match, Map<Node,Node> map) {
90                UndirectedGraph output = new UndirectedGraph();
91                Iterator<Node> iterator = g.getVertices().iterator();
92                int i = 0;
93                while(iterator.hasNext()) {
94                        Node u = iterator.next();
95                        output.addVertex(getMappedNode(map,u));
96                       
97                        Set<Node> neighbors = new HashSet<Node>();
98                        Iterator<Node> it = g.getNeighbors(u).iterator();
99                        while(it.hasNext())
100                                neighbors.add(getMappedNode(map, it.next()));
101                        it = g.getNeighbors(getMatchedNode(match, u)).iterator();
102                        while(it.hasNext())
103                                neighbors.add(getMappedNode(map, it.next()));
104                        neighbors.remove(getMappedNode(map,u));
105                        it = neighbors.iterator();
106                        while(it.hasNext()) {
107                                Node v = it.next();
108                                output.addVertex(v);
109                                output.addEdge(new Edge(Integer.toString(i),0,0),getMappedNode(map,u), v);
110                                i++;
111                        }
112                }
113               
114                //calcolo dei pesi del nuovo grafo: per ogni arco (u,v) && u < v.
115                //w(map(u),map(v)) += w(u,v).
116               
117                Iterator<Edge> edgeIterator = g.getEdges().iterator();
118                while(edgeIterator.hasNext()) {
119                        Edge oldEdge = edgeIterator.next();
120                        Pair<Node> srcDst = g.getEndpoints(oldEdge);
121                        Node src = srcDst.getFirst();
122                        Node dst = srcDst.getSecond();
123                        Node srcMapped = getMappedNode(map, src);
124                        Node dstMapped = getMappedNode(map, dst);
125                        if(!srcMapped.equals(dstMapped) && output.containsEdge(srcMapped, dstMapped)) {
126                                Edge newEdge = output.findEdge(srcMapped, dstMapped);
127                                newEdge.setWeight(newEdge.getWeight() + oldEdge.getWeight());
128                        }
129                }
130                iterator = g.getVertices().iterator();
131                Set<Node> nodesComplete = new HashSet<Node>();
132                while(iterator.hasNext()) {
133                        Node u = iterator.next();
134                        if(isMatched(match,u)) {
135                                Node v = getMatchedNode(match,u);
136                                if(!nodesComplete.contains(u)) {
137                                        getMappedNode(map,u).setVwgt(u.getVwgt() + v.getVwgt());
138                                        getMappedNode(map,u).setCewgt(u.getCewgt() + v.getCewgt() + g.findEdge(u, v).getWeight());
139                                        nodesComplete.add(u);
140                                        nodesComplete.add(v);
141                                }
142                        } else {
143                                getMappedNode(map,u).setVwgt(u.getVwgt());
144                                getMappedNode(map,u).setCewgt(u.getCewgt());
145                        }
146                }
147                return output;
148        }
149
150        /**
151         * Performs the first stage of the METIS algorithm, using RM.
152         */
153        private static CoarserGraphElement coarseOneStep(UndirectedGraph g) {
154                UndirectedGraph projected = g;
155                UndirectedGraph contracted = null;
156                Map<Node,Node> match = new HashMap<Node,Node>();
157                Map<Node,Node> map = new HashMap<Node,Node>();
158                RMMatch(g,match,map);
159                contracted = contract(g,match,map);
160                return new CoarserGraphElement(contracted, projected, match, map);
161        }
162
163       
164        /**
165         * Performs at least one contraction of the given the graph, and goes on until the graph
166         * is under the desidered size (see setFinerSize()).
167         * @param g
168         * @return the stack of contracted graphs
169         */
170        public static Stack<CoarserGraphElement> coarse(UndirectedGraph g) {
171                Stack<CoarserGraphElement> stack = new Stack<CoarserGraphElement>();
172                CoarserGraphElement e = null;
173                UndirectedGraph curr = g;
174                int i = 0;
175               
176            do {
177                if(debug)
178                        debugStream.println("--------CONTRACTION-nr" + i +"------------------------------");
179                e = coarseOneStep(curr);
180                stack.push(e);
181                curr = e.getContracted();
182                if(debug) {
183                        debugStream.println("-----------EXPANDED----------------------------------");
184                        debugStream.println(e.getProjected().toString());
185                        debugStream.println("-----------CONTRACTED--------------------------------");
186                        debugStream.println(e.getContracted().toString());
187                }
188                i++;
189            } while(e.getProjected().getVertexCount() > e.getContracted().getVertexCount() && e.getContracted().getVertexCount() > finerSize);
190            return stack;
191        }
192
193        public static void setFinerSize(int i) {
194                finerSize = i;
195        }
196}
Note: See TracBrowser for help on using the repository browser.