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)
     
  • 相关阅读:
    从苏宁电器到卡巴斯基(后传)第06篇:我的离职信
    Dalvik模式下基于Android运行时类加载的函数dexFindClass脱壳
    基于dalvik模式下的Xposed Hook开发的某加固脱壳工具
    Android平台dalvik模式下java Hook框架ddi的分析(2)--dex文件的注入和调用
    黑板客 -- 爬虫闯关 -- 关卡05
    黑板客 -- 爬虫闯关 -- 关卡04
    黑板客 -- 爬虫闯关 -- 关卡03
    黑板客 -- 爬虫闯关 -- 关卡02
    黑板客 -- 爬虫闯关 -- 关卡01
    Python小游戏 -- 猜单词
  • 原文地址:https://www.cnblogs.com/abdm-989/p/14123489.html
Copyright © 2011-2022 走看看