I am looking for a way to find a loopless path (preferably shortest path, but not necessarily though) from a source vertex (S) to a destination vertex (D) that passes through another specific vertex (X) somewhere in the graph.
Now, before you point me to Finding shortest path between pass through a specific vertex I want to say that this solution ignores the case when the shortest path from S to X already includes D, which is a possible scenario in where I am applying this algorithm. How would you solve this problem in that case?
What I tried was a naive attempt to look for such paths in the results of Yen's K shortest paths algorithm. But I am hoping there is a more efficient and certain way to do that.
Again, just to point it out, I am not necessarily looking for the shortest path from S to D through X, but just any loopless path, although shortest path would do better.
The basic concept is quite simple; then you get to adapt for cases that loop into and out of X
on their shortest remaining paths.
D
from the graph.P1
, the shortest path from S
to X
.D
to the graph.P1
.P2
, the shortest path from X
to D
.P1
+ P2
.That's the gist of the solution.
NOTE: you may find that removing P1
yields a sub-graph with no remaining path to D. In this case, you will want a dynamic programming solution that searches through the idea above, but with backtracking and another method to search for P1
candidates.
When you first find P1
, check that the node you're about to use will not isolate X
from D
on the second leg of the trip. This will give you a much faster search algorithm.
Is that enough of a start?
The need to adapt comes from a case such as this -- consider the graph
src dst
S 1, 2
1 X, D
2 D
X 1
Your partial paths are
S -> 1 -> X
S -> 2 -> 3 -> X
X -> 1 -> D
and, incidentally,
S -> 1 -> D
When you run your shortest-path searches, you get the path S 1 X 1 D
, rejected because of the loop. When you implement my first modification -- remove node 1
when trying to find a path X to D
, there is no remaining path.
The algorithm needs the ability to back up, rejecting the path X 1 D
to find X 2 3 D
. That's the coding that isn't immediately obvious from the description.
Here's a mental exercise for you: is it possible to construct a graph in which each shortest path (S to X
and X to D
) isolates the other terminal node from X
? In my example above, you can simply switch the process: when the S to X
path isolates D
, then start over: first find X to D
, remove node 1
, and then find S to X
in the remaining graph.
Can you find a graph where this switch doesn't work, either?
If not, you have an immediate solution. If so, you have a more complex case to handle.