简体   繁体   中英

On a weighted directed graph of unknown size, how can one iterate over all possible acyclic paths between two vertices from shortest to longest?

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.)

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.

归功于nm:Wikipedia上有关K最短路径路由的文章描述了各种现代方法,包括用于Dijkstra推广的伪代码,并链接到2011年有关K *的论文,该论文也利用了启发式方法。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM