迷宫问题
- 给一个二维列表,表示迷宫(0表示通道,1表示围墙),给出算法求一条走出迷宫的路
栈——深度优先搜索
- 回溯法:从一个节点开始,任意找下一个能走的点,当找不到能走的点时,退回上一个点寻找是否有其他方向的点
- 使用栈存储当前路径
- 路径不一定是最短的
代码:
maze = [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 1, 0, 0, 0, 1, 0, 1],
[1, 0, 0, 1, 0, 0, 0, 1, 0, 1],
[1, 0, 0, 0, 0, 1, 1, 0, 0, 1],
[1, 0, 1, 1, 1, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 1, 0, 0, 0, 0, 1],
[1, 0, 1, 0, 0, 0, 1, 0, 0, 1],
[1, 0, 1, 1, 1, 0, 1, 1, 0, 1],
[1, 1, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
dirs = [lambda x,y: (x-1,y), #上
lambda x,y: (x,y+1), #右
lambda x,y: (x+1,y), #下
lambda x,y: (x,y-1)] #左
def maze_path(x1, y1, x2, y2): #起点和终点位置,x第几行,y第几列
stack = []
stack.append((x1, y1))
while(len(stack)>0): #栈不空说明有路可以走
curNode = stack[-1] #当前点
if curNode[0] == x2 and curNode[1] ==y2: #走到终点了
for p in stack:
print(p)
return True
for dir in dirs:
nextNode = dir(curNode[0], curNode[1])
if maze[nextNode[0]][nextNode[1]] == 0:
stack.append(nextNode)
maze[nextNode[0]][nextNode[1]] = 2 #表示已经走过
break
else:
maze[nextNode[0]][nextNode[1]] = 2
stack.pop()
else:
print('没有路')
return False
队列——广度优先搜索
- 思路:从一个节点开始,寻找所有接下来能走的路,继续不断寻找,直到找到出口
- 使用队列存储当前正在考虑的节点
代码:
from collections import deque
maze = [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 1, 0, 0, 0, 1, 0, 1],
[1, 0, 0, 1, 0, 0, 0, 1, 0, 1],
[1, 0, 0, 0, 0, 1, 1, 0, 0, 1],
[1, 0, 1, 1, 1, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 1, 0, 0, 0, 0, 1],
[1, 0, 1, 0, 0, 0, 1, 0, 0, 1],
[1, 0, 1, 1, 1, 0, 1, 1, 0, 1],
[1, 1, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
dirs = [lambda x,y: (x-1,y), #上
lambda x,y: (x,y+1), #右
lambda x,y: (x+1,y), #下
lambda x,y: (x,y-1)] #左
def print_r(path):
curNode = path[-1]
realpath = []
while curNode[2] != -1:
realpath.append(curNode[0:2])
curNode = path[curNode[2]]
realpath.append(curNode[0:2])
realpath.reverse()
for node in realpath:
print(node)
def maze_path_queue(x1, y1, x2, y2): #起点和终点位置,x第几行,y第几列
queue = deque()
queue.append((x1, y1, -1))
path = []
while len(queue) > 0:
curNode = queue.leftpop()
path.append(curNode)
if curNode[0] == x2 and curNode[1] == y2: #到终点
print_r(path)
return True
for dir in dirs:
nextNode = dir(curNode[0], curNode[1])
if maze[nextNode[0]][nextNode[1]] == 0:
queue.append((nextNode[0], nextNode[1], len(path)-1))
maze[nextNode[0][nextNode[1]] = 2 #标记为已走过
else:
print('没有路')
return False