python数据结构与算法练习-广度优先搜索(队列-迷宫)

python数据结构与算法练习-队列解决迷宫问题

广度优先搜索

将迷宫表示为如下矩阵,1表示此路不通,0表示可行,起始位置A为迷宫的 [1][1] 位置,终点S为[8][8],求一条从A到S的通路。
请添加图片描述
思路:

  1. 广度优先搜索首先是会找到所有的可行路径,所以元素入队时候必须要知道当前节点来自哪个节点。
  2. 起点入队列,队列除了存放坐标之外还应具有此节点的来源节点的索引。
  3. 广度优先搜索返回的结果一般不唯一,结果中会存在路径最短的一条,所以广度优先搜索也可以解决最优路径问题。

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)

知识点记录。

  • 3
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值