迷宫问题:深度优先搜索和广度优先搜索

迷宫问题:深度优先搜索和广度优先搜索

1、深度优先搜索可以使用栈实现,栈顶元素为当前节点

2、当前节点搜索下一节点,判断节点是否走得通,如果走得通任意方向走一步,走不通一直弹出栈内元素,直到走得通

3、当前节点如果等于(x2,y2)说明搜索结束,已找到出口

4、对于每一个走过的路径都要标记为另一个数,便于下次不能搜索到

一、深度优先搜索

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 + 1, y),
        lambda x, y: (x, y - 1),
        lambda x, y: (x, y + 1)]

# 深度有优先搜索
def maze_path(x1, y1, x2, y2):
    '''(x1,y1)代表起点,(x2,y2)代表终点'''
    global nextNode
    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])
            # 如果有一个方向上为0则说明可以按照该方向继续走
            if maze[nextNode[0]][nextNode[1]] == 0:
                stack.append(nextNode)
                maze[nextNode[0]][nextNode[1]] = 2  # 标志为2说明当前节点走过了,找到一个可以走的点就结束
                break  # 跳出for的循环,只要栈不空就进入下一次寻找方向
        else:
            maze[nextNode[0]][nextNode[1]] = 2 # 没找到路也要标记,并把栈中的元素弹出
            stack.pop()
    else:
        print("没有路")
        return False


二 、广度优先搜索

1、广度优先搜素使用队列实现,但是队列实现时队内只保留当前路径的最后一个节点,所以队空了说明没有路可以走了

2、每次走下一步时需要一个列表把当前节点的上一个节点存下来,最后通过回溯找到该节点所在的路径

3、回溯函数要单独来写,判断的条件只要不是起始点就一直往回找,并把节点单独存放到一个列表中

4、如此找到的节点保存到realPath中是从终点到起点的,将列表逆序之后找到的就是该条路径

5、当找到路的时候,终点也会被放到path里,所以path的最后一个元素就是终点,回溯的时候就是通过终点往回找的

6、path里边放的是所有出队的节点,但是只有一条路径是最后到了终点的路径,根据回溯找到那条路径上所有的节点

from collection import deque
# 路径回溯函数
def print_path(path):
    curNode = path[-1]
    realPath = []
    while curNode[2] != -1:  # curNode[2] == -1 代表搜索到了起始位置
        realPath.append(curNode[0:2])  # curNode的前两个存放的就是真实走过的路径
        curNode = path[curNode[2]]
    # while循环结束将起点加入到路径中
    realPath.append(curNode[0:2])
    realPath.reverse() # 当前路径为终点到起点,列表反转
    # print(realPath)
    for p in realPath:
        print(p)


def maze_path_deque(x1, y1, x2, y2):
    queue = deque()  # -1代表起点的前一个节点的下标
    queue.append((x1, y1, -1))
    path = []  # 把出队的节点存起来,下一个节点回溯找到走过的路
    while len(queue) > 0:
        curNode = queue.pop()
        path.append(curNode)
        if curNode[0] == x2 and curNode[1] == y2:
            print_path(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

三、广度优先搜索(myself)

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 + 1, y),
        lambda x, y: (x, y - 1),
        lambda x, y: (x, y + 1)]


# 深度优先搜索实现队列,找到最短的路径
# 返回路径
def print_path(path):
    curNode = path[-1]
    real_path = []
    # 只要没有到起点,弹出没一个节点的下标
    while curNode[2] != -1:
        real_path.append(curNode[0:2])
        curNode = path[curNode[2]]
    real_path.append(curNode[0:2])  # 如果是起点的话将起点也加进来
    real_path.reverse()   # 原来是终点到起点,逆序起点到终点
    for item in real_path:
        print(item)


def maze_path(x1, y1, x2, y2):  # (x1,y1)代表起点,(x2,y2)代表终点
    stack = deque()
    path = []
    stack.append((x1, y1, -1))  # 起点进栈
    while len(stack) > 0:
        curNode = stack.pop()
        path.append(curNode)  # 每一个出队的都要保存下来
        if curNode[0] == x2 and curNode[1] == y2:
            # print("找到路")
            print_path(path)
            return True
        for dir in dirs:
            nextNode = dir(curNode[0], curNode[1])  # 计算下一个节点
            if maze[nextNode[0]][nextNode[1]] == 0:
                stack.append((nextNode[0], nextNode[1], len(path) - 1))
                maze[nextNode[0]][nextNode[1]] = 2
    else:
        print("没有路走")
        return False
``
  • 0
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值