Skip to content

Commit 1c0d031

Browse files
ecktermultun
authored andcommitted
core: pathfinding: reproduce edge case in a test + fix
1 parent 2b143c6 commit 1c0d031

File tree

3 files changed

+50
-24
lines changed

3 files changed

+50
-24
lines changed

core/src/main/java/fr/sncf/osrd/api/pathfinding/PathfindingBlocksEndpoint.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -323,9 +323,12 @@ private void assertPathTracksAreComplete(List<RJSDirectionalTrackRange> tracksOn
323323
while (i < tracksOnPath.size()) {
324324
var track = tracksOnPath.get(i);
325325
var trackName = track.trackSectionID;
326-
var fullTrack = new ArrayList<>(tracksOnPath.stream()
327-
.filter(trackOnPath -> Objects.equals(trackOnPath.trackSectionID, track.trackSectionID))
328-
.toList());
326+
var fullTrack = new ArrayList<RJSDirectionalTrackRange>();
327+
for (int j = i; j < tracksOnPath.size(); j++) {
328+
if (!trackName.equals(tracksOnPath.get(j).trackSectionID))
329+
break;
330+
fullTrack.add(tracksOnPath.get(j));
331+
}
329332
var fullTrackLength =
330333
toMeters(rawInfra.getTrackSectionLength(getTrackSectionFromNameOrThrow(trackName, rawInfra)));
331334

core/src/main/java/fr/sncf/osrd/utils/graph/Pathfinding.java

+22-21
Original file line numberDiff line numberDiff line change
@@ -169,28 +169,29 @@ public Result<EdgeT> runPathfinding(
169169
seen.put(step.range, step.nReachedTargets);
170170
if (hasReachedEnd(targetsOnEdges.size(), step))
171171
return buildResult(step);
172-
// Check if the next target is reached in this step
173-
for (var target : targetsOnEdges.get(step.nReachedTargets).apply(step.range.edge))
174-
if (step.range.start <= target.offset) {
175-
// Adds a new step precisely on the stop location. This ensures that we don't ignore the
176-
// distance between the start of the edge and the stop location
177-
var newRange = new EdgeRange<>(target.edge, step.range.start, target.offset);
178-
newRange = filterRange(newRange);
179-
assert newRange != null;
180-
if (newRange.end != target.offset) {
181-
// The target location is blocked by a blocked range, it can't be accessed from here
182-
continue;
172+
// Check if the next target is reached in this step, only if the step doesn't already reach a step
173+
if (step.prev == null || step.nReachedTargets == step.prev.nReachedTargets)
174+
for (var target : targetsOnEdges.get(step.nReachedTargets).apply(step.range.edge))
175+
if (step.range.start <= target.offset) {
176+
// Adds a new step precisely on the stop location. This ensures that we don't ignore the
177+
// distance between the start of the edge and the stop location
178+
var newRange = new EdgeRange<>(target.edge, step.range.start, target.offset);
179+
newRange = filterRange(newRange);
180+
assert newRange != null;
181+
if (newRange.end != target.offset) {
182+
// The target location is blocked by a blocked range, it can't be accessed from here
183+
continue;
184+
}
185+
var stepTargets = new ArrayList<>(step.targets);
186+
stepTargets.add(target);
187+
registerStep(
188+
newRange,
189+
step.prev,
190+
step.totalDistance,
191+
step.nReachedTargets + 1,
192+
stepTargets
193+
);
183194
}
184-
var stepTargets = new ArrayList<>(step.targets);
185-
stepTargets.add(target);
186-
registerStep(
187-
newRange,
188-
step.prev,
189-
step.totalDistance,
190-
step.nReachedTargets + 1,
191-
stepTargets
192-
);
193-
}
194195
var edgeLength = edgeToLength.apply(step.range.edge);
195196
if (step.range.end == edgeLength) {
196197
// We reach the end of the edge: we visit neighbors

core/src/test/java/fr/sncf/osrd/utils/graph/PathfindingTests.java

+22
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,28 @@ public void noPathTest() {
263263
assertNull(res);
264264
}
265265

266+
@Test
267+
public void noPathTestSameEdge() {
268+
/* No possible path without going backwards, with several steps on the last edge
269+
270+
0 -> B -> 1 -> 2 -> E2 -> E1 -> 3
271+
*/
272+
var builder = new SimpleGraphBuilder();
273+
builder.makeNodes(4);
274+
builder.makeEdge(0, 1, 100);
275+
builder.makeEdge(1, 2, 100);
276+
builder.makeEdge(2, 3, 100);
277+
var g = builder.build();
278+
var res = new Pathfinding<>(g)
279+
.setEdgeToLength(edge -> edge.length)
280+
.runPathfindingEdgesOnly(List.of(
281+
List.of(builder.getEdgeLocation("0-1")),
282+
List.of(builder.getEdgeLocation("2-3", 20)),
283+
List.of(builder.getEdgeLocation("2-3", 10))
284+
));
285+
assertNull(res);
286+
}
287+
266288
@Test
267289
public void sameEdgeNoPathTest() {
268290
/* The end is on the same edge but at a smaller offset that the start: no path

0 commit comments

Comments
 (0)