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

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

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

File size: 8.2 KB
Line 
1package weka.clusterers.forMetisMQI;
2
3import java.io.PrintStream;
4import java.util.ArrayList;
5import java.util.HashMap;
6import java.util.Iterator;
7import java.util.List;
8import java.util.Map.Entry;
9
10import weka.core.Attribute;
11import weka.core.Instance;
12import weka.core.Instances;
13
14public class Graph {
15       
16        protected static class NodeInfo {
17                /** The weight of the node */
18                protected int vwgt;
19                /** The size of the adjacency list of the node */
20                protected int nedges;
21                /**
22                 * The index into the adjacency list that is the beginning of the
23                 * adjacency list of v
24                 */
25                protected int iedges;
26                /** The weight of the edges that have been contracted to create the node */
27                protected int cewgt;
28                /** The sum of the weight of the edges adjacent to v */
29                protected int adjwgt;
30
31                public NodeInfo() {
32                        this.vwgt = 1;
33                        this.cewgt = 0;
34                        this.iedges = 0;
35                        this.nedges = 0;
36                        this.adjwgt = 0;
37
38                }
39
40                @Override
41                public String toString() {
42                        return "Vwgt: " + vwgt + " Cewgt: " + cewgt + " Iedges: " + iedges
43                                        + " Nedges: " + nedges + " Adjwgt: " + adjwgt;
44                }
45               
46                @Override
47                public NodeInfo clone() {
48                        NodeInfo ni = new NodeInfo();
49                        ni.adjwgt = adjwgt;
50                        ni.cewgt = cewgt;
51                        ni.iedges = iedges;
52                        ni.nedges = nedges;
53                        ni.vwgt = vwgt;
54                        return ni;
55                }
56        }
57
58        /**
59         * Additional node info for all vertices..
60         */
61        private List<NodeInfo> vtxs;
62        /**
63         * Adjacency vector.
64         */
65        private List<Integer> adjncy;
66        /**
67         * Weights vector
68         */
69        private List<Integer> weights;
70       
71        private HashMap<Integer,Integer> label;
72        private HashMap<Integer,Integer> index;
73
74        /**
75         * Build a new graph given a set of instances.
76         *
77         * @param data
78         */
79        public Graph(Instances data) {
80                vtxs = new ArrayList<NodeInfo>();
81                adjncy = new ArrayList<Integer>();
82                weights = new ArrayList<Integer>();
83                label = new HashMap<Integer,Integer>();
84                index = new HashMap<Integer,Integer>();
85                Iterator<Instance> dataIterator = data.iterator();
86                Attribute from = data.attribute("from");
87                Attribute to = data.attribute("to");
88                if (from == null || to == null)
89                        throw new RuntimeException(
90                                        "Unsupported data: check the list of attributes (from and to are needed).");
91                while (dataIterator.hasNext()) {
92                        Instance edge = dataIterator.next();
93                        int node1 = (int) Math.round(edge.value(from));
94                        int node2 = (int) Math.round(edge.value(to));
95                        addNode(node1); addNode(node2);
96                        addEdgeUndirected(node1, node2, 1);
97                }
98        }
99
100        public Graph() {
101                vtxs = new ArrayList<NodeInfo>();
102                adjncy = new ArrayList<Integer>();
103                weights = new ArrayList<Integer>();
104                label = new HashMap<Integer,Integer>();
105                index = new HashMap<Integer,Integer>();
106        }
107       
108        /**
109         * Returns an iterator over the nodes of the graph.
110         * @return
111         */
112        public Iterator<Integer> iterator() {
113                return label.keySet().iterator();
114        }
115       
116        /**
117         * Returns the label associated with a given index.
118         * @param index
119         * @return
120         */
121        public int getLabel(int index) {
122                return this.index.get(index);
123        }
124       
125        /**
126         * Returns the index associated with a given label.
127         * @param index
128         * @return
129         */
130        public int getIndex(int label) {
131                return this.label.get(label);
132        }
133       
134        private void updateAssociation(int index, int label) {
135                this.index.put(index,label);
136                this.label.put(label,index);
137        }
138       
139        /**
140         * Returns the weight of the edge (u,v).
141         * @param u
142         * @param v
143         * @return
144         */
145        public int getWeight(int u, int v) {
146                int i = getIndex(u);
147                int istart = vtxs.get(i).iedges;
148                int iend = vtxs.get(i).iedges + vtxs.get(i).nedges;
149                int weight = -1; boolean found = false;
150                for(int k = istart; k < iend && !found; k++) {
151                        if(adjncy.get(k) == v) {
152                                weight = weights.get(k);
153                                found = true;
154                    }
155                }
156                return weight;
157        }
158       
159        public void setWeight(int u, int v, int weight) {
160                int i = getIndex(u);
161                int j = getIndex(v);
162                int istart = vtxs.get(i).iedges;
163                int iend = istart + vtxs.get(i).nedges;
164                for(int k = istart; k < iend; k++){
165                        if(adjncy.get(k) == v) {
166                                weights.set(k, weight);
167                        }
168                }
169                int jstart = vtxs.get(j).iedges;
170                int jend = jstart + vtxs.get(j).nedges;
171                for(int k = jstart; k < jend; k++){
172                        if(adjncy.get(k) == u)
173                                weights.set(k, weight);
174                }
175        }
176       
177        public NodeInfo getNode(int u) {
178                int i = getIndex(u);
179                return vtxs.get(i);
180        }
181       
182        public int nedge() {
183                return adjncy.size();
184        }
185       
186        public boolean isNode(int u) {
187                return label.containsKey(u);
188        }
189       
190        public void addNode(int u) {
191                if(!isNode(u)) {
192                        int index = size();
193                        updateAssociation(index, u);
194                        NodeInfo node = new NodeInfo();
195                        node.iedges = nedge();
196                        node.nedges = 0;
197                        node.vwgt = 1;
198                        node.adjwgt = 0;
199                        node.cewgt = 0;
200                        vtxs.add(index, node);
201                }
202        }
203       
204        public int size() {
205                return vtxs.size();
206        }
207       
208        public List<Integer> getNeighbors(int u) {
209                int i = getIndex(u);
210                List<Integer> neighbors = new ArrayList<Integer>();
211                int istart = vtxs.get(i).iedges;
212                int iend = vtxs.get(i).iedges + vtxs.get(i).nedges;
213                for(int k = istart; k < iend; k++) {
214                        neighbors.add(adjncy.get(k));
215                }
216                return neighbors;
217        }
218       
219        /**
220         * Return true if u is neighbor of v.
221         * @param u
222         * @param v
223         * @return
224         */
225        public boolean isNeighbor(int u, int v){
226                return getNeighbors(u).contains(v);
227        }
228       
229        public void addEdgeUndirected(int i, int j, int w) {
230                addEdgeDirectedl(i, j, w);
231                addEdgeDirectedl(j, i, w);
232        }
233       
234        /**
235         * Add an edge from i to j of weight w if previously it doesn't exists, otherwise
236         * simply update the weight of the edge.
237         * @param i
238         * @param j
239         * @param w
240         */
241        public void addEdgeDirectedl(int u, int v, int w) {
242                int i = getIndex(u);
243                if(!isNeighbor(u,v)) {
244                        int istart = getNode(u).iedges;
245                        adjncy.add(istart,v);
246                        for(int k = i + 1; k < size(); k++) {
247                                vtxs.get(k).iedges++;
248                        }
249                        vtxs.get(i).nedges++;
250                        vtxs.get(i).adjwgt += w;
251                        weights.add(istart, w);
252                } else
253                        setWeight(u, v, w);
254        }
255       
256        public boolean isEdge(int u, int v) {
257                int i = getIndex(u);
258                int istart = vtxs.get(i).iedges;
259                int iend = vtxs.get(i).iedges + vtxs.get(i).nedges;
260                boolean found = false;
261                for(int k = istart; k < iend && !found; k++) {
262                        found = (adjncy.get(k) == v);
263                }
264                return found;
265        }
266
267        /**
268         * Print the graph structure.
269         */
270        public void printGraph(PrintStream io) {
271                for(int i = 0; i < vtxs.size(); i++) {
272                        int u = getLabel(i);
273                        io.print("Node: " + u + " Neighbors: ");
274                        Iterator<Integer> neighbors = getNeighbors(u).iterator();
275                        while(neighbors.hasNext()) {
276                                int v = neighbors.next();
277                                io.print(v + " [w: " + getWeight(u, v) + "] ");
278                        }
279                        io.println(getNode(u).toString());
280                }
281        }
282       
283        /**
284         * Return a list containing a random permutation of the vertices.
285         *
286         * @return a random permutation of vertices
287         */
288        public List<Integer> vtxsPermutation() {
289                Random r = Random.instance(); 
290                List<Integer> perm = new ArrayList<Integer>();
291                for (int i = 0; i < vtxs.size(); i++) {
292                        perm.add(getLabel(i));
293                }
294                for (int i = 0; i < perm.size(); i++) {
295                        int k = r.nextInt(perm.size());
296                        int swap = perm.get(k);
297                        perm.set(k, perm.get(i));
298                        perm.set(i, swap);
299                }
300                return perm;
301        }
302       
303        /**
304         * Randomize the adjacency list.
305         */
306        public void adjncyPermutation() {
307                Random r = Random.instance();
308                for (int i = 0; i < vtxs.size(); i++) {
309                        NodeInfo n = vtxs.get(i);
310                        for (int j = n.iedges; j < n.nedges + n.iedges; j++) {
311                                int k = r.nextInt(n.nedges) + n.iedges;
312                                int swap = adjncy.get(k);
313                                adjncy.set(k, adjncy.get(j));
314                                adjncy.set(j, swap);
315                                swap = weights.get(k);
316                                weights.set(k, weights.get(j));
317                                weights.set(j, swap);
318                        }
319                }
320        }
321       
322       
323        @Override
324        public Graph clone() {
325                Graph g = new Graph();
326                g.adjncy = new ArrayList<Integer>();
327                for(int i = 0; i < adjncy.size(); i++) {
328                        g.adjncy.add(adjncy.get(i));
329                }
330               
331                g.weights = new ArrayList<Integer>();
332                for(int i = 0; i < weights.size(); i++) {
333                        g.weights.add(weights.get(i));
334                }
335               
336                g.vtxs = new ArrayList<NodeInfo>();
337                for(int i = 0; i < vtxs.size(); i++) {
338                        g.vtxs.add(vtxs.get(i).clone());
339                }
340               
341                g.index = new HashMap<Integer, Integer>();
342                Iterator<Entry<Integer,Integer>> i = index.entrySet().iterator();
343                while(i.hasNext()) {
344                        Entry<Integer,Integer> entry = i.next();
345                        g.index.put(entry.getKey(), entry.getValue());
346                }
347               
348                g.label = new HashMap<Integer, Integer>();
349                i = label.entrySet().iterator();
350                while(i.hasNext()) {
351                        Entry<Integer,Integer> entry = i.next();
352                        g.label.put(entry.getKey(), entry.getValue());
353                }
354               
355               
356                return g;
357        }
358}
Note: See TracBrowser for help on using the repository browser.