source: src/main/java/weka/clusterers/forMetisMQI/graph/Subgraph.java @ 12

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

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

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