Here are a few algorithms that I found on the Internet to search for all possible paths on a chart. They do not change Dijkstra's algorithm, but I think that they should still do what you want.
From https://mathoverflow.net/questions/18603/finding-all-paths-on-undirected-graph :
Suresh proposed DFS, the MRA indicated that it is not clear what works. Here is my attempt at resolving after this comment stream. If the graph has m edges, n nodes and p paths from source s to the target t, then the algorithm below prints all the paths in time O ((np + 1) (m + n)). (In particular, it takes O (m + n) time to notice that there is no way.)
The idea is very simple: do an exhaustive search, but the guarantee is early if you are in a corner.
Without an early start, the MRA counter-example shows that an exhaustive search spends time Ξ© (n!), Even if p = 1: node t has only one adjacent edge, and its neighbor is node s, which is part of the complete (sub) graph Kn -one.
Press s on the stack stack and search:
path // is a stack (initially empty) seen // is a set def stuck(x) if x == t return False for each neighbor y of x if y not in seen insert y in seen if !stuck(y) return False return True def search(x) if x == t print path seen = set(path) if stuck(x) return for each neighbor y of x push y on the path search(y) pop y from the path
Here the search is exhaustive search and stuck can be implemented in the style of DFS (as here) or in the style of BFS.
From All possible paths in a cyclic undirected graph :
You can find all the paths using DFS, as described by Vlad. To find which nodes appear in each path, you can simply save an array of logic elements that says that each node has appeared in each path so far. When your DFS finds a path, go through each vertex out of the path and set the corresponding array value to false. When you're done, only the vertices with true values ββwill be the ones that appear on every path.
pseudo code:
int source; int sink; int nVerts; bool inAllPaths[nVerts]; // init to all true bool visited[nVerts]; // init to all false stack<int> path; // init empty bool dfs(int u) if (visited[u]) return; if (u == sink) for i = 0 to nVerts-1 if !stack.contains(i) inAllPaths[i] = false; return true; else visited[u] = true; stack.push(u); foreach edge (u, v) dfs(v); stack.pop(); visited[u] = false; return false; main() dfs(source); // inAllPaths contains true at vertices that exist in all paths // from source to sink.
However, this algorithm is not very efficient. For example, in a full graph, there are n vertices (all vertices have edges for all others), the number of paths will be n! (n factorial).
The best algorithm would be to check for each vertex in each path separately. For each vertex, try to find the path from the source to the sink without going to that vertex. If you cannot find one, this is because a vertex appears on every path.
pseudo code:
// Using the same initialisation as above, but with a slight modification // to dfs: change the foreach loop to foreach edge (u, v) if (dfs(v)) return true; // exit as soon as we find a path main() for i = 0 to nVerts-1 set all visited to false; if (inAllPaths[i]) visited[i] = true; if (dfs(source)) inAllPaths[i] = false; visited[i] = false;
Unfortunately, this still has the exponential worst case finding path. You can fix this by changing the search to a width search. If I'm not mistaken, this should give you O (VE) performance.
Some other articles discussing the issue:
algorithm for listing all possible paths
Find all the paths between two nodes of the graph