1
2
3
4
5
6
7
8
9
10 package edu.uci.ics.jung.algorithms.shortestpath;
11
12
13 import java.util.ArrayList;
14 import java.util.Collections;
15 import java.util.HashMap;
16 import java.util.HashSet;
17 import java.util.List;
18 import java.util.Map;
19 import java.util.Set;
20
21 import edu.uci.ics.jung.graph.Hypergraph;
22
23
24
25
26
27
28
29
30
31 public class BFSDistanceLabeler<V, E> {
32
33 private Map<V, Number> distanceDecorator = new HashMap<V,Number>();
34 private List<V> mCurrentList;
35 private Set<V> mUnvisitedVertices;
36 private List<V> mVerticesInOrderVisited;
37 private Map<V,HashSet<V>> mPredecessorMap;
38
39
40
41
42
43 public BFSDistanceLabeler() {
44 mPredecessorMap = new HashMap<V,HashSet<V>>();
45 }
46
47
48
49
50
51 public List<V> getVerticesInOrderVisited() {
52 return mVerticesInOrderVisited;
53 }
54
55
56
57
58
59 public Set<V> getUnvisitedVertices() {
60 return mUnvisitedVertices;
61 }
62
63
64
65
66
67
68
69 public int getDistance(Hypergraph<V,E> g, V v) {
70 if (!g.getVertices().contains(v)) {
71 throw new IllegalArgumentException("Vertex is not contained in the graph.");
72 }
73
74 return distanceDecorator.get(v).intValue();
75 }
76
77
78
79
80
81
82 public Set<V> getPredecessors(V v) {
83 return mPredecessorMap.get(v);
84 }
85
86 protected void initialize(Hypergraph<V,E> g, Set<V> rootSet) {
87 mVerticesInOrderVisited = new ArrayList<V>();
88 mUnvisitedVertices = new HashSet<V>();
89 for(V currentVertex : g.getVertices()) {
90 mUnvisitedVertices.add(currentVertex);
91 mPredecessorMap.put(currentVertex,new HashSet<V>());
92 }
93
94 mCurrentList = new ArrayList<V>();
95 for(V v : rootSet) {
96 distanceDecorator.put(v, new Integer(0));
97 mCurrentList.add(v);
98 mUnvisitedVertices.remove(v);
99 mVerticesInOrderVisited.add(v);
100 }
101 }
102
103 private void addPredecessor(V predecessor,V sucessor) {
104 HashSet<V> predecessors = mPredecessorMap.get(sucessor);
105 predecessors.add(predecessor);
106 }
107
108
109
110
111
112
113
114
115 public void labelDistances(Hypergraph<V,E> graph, Set<V> rootSet) {
116
117 initialize(graph,rootSet);
118
119 int distance = 1;
120 while (true) {
121 List<V> newList = new ArrayList<V>();
122 for(V currentVertex : mCurrentList) {
123 if(graph.containsVertex(currentVertex)) {
124 for(V next : graph.getSuccessors(currentVertex)) {
125 visitNewVertex(currentVertex,next, distance, newList);
126 }
127 }
128 }
129 if (newList.size() == 0) break;
130 mCurrentList = newList;
131 distance++;
132 }
133
134 for(V v : mUnvisitedVertices) {
135 distanceDecorator.put(v,new Integer(-1));
136 }
137 }
138
139
140
141
142
143
144
145 public void labelDistances(Hypergraph<V,E> graph, V root) {
146 labelDistances(graph, Collections.singleton(root));
147 }
148
149 private void visitNewVertex(V predecessor, V neighbor, int distance, List<V> newList) {
150 if (mUnvisitedVertices.contains(neighbor)) {
151 distanceDecorator.put(neighbor, new Integer(distance));
152 newList.add(neighbor);
153 mVerticesInOrderVisited.add(neighbor);
154 mUnvisitedVertices.remove(neighbor);
155 }
156 int predecessorDistance = distanceDecorator.get(predecessor).intValue();
157 int successorDistance = distanceDecorator.get(neighbor).intValue();
158 if (predecessorDistance < successorDistance) {
159 addPredecessor(predecessor,neighbor);
160 }
161 }
162
163
164
165
166
167 public Map<V, Number> getDistanceDecorator() {
168 return distanceDecorator;
169 }
170 }