Skip to content

Commit f3d8bd5

Browse files
committed
Concatenate edge-based paths properly for alternatives, fixes graphhopper#2101
1 parent 6922bbe commit f3d8bd5

File tree

2 files changed

+19
-20
lines changed

2 files changed

+19
-20
lines changed

core/src/main/java/com/graphhopper/routing/AlternativeRouteEdgeCH.java

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ List<AlternativeInfo> calcAlternatives(final int s, final int t) {
109109
PotentialAlternativeInfo potentialAlternativeInfo = new PotentialAlternativeInfo();
110110
potentialAlternativeInfo.v = fromSPTEntry.adjNode;
111111
potentialAlternativeInfo.edgeIn = getIncomingEdge(fromSPTEntry);
112-
potentialAlternativeInfo.edgeOut = getIncomingEdge(toSPTEntry);
113112
potentialAlternativeInfo.weight = 2 * (fromSPTEntry.getWeightOfVisitedPath() + toSPTEntry.getWeightOfVisitedPath()) + preliminaryShare;
114113
potentialAlternativeInfos.add(potentialAlternativeInfo);
115114
return true;
@@ -120,17 +119,18 @@ List<AlternativeInfo> calcAlternatives(final int s, final int t) {
120119
for (PotentialAlternativeInfo potentialAlternativeInfo : potentialAlternativeInfos) {
121120
int v = potentialAlternativeInfo.v;
122121
int tailSv = potentialAlternativeInfo.edgeIn;
123-
int headVt = potentialAlternativeInfo.edgeOut;
124122

125123
// Okay, now we want the s -> v -> t shortest via-path, so we route s -> v and v -> t
126124
// and glue them together.
127125
DijkstraBidirectionEdgeCHNoSOD svRouter = new DijkstraBidirectionEdgeCHNoSOD(graph);
128-
final Path svPath = svRouter.calcPath(s, v, ANY_EDGE, tailSv);
126+
final Path suvPath = svRouter.calcPath(s, v, ANY_EDGE, tailSv);
129127
extraVisitedNodes += svRouter.getVisitedNodes();
130128

129+
int u = graph.getBaseGraph().getEdgeIteratorState(tailSv, v).getBaseNode();
130+
131131
DijkstraBidirectionEdgeCHNoSOD vtRouter = new DijkstraBidirectionEdgeCHNoSOD(graph);
132-
final Path vtPath = vtRouter.calcPath(v, t, headVt, ANY_EDGE);
133-
Path path = concat(graph.getBaseGraph(), svPath, vtPath);
132+
final Path uvtPath = vtRouter.calcPath(u, t, tailSv, ANY_EDGE);
133+
Path path = concat(graph.getBaseGraph(), suvPath, uvtPath);
134134
extraVisitedNodes += vtRouter.getVisitedNodes();
135135

136136
double sharedDistanceWithShortest = sharedDistanceWithShortest(path);
@@ -148,7 +148,7 @@ List<AlternativeInfo> calcAlternatives(final int s, final int t) {
148148
// This is the final test we need: Discard paths that are not "locally shortest" around v.
149149
// So move a couple of nodes to the left and right from v on our path,
150150
// route, and check if v is on the shortest path.
151-
final IntIndexedContainer svNodes = svPath.calcNodes();
151+
final IntIndexedContainer svNodes = suvPath.calcNodes();
152152
int vIndex = svNodes.size() - 1;
153153
if (!tTest(path, vIndex))
154154
continue;
@@ -236,21 +236,21 @@ private EdgeIteratorState getNextNodeTMetersAway(Path path, int vIndex, double T
236236
return edges.get(i - 1);
237237
}
238238

239-
private static Path concat(Graph graph, Path svPath, Path vtPath) {
240-
assert svPath.isFound();
241-
assert vtPath.isFound();
239+
private static Path concat(Graph graph, Path suvPath, Path uvtPath) {
240+
assert suvPath.isFound();
241+
assert uvtPath.isFound();
242242
Path path = new Path(graph);
243-
path.setFromNode(svPath.calcNodes().get(0));
244-
for (EdgeIteratorState edge : svPath.calcEdges()) {
245-
path.addEdge(edge.getEdge());
246-
}
247-
for (EdgeIteratorState edge : vtPath.calcEdges()) {
243+
path.setFromNode(suvPath.calcNodes().get(0));
244+
for (EdgeIteratorState edge : suvPath.calcEdges()) {
248245
path.addEdge(edge.getEdge());
249246
}
250-
path.setEndNode(vtPath.getEndNode());
251-
path.setWeight(svPath.getWeight() + vtPath.getWeight());
252-
path.setDistance(svPath.getDistance() + vtPath.getDistance());
253-
path.addTime(svPath.time + vtPath.time);
247+
Iterator<EdgeIteratorState> uvtPathI = uvtPath.calcEdges().iterator();
248+
uvtPathI.next(); // skip u-v edge
249+
uvtPathI.forEachRemaining(edge -> path.addEdge(edge.getEdge()));
250+
path.setEndNode(uvtPath.getEndNode());
251+
path.setWeight(suvPath.getWeight() + uvtPath.getWeight());
252+
path.setDistance(suvPath.getDistance() + uvtPath.getDistance());
253+
path.addTime(suvPath.time + uvtPath.time);
254254
path.setFound(true);
255255
return path;
256256
}
@@ -271,7 +271,6 @@ public List<Path> calcPaths(int from, int to) {
271271
public static class PotentialAlternativeInfo {
272272
public int v;
273273
public int edgeIn;
274-
public int edgeOut;
275274
double weight;
276275
}
277276

core/src/test/java/com/graphhopper/routing/AlternativeRouteEdgeCHTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ public void testCalcOtherAlternatives() {
143143
List<AlternativeRouteEdgeCH.AlternativeInfo> pathInfos = altDijkstra.calcAlternatives(10, 5);
144144
assertEquals(2, pathInfos.size());
145145
assertEquals(IntArrayList.from(10, 4, 3, 6, 5), pathInfos.get(0).path.calcNodes());
146-
assertEquals(IntArrayList.from(10, 4, 3, 2, 9, 1, 5), pathInfos.get(1).path.calcNodes());
146+
assertEquals(IntArrayList.from(10, 4, 8, 7, 6, 5), pathInfos.get(1).path.calcNodes());
147147
// The shortest path works (no restrictions on the way back
148148
}
149149

0 commit comments

Comments
 (0)