zoukankan      html  css  js  c++  java
  • 算法之迷宫问题

    题目:给一个二维列表,表示迷宫(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]
     ]

    解决思路:

    • 在一个迷宫节点(x,y)上,可以进行四个方向的探查:maze[x-1][y], maze[x+1][y], maze[x][y-1], maze[x][y+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 solve_maze(x1, y1, x2, y2):
        stack = []
        stack.append((x1,y1))
        maze[x1][y1] = 2
        while len(stack) > 0:   # 当栈不空循环
            cur_node = stack[-1]
            if cur_node == (x2,y2): #到达终点
                for p in stack:
                    print(p)
                return True
            for dir in dirs:
                next_node = dir(*cur_node)
                if maze[next_node[0]][next_node[1]] == 0:   #找到一个能走的方向
                    stack.append(next_node)
                    maze[next_node[0]][next_node[1]] = 2  # 2表示已经走过的点
                    break
            else: #如果一个方向也找不到
                stack.pop()
        else:
            print("无路可走")
            return False

    用队列实现:

    解决思路:

    • 思路:从一个节点开始,寻找所有下面能继续走的点。继续寻找,直到找到出口。
    • 方法:创建一个空队列,将起点位置进队。在队列不为空时循环:出队一次。如果当前位置为出口,则结束算法;否则找出当前方块的4个相邻方块中可走的方块,全部进队。

    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]
    ]
    
    def solve_maze2(x1,y1,x2,y2):
        queue = deque()
        path = []    # 记录出队之后的节点
        queue.append((x1,y1,-1))
        maze[x1][y1] = 2
        while len(queue) > 0:
            cur_node = queue.popleft()
            path.append(cur_node)
            if cur_node[0] == x2 and cur_node[1] == y2:  #到终点
                real_path = []
                x,y,i = path[-1]
                real_path.append((x,y))
                while i >= 0:
                    node = path[i]
                    real_path.append(node[0:2])
                    i = node[2]
                real_path.reverse()
                for p in real_path:
                    print(p)
                return True
            for dir in dirs:
                next_node = dir(cur_node[0], cur_node[1])
                if maze[next_node[0]][next_node[1]] == 0:
                    queue.append((next_node[0], next_node[1], len(path)-1))
                    maze[next_node[0]][next_node[1]] = 2 # 标记为已经走过
        else:
            print("无路可走")
            return False
    
    solve_maze2(1,1,8,8)
  • 相关阅读:
    【Redis】搭建主从复制
    【安装】Ubuntu之Docker
    【安装】Ubuntu之MySQL
    【Docker】Dockerfile构建指令
    【Docker】常用命令
    【14】Flask 请求上下文
    【13】Flask 上下文前夕
    【12】Flask 分析线程和协程
    【11】Flask 高级进阶
    【10】Flask 高级摘要
  • 原文地址:https://www.cnblogs.com/haiyan123/p/8414812.html
Copyright © 2011-2022 走看看