广度优先搜索
将迷宫表示为如下矩阵,1表示此路不通,0表示可行,起始位置A为迷宫的 [1][1] 位置,终点S为[8][8],求一条从A到S的通路。
思路:
- 广度优先搜索首先是会找到所有的可行路径,所以元素入队时候必须要知道当前节点来自哪个节点。
- 起点入队列,队列除了存放坐标之外还应具有此节点的来源节点的索引。
- 广度优先搜索返回的结果一般不唯一,结果中会存在路径最短的一条,所以广度优先搜索也可以解决最优路径问题。
python 实现
#用队列解决迷宫问题对应的是广度优先搜索
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,0],
[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-1,y),
lambda x,y :(x,y-1),
lambda x,y :(x,y+1)
]
#这里要注意广度优先搜索首先是会找到所有的可行路径,所以元素入队时候必须要知道当前节点来自哪个节点 也就是nextnode和curnode的联系
def maze_path_queue(x1,y1,x2,y2):
#首先注意上下节点的联系需要用单独的列表存储
path_labe = []
#创建队列 起点入队,起点没有上一节点所里这里的联系用-1表示
queue = deque()
queue.append((x1,y1,-1))
while len(queue)>0:
curnode = queue.popleft()
path_labe.append(curnode)
#找到迷宫终点跳出循环
if curnode[0] == x2 and curnode[1] == y2:
cur = path_labe[-1]
#存放最终路径结果
path_result = []
while cur[2] != -1:#只有起点的第三个元素才是-1
path_result.append((cur[0],cur[1]))#路径不用储存节点之间的联系
cur = path_labe[cur[2]]#找到上一节点
path_result.reverse()
for path in path_result:
print(path)
return True
#未找到终点执行循环
for dir in dirs:
nextnode = dir(curnode[0],curnode[1])
#判断下一节点是否可通过
if maze[nextnode[0]][nextnode[1]] == 0:
#队列元素与nextnode形式不同,队列中要加入节点间的联系,上面知道联系储存在path_label中
queue.append((nextnode[0],nextnode[1],path_labe.index(curnode)))
#将循环过的节点标记为走过
maze[nextnode[0]][nextnode[1]] = 2
#这里不能break 因为最广是探索所有的路径 所以要找到所有可通过的 最深的只要找到一个就可以了 所以栈那里需要break
else:
print("NO way")
maze_path_queue(1,1,8,8)
#output
(2, 1)
(3, 1)
(4, 1)
(5, 1)
(5, 2)
(5, 3)
(6, 3)
(6, 4)
(6, 5)
(7, 5)
(8, 5)
(8, 6)
(8, 7)
(8, 8)
知识点记录。