我正在做一个作业,在该作业中我已经解决了主要问题并正在研究扩展练习。目前,已经给出了一张地图,并在网格上标识了所有可能的迷宫解决方案,网格的打印方式如下:
1 1 3 1 0 2
3 3 3 3 1 3
3 3 1 3 3 3
3 3 3 1 3 0
3 1 3 1 3 1
3 1 3 3 3 0
其中0是空白空间,1是墙壁,2是目标,3是访问空间。扩展任务是在任何给定的起点下,为迷宫提供最短的解决方案。如果起点是一堵墙,那么迷宫就无法解决。这也很好。它应该能够为给定的任何迷宫工作。
我真的不知道从哪里开始这个问题。一个想法是取所有路径的总和并找到其中的最小路径,但是我不确定如何实现这一点。
当前这是我的代码:
EMPTY = 0
WALL = 1
GOAL = 2
VISITED = 3
def solve(grid, x, y):
if grid[x][y] == GOAL:
show_grid(grid)
return True
elif grid[x][y] == WALL:
return False
elif grid[x][y] == VISITED:
return False
else:
# mark as visited
grid[x][y] = VISITED
# explore neighbors clockwise starting by going up
if ((x < len(grid)-1 and solve(grid, x + 1, y))
or (y > 0 and solve(grid, x, y-1))
or (x > 0 and solve(grid, x-1, y))
or (y < len(grid)-1 and solve(grid, x, y+1))):
return True
else:
return False
def show_grid (grid):
for i in range(len(grid), 0, -1):
# print("i: ", i)
for element in grid[i-1]:
print (element, end=" ")
print()
def main ():
grid = [[EMPTY, WALL, EMPTY, EMPTY, EMPTY, EMPTY],
[EMPTY, WALL, EMPTY, WALL, EMPTY, WALL],
[EMPTY, EMPTY, EMPTY, WALL, EMPTY, EMPTY],
[EMPTY, EMPTY, WALL, EMPTY, EMPTY, EMPTY],
[EMPTY, EMPTY, EMPTY, EMPTY, WALL, EMPTY],
[WALL, WALL, EMPTY, WALL, EMPTY, GOAL]]
solve(grid, 0, 0)
扩展名要求打印最短路径的长度,其中遍历1平方等于1个移动。感谢您提供有关此问题的任何帮助。
答案 0 :(得分:1)
您正在使用递归浏览网格,其中的基本情况是找到了GOAL
。 solve
的每个实例仅返回一个布尔值,因此您丢失了信息-实例采用的路径。
重构,以便该函数在可行时返回网格位置,并累积实例后代的返回值。
您需要重新考虑您的条件,并且您想确保探索所有路径(上,下,左,右)。在条件bool((0,0)) -> True
中使用a tuple is evaluated True
这一事实可能会有所帮助。
最后您可以:
我试图根据您当前的代码来制定该代码,因为我假设您了解当前流程的工作方式,并且从那里开始可能会更容易。
您还可以将网格查看为图形,每个 point 是一个节点,该节点的边缘与其周围的节点相邻。您可以先将网格解析为图形,然后使用任何定义良好的算法遍历图形并找到答案。对于树解决方案,根将是搜索的起点。我没有很多使用图的经验,所以我觉得我无法为此提供详细的答案-也许有人会给出更好的解释。 / p>
答案 1 :(得分:1)
我同意@wwii的回答,如果您正在探索所有解决方案,只需返回每个成功路径的长度,然后找到最短的路径即可。可以通过以下更改来实现:
例如,
GOAL = 'G'
WALL = 'W'
EMPTY = 'E'
def solve(grid, x, y):
if grid[x][y] == WALL or grid[x][y].endswith(GOAL):
return grid[x][y]
candidates = []
# explore neighbors clockwise starting by going down
if x < len(grid)-1:
candidates.append('d' + solve(grid, x + 1, y))
if y > 0:
candidates.append('l' + solve(grid, x, y - 1))
if x > 0:
candidates.append('u' + solve(grid, x - 1, y))
if y < len(grid)-1:
candidates.append('r' + solve(grid, x, y + 1))
# get rid of none solutions from candidates
candidates = [x for x in candidates if not x.endswith(GOAL)]
if not candidates: # if no solution, it's essentially a wall
grid[x][y] = 'W'
else:
# getting shortest path
grid[x][y] = sorted(candidates, key=lambda x: len(x))[0]
# for longest path use code below instead of above
# grid[x][y] = sorted(candidates, key=lambda x: len(x))[-1]
return grid[x][y]
如果访问了某个节点并到达了目标,则该节点上的值可能类似于“ drrurG”。这意味着最短的路径是向下,向右* 2,向上,向右,目标。方向约定向下表示向下一行,即x + 1。
请确保您可能需要更改代码的其他部分才能起作用。
以上代码遍历了所有可能的路径。但是您可能不需要。到达最短路径的方法可能更快,因为此问题并不像其他一般的寻路问题那么复杂。
例如,绝对最短的路径显然是从起点到目标的直线。首先检查。如果这不是解决方案,请开始检查下一条最短路径。看看那些工作。如果没有,继续前进直到找到它。