2

We can assume that all edge weights are positive, and that you can enumerate the edges leading outwards from a vertex, and likewise the edges leading inward, in O(1) time.

For example, you can perform Dijkstra traversal (or A*, with an admissible heuristic) and mark each vertex's distance from the start until you locate the end vertex, then recurse over these markings in reverse as they describe the possible predecessors on an optimal path. That is, for each possible predecessor, you can determine if it was found on the greedy optimal path if the difference between marked distances is equal to the weight of the edge that connects them.

When looking at possible predecessors, the cost of the incoming edge plus the difference between the optimal distance to each vertex is equal to the loss of optimality incurred by including this edge in a solution (zero for edges on optimal paths). So perhaps the question becomes: How can this best be extended to yield all possible paths ranked by decreasing optimality? Is there a clean way to perform a best-first traversal over this kind of meta-graph?

This seems like the right direction to go for a useful solution. Perhaps a useful thing to keep in mind is that if the part of the path you have explored so far is potentially part of a solution that is suboptimal by at least x, checking for cycles need only be done along the last x distance visited (any path suboptimal by x cannot possibly contain a cycle longer than x).

Is there a more efficient approach?

As a bonus question, is it also possible to do this on a graph (of known size) with negative edge weights? Does it become more difficult if negative cycles are introduced? (Remember, as we are looking only for acyclic paths this does not necessarily mean that the optimal solution runs away.)

Mumbleskates
  • 1,089
  • 8
  • 18

2 Answers2

0

For full graph of N nodes there are magnitude of (N-2)! possible acyclic pathes from node A to node B. Think about it... This should be huge huge number and if you only need K (big enough, but reasonable number) pathes, you better got K-shortest_path mentioned in comments.

If you can manage enough memory to hold all possible ways in it, there is obvious solution - generate all possible ways and sort them by weight. If not, you'll have to dump answers to disk and then collect them.

You can enumerate all possible ways with modified BFS - "visited" array is passed to recursive call instead of being global boolean array. When you visit destination, add it to global solutions map (key - weight, value - list of pathes with this weight).

If you cannot afford holding all pathes in memory, you can dump them to temporaty files. Naive solution for this: open file with name 0-padded up to 10 digits - or whatever fits your needs - weight, and add one line for path. After all pathes are collected, read files in appropriate order and form final result.

NB It's better not to open/append/close files if you can. You can collect pathes in map and dump only longest list when total number of pathes exceeds some limit, for example.

Alexander Anikin
  • 1,053
  • 5
  • 14
  • The key here is that the graph is of unknown size -- probably thousands of nodes, possibly an entirely unbounded graph. The goal is to be able to keep efficiently generating distinct paths, with strictly decreasing optimality, for as long as desired. So yes, turns out K-shortest-path is what I was looking for all along, and something like K* would likely be ideal. – Mumbleskates Nov 23 '16 at 05:07
0

Credit to n.m.: The Wikipedia article on K-shortest-path routing describes various modern approaches, including pseudocode for a generalization of Dijkstra, and links to a 2011 paper on K*, which also utilizes a heuristic.

Mumbleskates
  • 1,089
  • 8
  • 18