迷宫解决Python

时间:2016-03-22 22:38:48

标签: python solver maze

我已经不知疲倦地尝试在python中制作一个迷宫求解器。我使用了所有资源,如朋友,互联网和堆栈。我已经从我之前的堆栈问题中调整了很多代码,但是即使完全复制代码(我不喜欢这样做),仍然无法得到答案。

迷宫/输入文件(嵌套列表):

    [['*', '*', '*', '*', '*'],
    ['*', ' ', '*', ' ', '*'],
    ['*', ' ', ' ', ' ', '*'],
    ['*', ' ', '*', ' ', 'E'],
    ['*', 'S', '*', '*', '*']]

此功能在迷宫中的相同点上循环。我的起点" S"是(4,1),输出:

(4,1)
(4,0)
(3,1)

上面的输出来自我用来调试函数的print语句。它只是按顺序打印上面的内容,直到它达到递归限制。下面是我的求解函数:

already_visited=[]
def solve(x,y):
    global already_visited
    matrix = draw(load())
    print (x,y)

    #base cases
    if matrix[x][y] == "E":
        for row in matrix:
            row = str(row)[1:-1]
            print row
        return True
    if matrix[x][y] == "*":
        return False
    if matrix[x][y] == "x":
        return False

    matrix[x][y] = "x"

    #---------------------
    if (x,y) in already_visited: #check if we have already been here
        return False

    already_visited.append((x,y)) #add position to list
    #---------------------


    # recursive cases (matrix traversal)
    if (x < len(matrix)-1 and solve1(x+1,y)):
        return True
    elif (y > 0 and solve1(x,y-1)):
        return True
    elif (x > 0 and solve1(x-1,y)):
        return True
    elif (y < len(matrix)-1 and solve1(x,y+1)):
        return True
    else:
        return False

所有我进入xy的函数都是起始索引S,如上面发布的迷宫中所示。非常感谢任何帮助!

3 个答案:

答案 0 :(得分:0)

此处的代码不起作用:

if (x < len(matrix)-1 and solve1(x+1,y)):
        return True
    elif (y > 0 and solve1(x,y-1)):
        return True
    elif (x > 0 and solve1(x-1,y)):
        return True
    elif (y < len(matrix)-1 and solve1(x,y+1)):
        return True
    else:
        return False

问题在于递归。您的计划的作用是:

  1. 如果可能,请右转
  2. 如果没有尝试
  3. 如果没有尝试离开
  4. 如果没有尝试下来
  5. 由于你以递归方式进行,所以你的程序会一直运行到墙上,

    然后上去,直到撞墙,

    然后离开,

    然后下来。

    这样可以很容易地在圈子中运行。

    所以,就我所见,你有两个简单的可能性:

    1. 请记住,如果您访问了某个位置,并且在递归中总是返回False,如果您已经来过这里
    2. 随机运行
    3. 1号看起来像这样:

      already_visited=[]
      def solve1(x,y):
          global already_visited
          matrix = draw(load())
          print (x,y)
      
          #base cases
          if matrix[x][y] == "E":
              for row in matrix:
                  row = str(row)[1:-1]
                  print row
              return True
          if matrix[x][y] == "*":
              return False
          if matrix[x][y] == "x":
              return False
      
          matrix[x][y] = "x"
      
          #---------------------
          if (x,y) in already_visited: #check if we have already been here
              return False
      
          already_visited.append((x,y)) #add position to list
          #---------------------
      
      
          # recursive cases (matrix traversal)
          if (x < len(matrix)-1 and solve1(x+1,y)):
              return True
          elif (y > 0 and solve1(x,y-1)):
              return True
          elif (x > 0 and solve1(x-1,y)):
              return True
          elif (y < len(matrix)-1 and solve1(x,y+1)):
              return True
          else:
              return False
      

答案 1 :(得分:0)

使用正确的约束检查替换函数的开头使其无法进入IndexError。首先,您需要确保x在矩阵行数的范围内。然后,您需要检查相同的列数。这里len()给出的值是第一个超出范围。

此外,您在解算器的每次调用中重新加载矩阵。您应该只对一个矩阵进行操作以进行持久更改。为此,将其添加为函数的参数:

def solve2(matrix,x,y):
    print (x,y)
    if x >= len(matrix) or y >= len(matrix[x]):
        return False
    [...]

然后在第一次运行时将其称为solve2(draw(load()),4,1),并将每个递归调用替换为等效的solve2(matrix,x,y-1))。同样适用于solve1()

答案 2 :(得分:0)

制作迷宫很容易。你首先制作一个网格。

import networkx as nx
import numpy as np

G = nx.Graph()
for i in range(5):
    for j in range(5):
        G.add_node((i,j))
        if i >0:
            G.add_edge((i-1,j),(i,j))
        if j>0:
            G.add_edge((i,j),(i,j-1))

然后删除留下路径节点的墙。

a = np.array([['*', '*', '*', '*', '*'],
       ['*', ' ', '*', ' ', '*'],
       ['*', ' ', ' ', ' ', '*'],
       ['*', ' ', '*', ' ', 'E'],
       ['*', 'S', '*', '*', '*']])

for i in range(5):
    for j in range(5):
        if a[i][j]=='*':
            G.remove_node((i,j))

我在作弊并且处于开始和结束位置。但后来我让NetworkX从头到尾找到路径。

for point in nx.algorithms.astar_path(G,(4,1),(3,4)):
    print(point)