用Python从迷宫中找到出路

用Python从迷宫中找到出路,python,recursion,backtracking,maze,Python,Recursion,Backtracking,Maze,问题是要找到迷宫的出口。我找不到此代码中的错误。 迷宫编码:1-坑或墙,这取决于,0-高速公路,2,3-参观领域。南-南向下,东-东-左,北-北向上,西-西-左。lepes是执行递归移动的主要函数。x-活动移动的水平坐标,y-垂直坐标。顺便说一下,迷宫的长度是12 x 12,由坑壁包围,默认为1。真正的操场是一个10 x 10的场地。所有访问的移动都存储在列表s中,最初为s=[]。变量实验室存储迷宫。 我只是想找到走出迷宫的路。我用Python编写了以下代码: def lepes(x, y, l

问题是要找到迷宫的出口。我找不到此代码中的错误。 迷宫编码:1-坑或墙,这取决于,0-高速公路,2,3-参观领域。南-南向下,东-东-左,北-北向上,西-西-左。lepes是执行递归移动的主要函数。x-活动移动的水平坐标,y-垂直坐标。顺便说一下,迷宫的长度是12 x 12,由坑壁包围,默认为1。真正的操场是一个10 x 10的场地。所有访问的移动都存储在列表s中,最初为s=[]。变量实验室存储迷宫。 我只是想找到走出迷宫的路。我用Python编写了以下代码:

def lepes(x, y, lab, s):
    if x != 10 and y !=10:
        # step forward... 
        lab[x][y] = 3
        # can I move down?
        if x < 11 and lab[x+1][y] == 0 :
            s.append("S")
            lepes(x+1, y, lab, s)
        # can I move right?
        if y < 11 and lab[x][y+1] == 0:
            s.append("E")
            lepes(x, y+1, lab, s)
        # can I move up?
        if x > 0 and lab[x-1][y] == 0:
            s.append("N")
            lepes(x-1, y, lab, s)        
        # can I move left?
        if y > 0 and lab[x][y-1] == 0:
            s.append("W")
            lepes(x, y-1, lab, s)
        #   step back...
        #   mark as visited
        #lab[x][y] = 2
        s.append("")
        #s.pop()
    else:
        # The goal is reached, and last step forward...
        lab[x][y] = 3
        return
        # last step back 
        lab[x][y] = 2   
解的最终形式:.joins 我有这个:

s=SSSSSSSSS EESESESESEEENEEENEEWNEEENEEWWW

我应该有这样的东西:

s=SSSSS EENNEESSWWWWSSEESS


黄色是起点,绿色是目标。

您的if语句不是排他性的。在每个块中,您递归地调用函数,但当递归调用返回时,执行将继续进行,并且可以进入同一位置的其他块之一


您可以通过将它们更改为elif来解决这个问题,但我个人不认为递归是这里的最佳解决方案,除非您明确尝试以函数式方式编程:最好在顶部使用while循环,并在if的每个分支内更新x和y。

您的if语句不是独占的。在每个块中,您递归地调用函数,但当递归调用返回时,执行将继续进行,并且可以进入同一位置的其他块之一


您可以通过将它们更改为elif来解决这个问题,但我个人不认为递归是这里的最佳解决方案,除非您明确尝试以函数式方式编程:最好在顶部使用while循环,并在if的每个分支内更新x和y。

如果您正在寻找最短路径,我建议如下:

将迷宫转换为具有以下属性的加权图:

顶点集是所有可通过的正方形的集

边的集合是相邻可通过正方形的所有元组的集合

每条边的重量为1

在这之后,让Dijkstra先生或A为你做这项工作

我能找到的最短路径是sss-eeseeeess

下面是我找到它的快速而肮脏的代码:

#! /usr/bin/python3

lab = [[1,1,1,1,1,1,1,1,1,1,1,1],[1,0,0,0,0,0,0,0,0,0,0,1],[1,0,1,1,1,1,1,1,0,1,1,1],[1,0,1,0,0,0,0,0,0,0,0,1],[1,0,1,0,1,1,1,1,1,1,0,1],[1,0,1,0,1,0,0,0,0,0,0,1],[1,0,0,0,1,1,0,1,1,1,0,1],[1,0,1,0,0,0,0,1,0,1,1,1],[1,0,1,1,0,1,0,0,0,0,0,1],[1,0,1,0,0,1,1,1,1,1,0,1],[1,0,0,0,1,1,0,0,0,0,0,1],[1,1,1,1,1,1,1,1,1,1,1,1]]

class Node:
    def __init__ (self, x, y):
        self.x = x
        self.y = y
        self.neighbours = [ (x + xoff, y + yoff) for xoff, yoff in
            ( (1, 0), (0, 1), (0, -1), (-1, 0) )
            if not lab [y + yoff] [x + xoff] ]
        self.distance = ...
        self.path = ...
        self.visited = False

    def __repr__ (self):
        return '{}: ({})'.format ( (self.x, self.y), self.neighbours)

nodes = {}
for y in range (12):
    for x in range (12):
        if lab [y] [x]: continue
        nodes [x, y] = Node (x, y)

current = nodes [1, 1]
current.distance = 0
current.path = []
unvisited = set (nodes.keys () )

while True:
    dist = current.distance + 1
    for nx, ny in current.neighbours:
        if (nx, ny) not in unvisited: continue
        neighbour = nodes [nx, ny]
        if neighbour.distance is ... or neighbour.distance > dist:
            neighbour.distance = dist
            neighbour.path = current.path + [ (current.x, current.y) ]
    current.visited = True
    unvisited.remove ( (current.x, current.y) )
    if not unvisited: break
    current = sorted ( [node for node in nodes.values ()
        if not node.visited and node.distance is not ...],
        key = lambda node: node.distance) [0]

print (nodes [10, 10].path)
path = nodes [10, 10].path + [ (10, 10) ]
for (ax, ay), (bx, by) in zip (path, path [1:] ):
    if ax == bx and ay > by: print ('N', end = '')
    if ax == bx and ay < by: print ('S', end = '')
    if ay == by and ax > bx: print ('W', end = '')
    if ay == by and ax < bx: print ('E', end = '')
print ()
或者,如果从右上角开始,结果是:

[(10, 1), (9, 1), (8, 1), (8, 2), (8, 3), (9, 3), (10, 3), (10, 4), (10, 5), (9, 5), (8, 5), (7, 5), (6, 5), (6, 6), (6, 7), (6, 8), (7, 8), (8, 8), (9, 8), (10, 8), (10, 9)]
WWSSEESSWWWWSSSEEEESS

如果您正在寻找最短路径,我建议您:

将迷宫转换为具有以下属性的加权图:

顶点集是所有可通过的正方形的集

边的集合是相邻可通过正方形的所有元组的集合

每条边的重量为1

在这之后,让Dijkstra先生或A为你做这项工作

我能找到的最短路径是sss-eeseeeess

下面是我找到它的快速而肮脏的代码:

#! /usr/bin/python3

lab = [[1,1,1,1,1,1,1,1,1,1,1,1],[1,0,0,0,0,0,0,0,0,0,0,1],[1,0,1,1,1,1,1,1,0,1,1,1],[1,0,1,0,0,0,0,0,0,0,0,1],[1,0,1,0,1,1,1,1,1,1,0,1],[1,0,1,0,1,0,0,0,0,0,0,1],[1,0,0,0,1,1,0,1,1,1,0,1],[1,0,1,0,0,0,0,1,0,1,1,1],[1,0,1,1,0,1,0,0,0,0,0,1],[1,0,1,0,0,1,1,1,1,1,0,1],[1,0,0,0,1,1,0,0,0,0,0,1],[1,1,1,1,1,1,1,1,1,1,1,1]]

class Node:
    def __init__ (self, x, y):
        self.x = x
        self.y = y
        self.neighbours = [ (x + xoff, y + yoff) for xoff, yoff in
            ( (1, 0), (0, 1), (0, -1), (-1, 0) )
            if not lab [y + yoff] [x + xoff] ]
        self.distance = ...
        self.path = ...
        self.visited = False

    def __repr__ (self):
        return '{}: ({})'.format ( (self.x, self.y), self.neighbours)

nodes = {}
for y in range (12):
    for x in range (12):
        if lab [y] [x]: continue
        nodes [x, y] = Node (x, y)

current = nodes [1, 1]
current.distance = 0
current.path = []
unvisited = set (nodes.keys () )

while True:
    dist = current.distance + 1
    for nx, ny in current.neighbours:
        if (nx, ny) not in unvisited: continue
        neighbour = nodes [nx, ny]
        if neighbour.distance is ... or neighbour.distance > dist:
            neighbour.distance = dist
            neighbour.path = current.path + [ (current.x, current.y) ]
    current.visited = True
    unvisited.remove ( (current.x, current.y) )
    if not unvisited: break
    current = sorted ( [node for node in nodes.values ()
        if not node.visited and node.distance is not ...],
        key = lambda node: node.distance) [0]

print (nodes [10, 10].path)
path = nodes [10, 10].path + [ (10, 10) ]
for (ax, ay), (bx, by) in zip (path, path [1:] ):
    if ax == bx and ay > by: print ('N', end = '')
    if ax == bx and ay < by: print ('S', end = '')
    if ay == by and ax > bx: print ('W', end = '')
    if ay == by and ax < bx: print ('E', end = '')
print ()
或者,如果从右上角开始,结果是:

[(10, 1), (9, 1), (8, 1), (8, 2), (8, 3), (9, 3), (10, 3), (10, 4), (10, 5), (9, 5), (8, 5), (7, 5), (6, 5), (6, 6), (6, 7), (6, 8), (7, 8), (8, 8), (9, 8), (10, 8), (10, 9)]
WWSSEESSWWWWSSSEEEESS

也许一张图表会有帮助好吧,@mhlester。给你迷宫。这可能会有帮助吗?首先,由于您总是从测试南方开始,所以您的预期结果是错误的,应该是错误的SSSSSSSSSEENNENNEESEEEESS@beistvan请查看对我答案的编辑,显示如何找到更短的路径。@Hyperboreus我现在正在查看它。也许一个图表会有帮助好的,@mhlester。给你迷宫。这可能会有帮助吗?首先,由于您总是从测试南方开始,所以您的预期结果是错误的,应该是错误的SSSSSSSSSEENNENNEESEEEESS@beistvan请看我答案的编辑,显示如何找到更短的路径。@Hyperboreus我现在正在查看。这是一种回溯算法,但在第二个角点之后的某个点,它在坑内向右转弯,而不是向上转弯到自由通道。这是一种回溯算法,但在第二个角点之后的某个点,它在坑内向右转弯,而不是向上转弯到自由通道。