问题是找到迷宫的出口。我在这段代码中找不到错误。
迷宫编码:1 - 坑(或墙,它取决于),0 - 高速公路,2,3 - 访问的字段。 S - 南(下),E - 东(左),N - 北(上),W - 西(左)。 lepes()
是执行递归移动的主要函数。 x - 活动移动的水平,y - 垂直坐标。顺便说一下,迷宫的长度是12 x 12,被坑(墙壁,默认这意味着1)所包围。真正的游乐场是一个10 x 10的场地。所有访问的移动存储在列表s中,最初为s = []
。变量lab
存储迷宫。
我只是试图找出迷宫的出路。我在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
为了找到迷宫的出路,我试图从初始点(1,1)调用函数lepes(1, 1, lab, s)
。我必须用坐标(10,10)到达现场:
使用此初始值lab
:
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]]
最终解决方案形式:"".join(s)
我有这个:
s =“SSSSSSSSSEESSESSWSEESEEEENNNEEEEWNNNEEEEEEENNEEWWWWWW”
我应该有这样的事情:
s =“SSSSSEENNNEEEEEEESSWWWWSSSEEEESS”
黄色是起点,绿色是目标。
答案 0 :(得分:2)
如果您正在寻找最短路径,我建议如下:
将您的迷宫转换为具有以下属性的加权图:
顶点集是所有可通过的正方形的集合。
边缘集是相邻可通行方块的所有元组的集合。
每条边的重量为1。
在此之后让Dijkstra先生或A *为你做这项工作。
我能找到的最短路径是“SSSSSEESEEESEEEESS”。
这里是我发现它的快速和脏代码:
#! /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 ()
结果是:
[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 6), (3, 6), (3, 7), (4, 7), (5, 7), (6, 7), (6, 8), (7, 8), (8, 8), (9, 8), (10, 8), (10, 9)]
SSSSSEESEEESEEEESS
或者如果您在右上角开始,结果是:
[(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 :(得分:1)
您的if语句不是唯一的。在每个函数内部,您可以递归地调用函数,但是当递归调用返回时,执行只会继续执行,并且可以进入同一位置的其他块之一。
您可以通过将它们更改为elif
来解决此问题,但我个人并不认为递归是最佳解决方案(除非您明确尝试以函数式编程) :最好在顶部使用while循环,并在if的每个分支内更新x
和y
。