1
2
3
4
5
6
7
8
9
10 package edu.uci.ics.jung.algorithms.importance;
11
12 import java.text.DecimalFormat;
13 import java.text.Format;
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.Collections;
17 import java.util.HashMap;
18 import java.util.List;
19 import java.util.Map;
20
21 import com.google.common.cache.CacheBuilder;
22 import com.google.common.cache.CacheLoader;
23 import com.google.common.cache.LoadingCache;
24
25 import edu.uci.ics.jung.algorithms.util.IterativeProcess;
26 import edu.uci.ics.jung.graph.Graph;
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 public abstract class AbstractRanker<V,E> extends IterativeProcess {
46 private Graph<V,E> mGraph;
47 private List<Ranking<?>> mRankings;
48 private boolean mRemoveRankScoresOnFinalize;
49 private boolean mRankNodes;
50 private boolean mRankEdges;
51 private boolean mNormalizeRankings;
52 protected LoadingCache<Object, Map<V, Number>> vertexRankScores
53 = CacheBuilder.newBuilder().build(new CacheLoader<Object, Map<V, Number>>() {
54 public Map<V, Number> load(Object o) {
55 return new HashMap<V, Number>();
56 }
57 });
58 protected LoadingCache<Object, Map<E, Number>> edgeRankScores
59 = CacheBuilder.newBuilder().build(new CacheLoader<Object, Map<E, Number>>() {
60 public Map<E, Number> load(Object o) {
61 return new HashMap<E, Number>();
62 }
63 });
64
65 private Map<E,Number> edgeWeights = new HashMap<E,Number>();
66
67 protected void initialize(Graph<V,E> graph, boolean isNodeRanker,
68 boolean isEdgeRanker) {
69 if (!isNodeRanker && !isEdgeRanker)
70 throw new IllegalArgumentException("Must rank edges, vertices, or both");
71 mGraph = graph;
72 mRemoveRankScoresOnFinalize = true;
73 mNormalizeRankings = true;
74 mRankNodes = isNodeRanker;
75 mRankEdges = isEdgeRanker;
76 }
77
78
79
80
81 public Map<Object,Map<V, Number>> getVertexRankScores() {
82 return vertexRankScores.asMap();
83 }
84
85 public Map<Object,Map<E, Number>> getEdgeRankScores() {
86 return edgeRankScores.asMap();
87 }
88
89
90
91
92
93 public Map<V, Number> getVertexRankScores(Object key) {
94 return vertexRankScores.getUnchecked(key);
95 }
96
97 public Map<E, Number> getEdgeRankScores(Object key) {
98 return edgeRankScores.getUnchecked(key);
99 }
100
101 protected Collection<V> getVertices() {
102 return mGraph.getVertices();
103 }
104
105 protected int getVertexCount() {
106 return mGraph.getVertexCount();
107 }
108
109 protected Graph<V,E> getGraph() {
110 return mGraph;
111 }
112
113 @Override
114 public void reset() {
115 }
116
117
118
119
120
121 public boolean isRankingNodes() {
122 return mRankNodes;
123 }
124
125
126
127
128
129 public boolean isRankingEdges() {
130 return mRankEdges;
131 }
132
133
134
135
136
137
138 public void setRemoveRankScoresOnFinalize(boolean removeRankScoresOnFinalize) {
139 this.mRemoveRankScoresOnFinalize = removeRankScoresOnFinalize;
140 }
141
142 protected void onFinalize(Object e) {}
143
144
145
146
147
148 abstract public Object getRankScoreKey();
149
150
151 @SuppressWarnings("unchecked")
152 @Override
153 protected void finalizeIterations() {
154 List<Ranking<?>> sortedRankings = new ArrayList<Ranking<?>>();
155
156 int id = 1;
157 if (mRankNodes) {
158 for (V currentVertex : getVertices()) {
159 Ranking<V> ranking = new Ranking<V>(id,getVertexRankScore(currentVertex),currentVertex);
160 sortedRankings.add(ranking);
161 if (mRemoveRankScoresOnFinalize) {
162 this.vertexRankScores.getUnchecked(getRankScoreKey()).remove(currentVertex);
163 }
164 id++;
165 onFinalize(currentVertex);
166 }
167 }
168 if (mRankEdges) {
169 for (E currentEdge : mGraph.getEdges()) {
170
171 Ranking<E> ranking = new Ranking<E>(id,getEdgeRankScore(currentEdge),currentEdge);
172 sortedRankings.add(ranking);
173 if (mRemoveRankScoresOnFinalize) {
174 this.edgeRankScores.getUnchecked(getRankScoreKey()).remove(currentEdge);
175 }
176 id++;
177 onFinalize(currentEdge);
178 }
179 }
180
181 mRankings = sortedRankings;
182 Collections.sort(mRankings);
183 }
184
185
186
187
188
189
190
191 public List<Ranking<?>> getRankings() {
192 return mRankings;
193 }
194
195
196
197
198
199
200 public List<Double> getRankScores(int topKRankings) {
201 List<Double> scores = new ArrayList<Double>();
202 int count=1;
203 for (Ranking<?> currentRanking : getRankings()) {
204 if (count > topKRankings) {
205 return scores;
206 }
207 scores.add(currentRanking.rankScore);
208 count++;
209 }
210
211 return scores;
212 }
213
214
215
216
217
218
219
220
221
222
223 public double getVertexRankScore(V v) {
224 Number rankScore = vertexRankScores.getUnchecked(getRankScoreKey()).get(v);
225 if (rankScore != null) {
226 return rankScore.doubleValue();
227 } else {
228 throw new RuntimeException("setRemoveRankScoresOnFinalize(false) must be called before evaluate().");
229 }
230 }
231
232 public double getVertexRankScore(V v, Object key) {
233 return vertexRankScores.getUnchecked(key).get(v).doubleValue();
234 }
235
236 public double getEdgeRankScore(E e) {
237 Number rankScore = edgeRankScores.getUnchecked(getRankScoreKey()).get(e);
238 if (rankScore != null) {
239 return rankScore.doubleValue();
240 } else {
241 throw new RuntimeException("setRemoveRankScoresOnFinalize(false) must be called before evaluate().");
242 }
243 }
244
245 public double getEdgeRankScore(E e, Object key) {
246 return edgeRankScores.getUnchecked(key).get(e).doubleValue();
247 }
248
249 protected void setVertexRankScore(V v, double rankValue, Object key) {
250 vertexRankScores.getUnchecked(key).put(v, rankValue);
251 }
252
253 protected void setEdgeRankScore(E e, double rankValue, Object key) {
254 edgeRankScores.getUnchecked(key).put(e, rankValue);
255 }
256
257 protected void setVertexRankScore(V v, double rankValue) {
258 setVertexRankScore(v,rankValue, getRankScoreKey());
259 }
260
261 protected void setEdgeRankScore(E e, double rankValue) {
262 setEdgeRankScore(e, rankValue, getRankScoreKey());
263 }
264
265 protected void removeVertexRankScore(V v, Object key) {
266 vertexRankScores.getUnchecked(key).remove(v);
267 }
268
269 protected void removeEdgeRankScore(E e, Object key) {
270 edgeRankScores.getUnchecked(key).remove(e);
271 }
272
273 protected void removeVertexRankScore(V v) {
274 vertexRankScores.getUnchecked(getRankScoreKey()).remove(v);
275 }
276
277 protected void removeEdgeRankScore(E e) {
278 edgeRankScores.getUnchecked(getRankScoreKey()).remove(e);
279 }
280
281 protected double getEdgeWeight(E e) {
282 return edgeWeights.get(e).doubleValue();
283 }
284
285 protected void setEdgeWeight(E e, double weight) {
286 edgeWeights.put(e, weight);
287 }
288
289 public void setEdgeWeights(Map<E,Number> edgeWeights) {
290 this.edgeWeights = edgeWeights;
291 }
292
293
294
295
296 public Map<E, Number> getEdgeWeights() {
297 return edgeWeights;
298 }
299
300 protected void assignDefaultEdgeTransitionWeights() {
301
302 for (V currentVertex : getVertices()) {
303
304 Collection<E> outgoingEdges = mGraph.getOutEdges(currentVertex);
305
306 double numOutEdges = outgoingEdges.size();
307 for (E currentEdge : outgoingEdges) {
308 setEdgeWeight(currentEdge,1.0/numOutEdges);
309 }
310 }
311 }
312
313 protected void normalizeEdgeTransitionWeights() {
314
315 for (V currentVertex : getVertices()) {
316
317 Collection<E> outgoingEdges = mGraph.getOutEdges(currentVertex);
318
319 double totalEdgeWeight = 0;
320 for (E currentEdge : outgoingEdges) {
321 totalEdgeWeight += getEdgeWeight(currentEdge);
322 }
323
324 for (E currentEdge : outgoingEdges) {
325 setEdgeWeight(currentEdge,getEdgeWeight(currentEdge)/totalEdgeWeight);
326 }
327 }
328 }
329
330 protected void normalizeRankings() {
331 if (!mNormalizeRankings) {
332 return;
333 }
334 double totalWeight = 0;
335
336 for (V currentVertex : getVertices()) {
337 totalWeight += getVertexRankScore(currentVertex);
338 }
339
340 for (V currentVertex : getVertices()) {
341 setVertexRankScore(currentVertex,getVertexRankScore(currentVertex)/totalWeight);
342 }
343 }
344
345
346
347
348
349
350
351 public void printRankings(boolean verbose,boolean printScore) {
352 double total = 0;
353 Format formatter = new DecimalFormat("#0.#######");
354 int rank = 1;
355
356 for (Ranking<?> currentRanking : getRankings()) {
357 double rankScore = currentRanking.rankScore;
358 if (verbose) {
359 System.out.print("Rank " + rank + ": ");
360 if (printScore) {
361 System.out.print(formatter.format(rankScore));
362 }
363 System.out.print("\tVertex Id: " + currentRanking.originalPos);
364 System.out.print(" (" + currentRanking.getRanked() + ")");
365 System.out.println();
366 } else {
367 System.out.print(rank + "\t");
368 if (printScore) {
369 System.out.print(formatter.format(rankScore));
370 }
371 System.out.println("\t" + currentRanking.originalPos);
372
373 }
374 total += rankScore;
375 rank++;
376 }
377
378 if (verbose) {
379 System.out.println("Total: " + formatter.format(total));
380 }
381 }
382
383
384
385
386
387
388
389 public void setNormalizeRankings(boolean normalizeRankings) {
390 mNormalizeRankings = normalizeRankings;
391 }
392 }