source: branches/MetisMQI/src/main/java/weka/clusterers/forMetisMQI/Coarse.java

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

Taggata versione per la demo e aggiunto branch.

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