iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >使用python求解迷宫问题的三种实现方法
  • 714
分享到

使用python求解迷宫问题的三种实现方法

2024-04-02 19:04:59 714人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

目录前言递归求解回溯求解队列求解总结前言 在迷宫问题中,给定入口和出口,要求找到路径。本文将讨论三种求解方法,递归求解、回溯求解和队列求解。 在介绍具体算法之前,先考虑将迷宫数字化。

前言

在迷宫问题中,给定入口和出口,要求找到路径。本文将讨论三种求解方法,递归求解、回溯求解和队列求解。

在介绍具体算法之前,先考虑将迷宫数字化。这里将迷宫用一个二维的list存储(即list嵌套在list里),将不可到达的位置用1表示,可到达的位置用0表示,并将已经到过的位置用2表示。

递归求解

递归求解的基本思路是:

  • 每个时刻总有一个当前位置,开始时这个位置是迷宫人口。
  • 如果当前位置就是出口,问题已解决。
  • 否则,如果从当前位置己无路可走,当前的探查失败,回退一步。
  • 取一个可行相邻位置用同样方式探查,如果从那里可以找到通往出口的路径,那么从当前位置到出口的路径也就找到了。

在整个计算开始时,把迷宫的人口(序对)作为检查的当前位置,算法过程就是:

  • mark当前位置。
  • 检查当前位置是否为出口,如果是则成功结束。
  • 逐个检查当前位置的四邻是否可以通达出口(递归调用自身)。
  • 如果对四邻的探索都失败,报告失败。
dirs=[(0,1),(1,0),(0,-1),(-1,0)] #当前位置四个方向的偏移量
path=[]              #存找到的路径
 
def mark(maze,pos):  #给迷宫maze的位置pos标"2"表示“倒过了”
    maze[pos[0]][pos[1]]=2
 
def passable(maze,pos): #检查迷宫maze的位置pos是否可通行
    return maze[pos[0]][pos[1]]==0
 
def find_path(maze,pos,end):
    mark(maze,pos)
    if pos==end:
        print(pos,end=" ")  #已到达出口,输出这个位置。成功结束
        path.append(pos)
        return True
    for i in range(4):      #否则按四个方向顺序检查
        nextp=pos[0]+dirs[i][0],pos[1]+dirs[i][1]
        #考虑下一个可能方向
        if passable(maze,nextp):        #不可行的相邻位置不管
            if find_path(maze,nextp,end):#如果从nextp可达出口,输出这个位置,成功结束
                print(pos,end=" ")
                path.append(pos)
                return True
    return False
 
def see_path(maze,path):     #使寻找到的路径可视化
    for i,p in enumerate(path):
        if i==0:
            maze[p[0]][p[1]] ="E"
        elif i==len(path)-1:
            maze[p[0]][p[1]]="S"
        else:
            maze[p[0]][p[1]] =3
    print("\n")
    for r in maze:
        for c in r:
            if c==3:
                print('\033[0;31m'+"*"+" "+'\033[0m',end="")
            elif c=="S" or c=="E":
                print('\033[0;34m'+c+" " + '\033[0m', end="")
            elif c==2:
                print('\033[0;32m'+"#"+" "+'\033[0m',end="")
            elif c==1:
                print('\033[0;;40m'+" "*2+'\033[0m',end="")
            else:
                print(" "*2,end="")
        print()
 
if __name__ == '__main__':
    maze=[[1,1,1,1,1,1,1,1,1,1,1,1,1,1],\
          [1,0,0,0,1,1,0,0,0,1,0,0,0,1],\
          [1,0,1,0,0,0,0,1,0,1,0,1,0,1],\
          [1,0,1,0,1,1,1,1,0,1,0,1,0,1],\
          [1,0,1,0,0,0,0,0,0,1,1,1,0,1],\
          [1,0,1,1,1,1,1,1,1,1,0,0,0,1],\
          [1,0,1,0,0,0,0,0,0,0,0,1,0,1],\
          [1,0,0,0,1,1,1,0,1,0,1,1,0,1],\
          [1,0,1,0,1,0,1,0,1,0,1,0,0,1],\
          [1,0,1,0,1,0,1,0,1,1,1,1,0,1],\
          [1,0,1,0,0,0,1,0,0,1,0,0,0,1],\
          [1,1,1,1,1,1,1,1,1,1,1,1,1,1]]
    start=(1,1)
    end=(10,12)
    find_path(maze,start,end)
    see_path(maze,path)

代码中see_path函数可以在控制台直观打印出找到的路径,打印结果如下:

S是入口位置 ,E是出口位置,*代表找到的路径,#代表探索过的路径。

回溯求解

在回溯解法中,主要是用栈来存储可以探索的位置。利用栈后进先出的特点,在一条分路上探索失败时,回到最近一次存储的可探索位置。这是一种深度优先搜索的方法。

def maze_solver(maze,start,end):
    if start==end:
        print(start)
        return
    st=SStack()
    mark(maze,start)
    st.push((start,0))             #入口和方向0的序对入栈
    while not st.is_empty():      #走不通时回退
        pos,nxt=st.pop()           #取栈顶及其检查方向
        for i in range(nxt,4):     #依次检查未检查方向,算出下一位置
            nextp = pos[0] + dirs[i][0], pos[1] + dirs[i][1]
            if nextp==end:
                print_path(end,pos,st)  #到达出口,打印位置
                return
            if passable(maze,nextp):    #遇到未探索的新位置
                st.push((pos,i+1))      #原位置和下一方向入栈
                mark(maze,nextp)
                st.push((nextp,0))      #新位置入栈
                break                   #退出内层循环,下次迭代将以新栈顶作为当前位置继续
    print("找不到路径")

队列求解

队列求解算法中,以队列存储可以探索的位置。利用队列先进先出的特点,实现在每个分支上同时进行搜索路径,直到找到出口。这是一种广度优先搜索的方法。

def maze_solver_queue(maze,start,end):
   path.append(start)
   if start==end:
       print("找到路径")
       return
   qu=SQueue()
   mark(maze,start)
   qu.enqueue(start)                #start位置入队
   while not qu.is_empty():        #还有候选位置
       pos=qu.dequeue()             #取出下一位置
       for i in range(4):           #检查每个方向
           nextp = pos[0] + dirs[i][0], pos[1] + dirs[i][1]
           if passable(maze,nextp): #找到新的探索方向
               if nextp==end:       #是出口,成功
                   print("找到路径")
                   path.append(end)
                   return
               mark(maze,nextp)
               qu.enqueue(nextp)    #新位置入队
               path.append(nextp)
 
   print("未找到路径")

但队列求解方法,不能直接得出找到的具体路径,要得到找到的路径还需要其他存储结构(如链表)。

总结

到此这篇关于使用python求解迷宫问题的三种实现方法的文章就介绍到这了,更多相关Python求解迷宫问题内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 使用python求解迷宫问题的三种实现方法

本文链接: https://www.lsjlt.com/news/142848.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 使用python求解迷宫问题的三种实现方法
    目录前言递归求解回溯求解队列求解总结前言 在迷宫问题中,给定入口和出口,要求找到路径。本文将讨论三种求解方法,递归求解、回溯求解和队列求解。 在介绍具体算法之前,先考虑将迷宫数字化。...
    99+
    2024-04-02
  • 如何使用python求解迷宫问题
    这篇文章主要介绍“如何使用python求解迷宫问题”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“如何使用python求解迷宫问题”文章能帮助大家解决问题。前言在迷宫问题中,给定入口和出口,要求找到路...
    99+
    2023-06-29
  • 使用OpenCV实现迷宫解密的全过程
    目录一、你能自己走出迷宫吗?二、使用OpenCV找出出口。1、对图像进行二值化处理。2、 对二值化后的图像进行轮廓检测并标注3、对图像阈值进行处理。4、对图像进行扩展操作。...
    99+
    2024-04-02
  • Python实现解析参数的三种方法详解
    目录先决条件使用 argparse使用 JSON 文件使用 YAML 文件最后的想法今天我们分享的主要目的就是通过在 Python 中使用命令行和配置文件来提高代码的效率 Let&#...
    99+
    2024-04-02
  • JavaScript三种方法解决约瑟夫环问题的方法
    目录概述问题描述循环链表有序数组数学递归总结概述 约瑟夫环问题又称约瑟夫问题或丢手绢问题,是一道经典的算法问题。问题描述也有很多变式,但大体的解题思路是相同的。本篇将以循环链表、有序...
    99+
    2024-04-02
  • 用python实现零钱找零的三种方法
    1.递归(recursion) def coins_changeREC(coin_values, change): """ 递归实现零钱找零 """ min_count = change ...
    99+
    2023-01-31
    三种 零钱 方法
  • AJAX请求数据及实现跨域的三种方法详解
    目录传统方法的缺点:什么是ajax?XMLHttpRequest 对象五步使用法:同步和异步的区别:如何将原生ajax进行封装JS几种跨域方法和原理附:ajax跨域post请求的ja...
    99+
    2024-04-02
  • Spring三种方法的注解自动注入问题
    目录Spring三种方法的注解自动注入1 @Autowired注解2 @Resource3 @InjectSpring 注解版 属性赋值 自动注入总结Spring三种方法的注解自动注...
    99+
    2022-12-28
    Spring注解 Spring自动注入 Spring注解自动注入
  • 详解基于C++实现约瑟夫环问题的三种解法
    目录一、前言二、循环链表模拟三、有序集合模拟四、递归公式解决五、结语一、前言 什么是约瑟夫环问题? 约瑟夫环问题在不同平台被"优化"描述的不一样,例如在牛客剑指offer叫孩子们的游...
    99+
    2024-04-02
  • C语言实现求最大公约数的三种方法
    目录题目描述问题分析代码实现方法一:穷举法方法二:辗转相除法方法三:更相减损法题目描述 求任意两个正整数的最大公约数 问题分析 最大公因数,也称最大公约数、最大公因子,指两个或多个整...
    99+
    2024-04-02
  • PHP使用三种方法实现数据采集
    目录什么叫采集?PHP制作采集的技术1. 使用socket技术采集:2. 使用curl_一套函数3. 直接使用file_get_contents(最顶层的)3种方...
    99+
    2024-04-02
  • python 实现多线程的三种方法总结
    1._thread.start_new_thread(了解) import threading import time import _thread def job(): ...
    99+
    2024-04-02
  • Python实现抽象基类的3三种方法
    Python的抽象基类类似于Java、C++等面向对象语言中的接口的概念。抽象基类提供了一种要求子类实现指定协议的方式,如果一个抽象基类要求实现指定的方法,而子类没有实现的话,当试图创建子类或者执行子类代码时会抛出异常。这里简单介绍一下P...
    99+
    2023-01-31
    三种 抽象 方法
  • 如何使用CSS实现换行(三种方法)
    换行是指在文字或者其他内容到达行末时,自动转到下一行的行为。在网页设计中,正确的换行可以使页面看起来更加舒适和自然。在CSS中,实现正确的换行需要了解一些原理和技巧。本文将为您介绍如何使用CSS实现换行的几种方法。方法一:使用word-wr...
    99+
    2023-05-14
  • Python 三种方法实现截图【详解+完整代码】
    人生苦短 我用python 如何用python实现截屏? 一、方法一 PIL中的ImageGrab模块 使用PIL中的ImageGrab模块简单,但是效率有点低 PIL是Python Imaging...
    99+
    2023-09-03
    python 开发语言 opencv pycharm
  • Golang实现解析JSON的三种方法总结
    目录背景示例Json例子解释1)反序列化成map2)反序列化成对象3)复杂json的解析总结背景 这是一篇写给0-1年新人的文章,短平快的教会你如何解析json字符串。 示例Json...
    99+
    2024-04-02
  • 解决Linux动态库依赖问题的三种实用方法分别是什么
    解决Linux动态库依赖问题的三种实用方法分别是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。 概述平时在编译安装某个软件时,如果自定义了一些安装目录,安装后...
    99+
    2023-06-16
  • Python实现求解最大公约数的五种方法总结
    目录方法一:短除法方法二:欧几里得算法(辗转相除法)方法三:更相减损术方法四:穷举法(枚举法)方法五:Stein算法求最大公约数是习题中比较常见的类型,下面小编会给大家提供五种比较常...
    99+
    2024-04-02
  • python 三元条件判断的3种实现方法
    python 三元条件判断的3种实现方法 C语言中有三元条件表达式,如 a>ba:b,Python中没有三目运算符(:),但Python有它自...
    99+
    2023-01-31
    条件 方法 python
  • 使用sublime Text3过程中各种问题的解决方法
    这篇文章给大家介绍使用sublime Text3过程中各种问题的解决方法,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。一、package control无法安装有梯子的可以用ctrl+shift+p呼出命令行...
    99+
    2023-06-26
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作