【问题标题】:Backtracking in a recursive maze; python在递归迷宫中回溯; Python
【发布时间】:2020-04-01 02:06:24
【问题描述】:

我正在编写一个迷宫求解算法,一旦你撞到“墙”,我就会遇到回溯问题

到目前为止,我的代码检查了一些基本的递归情况,例如我是否已经到达终点或是否检查了所有点。我也这样做了,以便有一个列表可以跟踪解决方案“路径”并相应地添加和删除点。因此,每次添加一个点时,它都会检查其是否有效并检查该点,上、左、右、下等。如果没有一个有效,则执行此语句

    else:
    path.pop()
    return solve_maze(maze,path,end) 

这将删除点和回溯,并在函数开头检查以下条件。

square = list(path[-1])

#Base Case

if end in path:
    return True

elif square == None:
    return False

elif maze[square[0]][square[1]] == "X":
    path.pop()
    return solve_maze(maze,path,end)

elif tuple(square) in path:
    path.pop()
    return solve_maze(maze,path,end)

但是,当我执行最后一行时,它只会删除路径中的所有点,并且出现索引错误。

对于遇到死胡同后如何回溯有什么建议吗?

【问题讨论】:

  • 如果你想逃离迷宫你只需要选择一堵墙并跟随它,你不需要递归
  • 要求这样做的方式是递归;一旦撞到墙,就必须回溯
  • 您能否提供整个功能、输入/输出示例以及您的解决方案失败的地方?您提供给我们的详细信息基本上很难帮助您
  • 这个过程的通用(谷歌)名称是深度优先搜索。

标签: python if-statement recursion maze recursive-backtracking


【解决方案1】:

这是一个被大量评论的解决方案:

def backtrack(i,j):
   # if matrix[i][j] is visited, then do nothing
   # if it is a wall, then do not insert it in the path from the first place
   if visit[i][j] != 0 or matrix[i][j] == 'X':
      return
   # mark the index as visited as to not visit it again
   visit[i][j] = 1
   # add the index to the path
   path.append((i,j))
   # if it is the GOAL, then store this path somewhere, 
   # and pop the last index to traverse other paths that reaches the GOAL
   if matrix[i][j] == 'G':
      # any paths that reach the GOAL are appended here
      ans.append(list(path))
      path.pop()
      return
   # loop on the neighbors. if they are valid indices, do the same work again
   for k in range(3):
      nwi = i + row[k]
      nwj = j + col[k]
      if valid(nwi, nwj):
         backtrack(nwi, nwj)
   # after finishing this index, just pop because we do not need it any more
   path.pop()
   return

def valid(i,j):
   return (i >= 0 and i <=2) and (j >= 0 and j <= 2)

# just a dummy matrix to start with
matrix = [['.', '.', '.'], ['.', 'X', '.'], ['.', 'G', 'X']]
# an array that marks indices as visited or not
visit = [[0,0,0],[0,0,0],[0,0,0]]
# the path that is used in the back tracking
path = []
# this will be a list of lists containing ALL the paths that can reach the GOAL
ans = []
# these are the neighbors indices
row = [-1, 1, 0, 0]
col = [0, 0, 1, -1]

backtrack(0,0)

if len(ans) == 0: 
   print("no path found!")
else:
   print(ans)

我的解决方案将在名为 ans 的列表列表中为您提供可以到达目标的所有路径。如果 ans 的长度为零,则找不到路径。

如果您对代码中写的 cmets 不理解或有任何困惑,请不要犹豫,发表评论,我会回复。

注意:(编辑)

我假设了迷宫的起始状态和函数内容本身,因为您没有提供任何测试用例或完整的函数本身。

【讨论】: