0

I have a jorney between A and B which has different paths to end it. The paths are defined by the initial and final kilometers:

path 0 -> (0, 10)
path 1 -> (10, 25)
path 2 -> (10, 15)
path 3 -> (15, 20)
path 4 -> (20, 30)
path 5 -> (25, 35)
path 6 -> (30, 35)
path 7 -> (35, 40)
path 8 -> (40, 50)

As you can see, there are paths that overlap. In fact, we can get the list of overlapped paths:

path 0 -> NONE
path 1 -> 2,3,4
path 2 -> 1
path 3 -> 1
path 4 -> 1,5
path 5 -> 4,6
path 6 -> 5
path 7 -> NONE
path 8 -> NONE

What I want to get is all the possible routes without overlapped paths in the route but only one should be taken. Is there an algorithm that can solve this problem? I tried to implement with recursion or with an auxiliar data structure like a stack, but I find quite difficult to obtain a list with the final possible routes, also I tried to inverse the problem and try to obtain a list of the paths discarded, which are:

route 0-2-3-4-6-7-8 -> [1,5] discarded
route 0-2-3-5-7-8 -> [1,4,6] discarded
route 0-1-6-7-8 -> [2,3,4,5] discarded
route 0-1-5-7-8 -> [2,3,4,6] discarded
RobinHood
  • 377
  • 4
  • 20

2 Answers2

0

Yes. This is a simple graph problem. Instead of looking at these as overlapping paths, realize that the milestones are disjoint nodes. For instance, if you're at milestone 20, the only forward move you can make is to 30 -- and overlap with other segments doesn't matter at all. Perhaps it works better if you think of them as airline routes to numbered cities.

You can look up the various graph traversal algorithms to choose an algorithm. This one is simple: you have only one decision point, at milestone 10. Once you make that choice, the rest of the route is determined.

Can you take it from there?

Prune
  • 76,765
  • 14
  • 60
  • 81
  • Could you write a pseudocode or give me the reference of this algorithm? I can't see how to take one route and then come back to the previous overlapping path for getting the remainder route and so on until I have all possible routes. Thank you. – RobinHood Mar 14 '17 at 22:36
  • That's generally beyond StackOverflow response. Where are you stuck on the pseudo-code for the algorithms you looked up? You should have gone through at least "graph traversal algorithm" before you posted that comment, neh? Many of those come with pseudo-code. Start with Dijkstra's algorithm and branch out from there? – Prune Mar 14 '17 at 22:53
  • Actually, I don't want a "graph traversal", what I have tried is to loop over the overlapping list and see if the current path have an overlap, if so I keep this for a new route (recursion) and keep the overlapping path to discard them in the following steps. Then when I found a path with a new overlapping path I create another route (recursion) and so on until I finish the route and get a route. Finally, I must obtain all the routes, but something is missing in my approach because I got an infinite recursion or the discarded path list doesn't update properly. Could help upload some code here? – RobinHood Mar 14 '17 at 23:13
  • Yes! If you want help with *code*, then post it in the body of a question. See [Minimal, complete, verifiable example](http://stackoverflow.com/help/mcve) to make sure you touch all the points for a properly-formed code question. – Prune Mar 14 '17 at 23:31
  • However, do note that this path-finding is isomorphic to graph traversal. – Prune Mar 14 '17 at 23:32
0

Finally, I get the code! (possibly it could be improvable):

from copy import deepcopy

discarded_overlapped = []
def overlap(overlapped,discarded):
    if all(x is None for x in overlapped):
        discarded.sort()
        if discarded not in discarded_overlapped:
            discarded_overlapped.append(discarded)
        return
    for i in range(len(overlapped)):
        if not overlapped[i] == None:
            overlapped_copy = deepcopy(overlapped)
            discarded_copy = deepcopy(discarded)
            for j in overlapped[i]:
                if j not in discarded:
                    discarded_copy.append(j)
                    overlapped_copy[j] = None
            overlapped_copy[i] = None
            overlap(overlapped_copy,discarded_copy)


Data = [None,[2,3,4],[1],[1],[1,5],[4,6],[5],None,None]
overlap(Data,[])
print(discarded_overlapped)
# [[2, 3, 4, 6], [2, 3, 4, 5], [1, 5], [1, 4, 6]]
RobinHood
  • 377
  • 4
  • 20