简体   繁体   中英

Recursive graph traversal: how to generate and return all paths?

Here is my code right now:

  hasht= {"A":["B", "D", "E"], "B":["C"], "C":["D", "E"], "D":["C", "E"], "E":["B"]}
   paths=[]
   def recusive(start, finish, val):
      if start==finish and val!=1:
        return start
    else:
        for i in hasht[start]:
            path= start+ recusive(i,finish,2)
            paths.append(path)
print (recusive("C","C",1))
print paths

Desired output: [CDC, CDEBC, CEBC]

I am trying to generate a table like the one above, but I am running into a problem where the string and the array are not being concatenated. When I just return, it returns CDC and works however and it exits the function as return is meant to do. I am wondering how I can improve my code here to make it work and figure out why my logic was faulty. For example, I understand that it generates say [DC] , but I am confused as to how to go around that. Perhaps index the value returned? Yet that doesn't work either! I am just confused as to how to make the path return once it is CDC , and then move on to the next one.

You need to be a little careful when using recursion in Python, as the pre-set limit on recursion depth is quite low, and you'll start getting errors like RuntimeError: maximum recursion depth exceeded in cmp if you recurse too deeply.

When I try to run your code, I get an error: TypeError: cannot concatenate 'str' and 'NoneType' objects . This is because the function only returns a value when start == finish , ie when you get to 'C' again, in your example. Because there is no return in the else part of the function, it returns the special value None , if start != end. Python won't let you add None to a string, which explains the error.

The code below does what I think you're trying to do, which is return a list of all paths from startNode to endNode . I've made the graph an input argument here, and the list of paths is returned. It takes 2 additional arguments, allPaths and pathSoFar , to keep track of the list of all paths, and the current path. This is only intended as an example of how to use recursion to achieve this. There are several things wrong with this code:

1) It uses recursion which, as I said earlier, is not a great idea in Python unless you increase the pre-set limit.

2) It does not deal properly with cycles. If there are cycles in the graph, this function will just keep on going until it hits the recursion limit. Try running it with A as the start and end node to see this.

    def generatePaths(theGraph, startNode, endNode, allPaths, pathSoFar=""):
        """
        Recursive function. Finds all paths through the specified
        graph from start node to end node. For cyclical paths, this stops
        at the end of the first cycle.
        """
        pathSoFar = pathSoFar + startNode

        for node in theGraph[startNode]:

            if node == endNode:
                allPaths.append(pathSoFar + node)
            else:
                generatePaths(theGraph, node, endNode, allPaths, pathSoFar)




    graph = {"A":["B", "D", "E"], "B":["C"], "C":["D", "E"], "D":["C", "E"], "E":["B"]}
    paths = []
    generatePaths(graph, "C", "C", paths)
    print paths

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