Runtime Error in python: “Maximum recursion depth exceeded”

∥☆過路亽.° 提交于 2021-02-19 06:16:31

问题


I have a program that searches through a 2D list that represents a maze like so:

####################################
#S#  ##  ######## # #      #     # #
# #   #             # #        #   #
#   # ##### ## ###### # #######  # #
### # ##    ##      # # #     #### #
#   #    #  #######   #   ###    #E#
####################################

I understand what a recursion error is but I don't know why this code causes it as it should simply lead to finding the "E". Does anyone know how this possibly generates the error?

def solve(x,y):
    mazeList = loadMaze("sample.maze")    

    if mazeList[y][x] == "E":
        return "YOU'VE SOLVED THE MAZE!"
    elif mazeList[y][x+1] == " ":  #right
        mazeList[y][x+1] = ">"
        solve(x+1,y)
    elif mazeList[y+1][x] == " ":  #down
        mazeList[y+1][x] = "v"
        solve(x,y+1)    
    elif mazeList[y][x-1] == " ":  #left
        mazeList[y][x-1] = "<"
        solve(x-1,y)    
    elif mazeList[y-1][x] == " ":  #up
        mazeList[y-1][x] = "^"
        solve(x,y-1)    

回答1:


You re-load mazeList each time you call the function.

So at the start of solve() you are right back at the starting conditions, and you end up running in circles.

Use a keyword argument to pass mazeList on to recursive calls, default it to None and only load the maze when it is still None:

def solve(x, y, mazeList=None):
    if mazeList is None:
        mazeList = loadMaze("sample.maze")

and pass mazeList to recursive calls.

Next problem is that you never return recursive calls; when you call solve() from within solve() you still need to return its result:

def solve(x, y, mazeList=None):
    if mazeList is None:
        mazeList = loadMaze("sample.maze")

    if mazeList[y][x] == "E":
        return "YOU'VE SOLVED THE MAZE!"
    elif mazeList[y][x+1] == " ":  #right
        mazeList[y][x+1] = ">"
        return solve(x+1,y,mazeList)
    elif mazeList[y+1][x] == " ":  #down
        mazeList[y+1][x] = "v"
        return solve(x,y+1,mazeList)    
    elif mazeList[y][x-1] == " ":  #left
        mazeList[y][x-1] = "<"
        return solve(x-1,y,mazeList)    
    elif mazeList[y-1][x] == " ":  #up
        mazeList[y-1][x] = "^"
        return solve(x,y-1,mazeList)    

You'd still paint yourself in a corner with this technique; to recursively solve a maze, you need to try all paths, not just one, and give each recursive call a copy of the maze with the one chosen path marked out only.

You also always test for the next cell, but never take into account that that next cell could be the goal; you never move onto E because that cell is not equal to ' ', so it's not a move candidate.

The following version can solve your maze:

directions = (
    (1, 0, '>'),
    (0, 1, 'v'),
    (-1, 0, '<'),
    (0, -1, '^'),
)

def solve(x, y, mazeList=None):
    if mazeList is None:
        mazeList = loadMaze("sample.maze")

    for dx, dy, char in directions:
        nx, ny = x + dx, y + dy

        if mazeList[ny][nx] == "E":
            return "YOU'VE SOLVED THE MAZE!"

        if mazeList[ny][nx] == " ":
            new_maze = [m[:] for m in mazeList]
            new_maze[ny][nx] = char
            result = solve(nx, ny, new_maze)
            if result is not None:
                return result

Testing for each direction separately was getting tedious, so I replaced that with a loop over a sequence of directions instead; each tuple is a change in x, in y and the character to use when moving in that direction.

Demo, with printout of the solved maze:

>>> def loadMaze(ignored):
...     maze = '''\
... ####################################
... #S#  ##  ######## # #      #     # #
... # #   #             # #        #   #
... #   # ##### ## ###### # #######  # #
... ### # ##    ##      # # #     #### #
... #   #    #  #######   #   ###    #E#
... ####################################
... '''
...     return [list(m) for m in maze.splitlines()]
... 
>>> directions = (
...     (1, 0, '>'),
...     (0, 1, 'v'),
...     (-1, 0, '<'),
...     (0, -1, '^'),
... )
>>> 
>>> def solve(x, y, mazeList=None):
...     if mazeList is None:
...         mazeList = loadMaze("sample.maze")   
...     for dx, dy, char in directions:
...         nx, ny = x + dx, y + dy
...         if mazeList[ny][nx] == "E":
...             print '\n'.join([''.join(m) for m in mazeList])
...             return "YOU'VE SOLVED THE MAZE!"
...         if mazeList[ny][nx] == " ":
...             new_maze = [m[:] for m in mazeList]
...             new_maze[ny][nx] = char
...             result = solve(nx, ny, new_maze)
...             if result is not None:
...                 return result
... 
>>> solve(1, 1)
####################################
#S#  ##  ######## # #^>>>>>#  ^>># #
#v#^>>#    ^>>>     #^#   v>>>>#v>>#
#v>>#v#####^##v######^# #######  #v#
### #v##^>>>##v>>>>>#^# #     ####v#
#   #v>>>#  #######v>>#   ###    #E#
####################################
"YOU'VE SOLVED THE MAZE!"


来源:https://stackoverflow.com/questions/22717248/runtime-error-in-python-maximum-recursion-depth-exceeded

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!