31
31
import com .graphhopper .storage .SPTEntry ;
32
32
import com .graphhopper .util .*;
33
33
34
+ import java .util .ArrayList ;
35
+ import java .util .List ;
34
36
import java .util .PriorityQueue ;
35
37
36
38
/**
@@ -67,10 +69,11 @@ public class AStarBidirection extends AbstractBidirAlgo implements Recalculation
67
69
protected IntObjectMap <AStarEntry > bestWeightMapTo ;
68
70
private IntObjectMap <AStarEntry > bestWeightMapOther ;
69
71
private ConsistentWeightApproximator weightApprox ;
70
- private PriorityQueue <AStarEntry > prioQueueOpenSetFrom ;
71
- private PriorityQueue <AStarEntry > prioQueueOpenSetTo ;
72
- private final IntHashSet ignoreExplorationFrom = new IntHashSet ();
73
- private final IntHashSet ignoreExplorationTo = new IntHashSet ();
72
+ private PriorityQueue <AStarEntry > pqOpenSetFrom ;
73
+ private PriorityQueue <AStarEntry > pqOpenSetTo ;
74
+ private IntHashSet ignoreExplorationFrom = new IntHashSet ();
75
+ private IntHashSet ignoreExplorationTo = new IntHashSet ();
76
+ private boolean updateBestPath = true ;
74
77
75
78
public AStarBidirection (Graph graph , Weighting weighting , TraversalMode tMode ) {
76
79
super (graph , weighting , tMode );
@@ -82,10 +85,10 @@ public AStarBidirection(Graph graph, Weighting weighting, TraversalMode tMode) {
82
85
}
83
86
84
87
protected void initCollections (int size ) {
85
- prioQueueOpenSetFrom = new PriorityQueue <AStarEntry >(size );
88
+ pqOpenSetFrom = new PriorityQueue <AStarEntry >(size );
86
89
bestWeightMapFrom = new GHIntObjectHashMap <AStarEntry >(size );
87
90
88
- prioQueueOpenSetTo = new PriorityQueue <AStarEntry >(size );
91
+ pqOpenSetTo = new PriorityQueue <AStarEntry >(size );
89
92
bestWeightMapTo = new GHIntObjectHashMap <AStarEntry >(size );
90
93
}
91
94
@@ -110,7 +113,7 @@ protected SPTEntry createSPTEntry(int node, double weight) {
110
113
public void initFrom (int from , double weight ) {
111
114
currFrom = new AStarEntry (EdgeIterator .NO_EDGE , from , weight , weight );
112
115
weightApprox .setFrom (from );
113
- prioQueueOpenSetFrom .add (currFrom );
116
+ pqOpenSetFrom .add (currFrom );
114
117
115
118
if (currTo != null ) {
116
119
currFrom .weight += weightApprox .approximate (currFrom .adjNode , false );
@@ -136,7 +139,7 @@ public void initFrom(int from, double weight) {
136
139
public void initTo (int to , double weight ) {
137
140
currTo = new AStarEntry (EdgeIterator .NO_EDGE , to , weight , weight );
138
141
weightApprox .setTo (to );
139
- prioQueueOpenSetTo .add (currTo );
142
+ pqOpenSetTo .add (currTo );
140
143
141
144
if (currFrom != null ) {
142
145
currFrom .weight += weightApprox .approximate (currFrom .adjNode , false );
@@ -193,24 +196,24 @@ protected boolean finished() {
193
196
194
197
@ Override
195
198
boolean fillEdgesFrom () {
196
- if (prioQueueOpenSetFrom .isEmpty ())
199
+ if (pqOpenSetFrom .isEmpty ())
197
200
return false ;
198
201
199
- currFrom = prioQueueOpenSetFrom .poll ();
202
+ currFrom = pqOpenSetFrom .poll ();
200
203
bestWeightMapOther = bestWeightMapTo ;
201
- fillEdges (currFrom , prioQueueOpenSetFrom , bestWeightMapFrom , ignoreExplorationFrom , outEdgeExplorer , false );
204
+ fillEdges (currFrom , pqOpenSetFrom , bestWeightMapFrom , ignoreExplorationFrom , outEdgeExplorer , false );
202
205
visitedCountFrom ++;
203
206
return true ;
204
207
}
205
208
206
209
@ Override
207
210
boolean fillEdgesTo () {
208
- if (prioQueueOpenSetTo .isEmpty ())
211
+ if (pqOpenSetTo .isEmpty ())
209
212
return false ;
210
213
211
- currTo = prioQueueOpenSetTo .poll ();
214
+ currTo = pqOpenSetTo .poll ();
212
215
bestWeightMapOther = bestWeightMapFrom ;
213
- fillEdges (currTo , prioQueueOpenSetTo , bestWeightMapTo , ignoreExplorationTo , inEdgeExplorer , true );
216
+ fillEdges (currTo , pqOpenSetTo , bestWeightMapTo , ignoreExplorationTo , inEdgeExplorer , true );
214
217
visitedCountTo ++;
215
218
return true ;
216
219
}
@@ -256,7 +259,9 @@ private void fillEdges(AStarEntry currEdge, PriorityQueue<AStarEntry> prioQueueO
256
259
257
260
ase .parent = currEdge ;
258
261
prioQueueOpenSet .add (ase );
259
- updateBestPath (iter , ase , traversalId );
262
+
263
+ if (updateBestPath )
264
+ updateBestPath (iter , ase , traversalId );
260
265
}
261
266
}
262
267
}
@@ -290,42 +295,69 @@ public void updateBestPath(EdgeIteratorState edgeState, AStarEntry entryCurrent,
290
295
}
291
296
}
292
297
298
+ IntObjectMap <AStarEntry > getBestFromMap () {
299
+ return bestWeightMapFrom ;
300
+ }
301
+
302
+ IntObjectMap <AStarEntry > getBestToMap () {
303
+ return bestWeightMapTo ;
304
+ }
305
+
306
+ void setBestOtherMap (IntObjectMap <AStarEntry > other ) {
307
+ bestWeightMapOther = other ;
308
+ }
309
+
310
+ void setFromDataStructures (AStarBidirection astar ) {
311
+ pqOpenSetFrom = astar .pqOpenSetFrom ;
312
+ bestWeightMapFrom = astar .bestWeightMapFrom ;
313
+ finishedFrom = astar .finishedFrom ;
314
+ currFrom = astar .currFrom ;
315
+ visitedCountFrom = astar .visitedCountFrom ;
316
+ ignoreExplorationFrom = astar .ignoreExplorationFrom ;
317
+ weightApprox .setFrom (astar .currFrom .adjNode );
318
+ // outEdgeExplorer
319
+ }
320
+
321
+ void setToDataStructures (AStarBidirection astar ) {
322
+ pqOpenSetTo = astar .pqOpenSetTo ;
323
+ bestWeightMapTo = astar .bestWeightMapTo ;
324
+ finishedTo = astar .finishedTo ;
325
+ currTo = astar .currTo ;
326
+ visitedCountTo = astar .visitedCountTo ;
327
+ ignoreExplorationTo = astar .ignoreExplorationTo ;
328
+ weightApprox .setTo (astar .currTo .adjNode );
329
+ // inEdgeExplorer
330
+ }
331
+
293
332
@ Override
294
333
public void afterHeuristicChange (boolean forward , boolean backward ) {
295
334
if (forward ) {
296
- ignoreExplorationFrom .ensureCapacity (bestWeightMapFrom .size ());
297
- bestWeightMapFrom .forEach (new IntObjectPredicate <AStarEntry >() {
298
- @ Override
299
- public boolean apply (int key , AStarEntry value ) {
335
+
336
+ // update PQ due to heuristic change (i.e. weight changed)
337
+ if (!pqOpenSetFrom .isEmpty ()) {
338
+ // copy into temporary array to avoid pointer change of PQ
339
+ AStarEntry [] entries = pqOpenSetFrom .toArray (new AStarEntry [pqOpenSetFrom .size ()]);
340
+ pqOpenSetFrom .clear ();
341
+ for (AStarEntry value : entries ) {
300
342
value .weight = value .weightOfVisitedPath + weightApprox .approximate (value .adjNode , false );
301
- ignoreExplorationFrom .add (key );
302
- return true ;
303
- }
304
- });
343
+ // does not work for edge based
344
+ // ignoreExplorationFrom.add(value.adjNode);
305
345
306
- // update PQ with new entries
307
- if (!prioQueueOpenSetFrom .isEmpty ()) {
308
- final PriorityQueue <AStarEntry > tmpFrom = new PriorityQueue <>(prioQueueOpenSetFrom .size ());
309
- tmpFrom .addAll (prioQueueOpenSetFrom );
310
- prioQueueOpenSetFrom = tmpFrom ;
346
+ pqOpenSetFrom .add (value );
347
+ }
311
348
}
312
349
}
313
350
314
351
if (backward ) {
315
- ignoreExplorationTo . ensureCapacity ( bestWeightMapTo . size ());
316
- bestWeightMapTo . forEach (new IntObjectPredicate < AStarEntry >() {
317
- @ Override
318
- public boolean apply ( int key , AStarEntry value ) {
352
+ if (! pqOpenSetTo . isEmpty ()) {
353
+ AStarEntry [] entries = pqOpenSetTo . toArray (new AStarEntry [ pqOpenSetTo . size ()]);
354
+ pqOpenSetTo . clear ();
355
+ for ( AStarEntry value : entries ) {
319
356
value .weight = value .weightOfVisitedPath + weightApprox .approximate (value .adjNode , true );
320
- ignoreExplorationTo .add (key );
321
- return true ;
322
- }
323
- });
357
+ // ignoreExplorationTo.add(value.adjNode);
324
358
325
- if (!prioQueueOpenSetTo .isEmpty ()) {
326
- final PriorityQueue <AStarEntry > tmpTo = new PriorityQueue <>(prioQueueOpenSetTo .size ());
327
- tmpTo .addAll (prioQueueOpenSetTo );
328
- prioQueueOpenSetTo = tmpTo ;
359
+ pqOpenSetTo .add (value );
360
+ }
329
361
}
330
362
}
331
363
}
0 commit comments