source: src/main/java/weka/clusterers/forMetisMQI/Subgraph.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: 5.9 KB
Line 
1package weka.clusterers.forMetisMQI;
2
3import java.util.ArrayList;
4import java.util.BitSet;
5import java.util.HashMap;
6import java.util.Iterator;
7import java.util.List;
8import java.util.SortedSet;
9import java.util.TreeSet;
10import java.util.Map.Entry;
11
12import weka.clusterers.forMetisMQI.Graph.NodeInfo;
13
14public class Subgraph {
15       
16        private Graph g = null;
17        private BitSet nodes = null;
18        private List<Integer> listOfNodes = null;
19        private HashMap<Integer,Integer> ID = null;
20        private HashMap<Integer,Integer> ED = null;
21        private HashMap<Integer,List<Integer>> bucketGain = null;
22        private SortedSet<Integer> gainSet = null;
23        private boolean recomputeGain = true;
24       
25        public Subgraph(Graph g){
26                this.g = g;
27                nodes = new BitSet(g.size());
28                listOfNodes = new ArrayList<Integer>();
29                ID = new HashMap<Integer,Integer>();
30                ED = new HashMap<Integer,Integer>();
31                bucketGain = new HashMap<Integer, List<Integer>>();
32                gainSet = new TreeSet<Integer>();
33        }
34       
35        public Graph getGraph() {
36                return g;
37        }
38       
39        public void addNode(int u) {
40                nodes.set(g.getIndex(u));
41                listOfNodes.add(u);
42                ID.put(u, 0);
43                ED.put(u, 0);
44                recomputeGain = true;
45        }
46       
47        private void computeDegree() {
48                for(int i = 0; i < size(); i++) {
49                        int u = listOfNodes.get(i);
50                        Iterator<Integer> it = g.getNeighbors(u).iterator();
51                        int newID = 0;
52                        int newED = 0;
53                        while(it.hasNext()) {
54                                int v = it.next();
55                                if(contains(v))
56                                        newID = newID + g.getWeight(u, v);
57                                else
58                                        newED = newED + g.getWeight(u, v);
59                                ID.put(u, newID);
60                                ED.put(u, newED);
61                        }
62                }
63        }
64       
65        private void computeGain() {
66                bucketGain.clear();
67                gainSet.clear();
68                ID.clear();
69                ED.clear();
70                computeDegree();
71                for(int i = 0; i < size(); i++) {
72                        int u = listOfNodes.get(i);
73                        int gainU = ED.get(u) - ID.get(u);
74                        if(!bucketGain.containsKey(gainU)) {
75                                bucketGain.put(gainU, new ArrayList<Integer>());
76                        }
77                        bucketGain.get(gainU).add(u);
78                        gainSet.add(gainU);
79                }
80                recomputeGain = false;
81        }
82       
83        public int getCandidate() {
84                return getCandidate(new ArrayList<Integer>());
85        }
86       
87        /**
88         *
89         * @param marked
90         * @return the candidate node for swap or -1 if there aren't available nodes.
91         */
92        public int getCandidate(List<Integer> marked) {
93                if(recomputeGain)
94                        computeGain();
95                int candidate = -1;
96                Iterator<Integer> iterator = ((TreeSet<Integer>)gainSet).descendingIterator();
97                while(iterator.hasNext() && (candidate == -1)) {
98                        int gain = iterator.next();
99                        Iterator<Integer> nodes = bucketGain.get(gain).iterator();
100                        while(nodes.hasNext() && (candidate == -1)) {
101                                int u = nodes.next();
102                                if(!marked.contains(u))
103                                        candidate = u;
104                        }
105                }
106                return candidate;
107        }
108       
109        public int gain(int u){
110                if(recomputeGain)
111                        computeGain();
112                return ED.get(u) - ID.get(u);
113        }
114       
115        public void remove(int u) {
116                if(recomputeGain)
117                        computeGain();
118                int gainU = gain(u);
119                nodes.set(g.getIndex(u), false);
120                listOfNodes.remove(listOfNodes.indexOf(u));
121                ID.remove(u);
122                ED.remove(u);
123                List<Integer> l = bucketGain.get(gainU);
124                l.remove(l.indexOf(u));
125                if(l.size() == 0) {
126                        bucketGain.remove(gainU);
127                        gainSet.remove(gainU);
128                }
129                recomputeGain = true;
130        }
131       
132        public int size() {
133                return listOfNodes.size();
134        }
135       
136        public Iterator<Integer> iterator() {
137                return listOfNodes.iterator();
138        }
139       
140        public boolean isEdge(int u, int v) {
141                return nodes.get(g.getIndex(u)) && nodes.get(g.getIndex(v)) && g.isEdge(u, v);
142        }
143       
144        public boolean contains(int u) {
145                return nodes.get(g.getIndex(u));
146        }
147       
148        public List<Integer> getNeighbours(int u) {
149                List<Integer> neighbors = new ArrayList<Integer>();
150                Iterator<Integer> iterator = g.getNeighbors(u).iterator(); 
151                while(iterator.hasNext()) {
152                        int v = iterator.next();
153                        if(contains(v) && isEdge(u, v))
154                                neighbors.add(v);
155                }
156                return neighbors;
157        }
158       
159        public int getExternalDegree() {
160                if(recomputeGain)
161                        computeGain();
162                int acc = 0;
163                Iterator<Integer> it = ED.values().iterator();
164                while(it.hasNext())
165                        acc = acc + it.next();
166                return acc;
167        }
168       
169        @Override
170        public String toString() {
171                String out = "[";
172                Iterator<Integer> it = listOfNodes.iterator();
173                while(it.hasNext()) {
174                        int u = it.next();
175                        out = out + u + ",";
176                }
177                out = out + "]";
178                return out;
179        }
180       
181        public List<Integer> getBoundary() {
182                if(recomputeGain)
183                        computeGain();
184                Iterator<Entry<Integer,Integer>> EDIterator = ED.entrySet().iterator();
185                List<Integer> boundary = new ArrayList<Integer>();
186                while(EDIterator.hasNext()) {
187                        Entry<Integer,Integer> entry = EDIterator.next();
188                        if(entry.getValue() > 0)
189                                boundary.add(entry.getKey());
190                }
191                return boundary;
192        }
193       
194        private Subgraph() {
195               
196        }
197       
198        @Override
199        public Subgraph clone() {
200                Subgraph clone = new Subgraph();
201                clone.g = g.clone();
202               
203                clone.nodes = (BitSet)nodes.clone();
204               
205                clone.listOfNodes = new ArrayList<Integer>();
206                for(int i = 0; i < listOfNodes.size(); i++) {
207                        clone.listOfNodes.add(listOfNodes.get(i));
208                }
209               
210                clone.ID = new HashMap<Integer, Integer>();
211                Iterator<Entry<Integer,Integer>> i = ID.entrySet().iterator();
212                while(i.hasNext()) {
213                        Entry<Integer,Integer> entry = i.next();
214                        clone.ID.put(entry.getKey(), entry.getValue());
215                }
216               
217                clone.ED = new HashMap<Integer, Integer>();
218                i = ED.entrySet().iterator();
219                while(i.hasNext()) {
220                        Entry<Integer,Integer> entry = i.next();
221                        clone.ED.put(entry.getKey(), entry.getValue());
222                }
223               
224                clone.bucketGain = new HashMap<Integer, List<Integer>>();
225                Iterator<Entry<Integer,List<Integer>>>it = bucketGain.entrySet().iterator();
226                while(it.hasNext()) {
227                        Entry<Integer,List<Integer>> entry = it.next();
228                        List<Integer> bucketClone = new ArrayList<Integer>();
229                        List<Integer> bucket = entry.getValue();
230                        for(int j = 0; j < bucket.size(); j++) {
231                                bucketClone.add(bucket.get(j));
232                        }
233                        clone.bucketGain.put(entry.getKey(), bucketClone);
234                }
235               
236                clone.gainSet = new TreeSet<Integer>();
237                Iterator<Integer> gainIt = gainSet.iterator();
238                while(gainIt.hasNext()) {
239                        gainSet.add(gainIt.next());
240                }
241               
242                clone.recomputeGain = recomputeGain;
243               
244                return clone;
245        }
246}
Note: See TracBrowser for help on using the repository browser.