1 25 43 package org.jgrapht.traverse; 44 45 import org.jgrapht.*; 46 import org.jgrapht.util.*; 47 48 49 63 public class ClosestFirstIterator<V, E> 64 extends CrossComponentIterator<V, E, FibonacciHeapNode<ClosestFirstIterator.QueueEntry<V, E>>> 65 { 66 67 69 72 private FibonacciHeap<QueueEntry<V, E>> heap = 73 new FibonacciHeap<QueueEntry<V, E>>(); 74 75 78 private double radius = Double.POSITIVE_INFINITY; 79 80 82 87 public ClosestFirstIterator(Graph<V, E> g) 88 { 89 this(g, null); 90 } 91 92 102 public ClosestFirstIterator(Graph<V, E> g, V startVertex) 103 { 104 this(g, startVertex, Double.POSITIVE_INFINITY); 105 } 106 107 120 public ClosestFirstIterator(Graph<V, E> g, V startVertex, double radius) 121 { 122 super(g, startVertex); 123 this.radius = radius; 124 checkRadiusTraversal(isCrossComponentTraversal()); 125 } 126 127 129 public void setCrossComponentTraversal(boolean crossComponentTraversal) 131 { 132 checkRadiusTraversal(crossComponentTraversal); 133 super.setCrossComponentTraversal(crossComponentTraversal); 134 } 135 136 146 public double getShortestPathLength(V vertex) 147 { 148 FibonacciHeapNode<QueueEntry<V, E>> node = getSeenData(vertex); 149 150 if (node == null) { 151 return Double.POSITIVE_INFINITY; 152 } 153 154 return node.getKey(); 155 } 156 157 169 public E getSpanningTreeEdge(V vertex) 170 { 171 FibonacciHeapNode<QueueEntry<V, E>> node = getSeenData(vertex); 172 173 if (node == null) { 174 return null; 175 } 176 177 return node.getData().spanningTreeEdge; 178 } 179 180 183 protected boolean isConnectedComponentExhausted() 184 { 185 if (heap.size() == 0) { 186 return true; 187 } else { 188 if (heap.min().getKey() > radius) { 189 heap.clear(); 190 191 return true; 192 } else { 193 return false; 194 } 195 } 196 } 197 198 201 protected void encounterVertex(V vertex, E edge) 202 { 203 FibonacciHeapNode<QueueEntry<V, E>> node = createSeenData(vertex, edge); 204 putSeenData(vertex, node); 205 heap.insert(node, node.getKey()); 206 } 207 208 215 protected void encounterVertexAgain(V vertex, E edge) 216 { 217 FibonacciHeapNode<QueueEntry<V, E>> node = getSeenData(vertex); 218 219 if (node.getData().frozen) { 220 return; 222 } 223 224 double candidatePathLength = calculatePathLength(vertex, edge); 225 226 if (candidatePathLength < node.getKey()) { 227 node.getData().spanningTreeEdge = edge; 228 heap.decreaseKey(node, candidatePathLength); 229 } 230 } 231 232 235 protected V provideNextVertex() 236 { 237 FibonacciHeapNode<QueueEntry<V, E>> node = heap.removeMin(); 238 node.getData().frozen = true; 239 240 return node.getData().vertex; 241 } 242 243 private void assertNonNegativeEdge(E edge) 244 { 245 if (getGraph().getEdgeWeight(edge) < 0) { 246 throw new IllegalArgumentException ( 247 "negative edge weights not allowed"); 248 } 249 } 250 251 260 private double calculatePathLength(V vertex, E edge) 261 { 262 assertNonNegativeEdge(edge); 263 264 V otherVertex = Graphs.getOppositeVertex(getGraph(), edge, vertex); 265 FibonacciHeapNode<QueueEntry<V, E>> otherEntry = 266 getSeenData(otherVertex); 267 268 return otherEntry.getKey() 269 + getGraph().getEdgeWeight(edge); 270 } 271 272 private void checkRadiusTraversal(boolean crossComponentTraversal) 273 { 274 if (crossComponentTraversal && (radius != Double.POSITIVE_INFINITY)) { 275 throw new IllegalArgumentException ( 276 "radius may not be specified for cross-component traversal"); 277 } 278 } 279 280 288 private FibonacciHeapNode<QueueEntry<V, E>> createSeenData( 289 V vertex, 290 E edge) 291 { 292 double shortestPathLength; 293 294 if (edge == null) { 295 shortestPathLength = 0; 296 } else { 297 shortestPathLength = calculatePathLength(vertex, edge); 298 } 299 300 QueueEntry<V, E> entry = new QueueEntry<V, E>(); 301 entry.vertex = vertex; 302 entry.spanningTreeEdge = edge; 303 304 return 305 new FibonacciHeapNode<QueueEntry<V, E>>( 306 entry, 307 shortestPathLength); 308 } 309 310 312 315 static class QueueEntry<V, E> 316 { 317 320 E spanningTreeEdge; 321 322 325 V vertex; 326 327 330 boolean frozen; 331 332 QueueEntry() 333 { 334 } 335 } 336 } 337
| Popular Tags
|