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

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

Inizio prototipazione di Metis+MQI.

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