人工智能实验——八数码难题

2023-05-16

人工智能实验——八数码难题


人工智能实验——八数码难题

  • 人工智能实验——八数码难题
    • 八数码难题简介
    • 八数码难题所用到的算法简介
    • 代码实现解释
    • 运行结果显示
    • 代码附件
    • 程序可视化

八数码难题简介


八数码问题指的是定义一个3$\times$3的格子,然后把1-8八个数字随机放入这些格子中,然后排列成规则的格子。就像下面图所示:

在这里插入图片描述

而本文所要解决的是,如何设计一个程序解决八数码问题。解决八数码问题其实算是一个搜索问题。

八数码难题所用到的算法简介


  • BFS广度优先搜索算法

    以接近起始节点的程度依次扩展节点的搜索方法 宽度优先搜索是逐层进行的;在对下一层的任一节点进行搜 索之前,必须搜索完本层的所有节点。

    在这里插入图片描述

  • DFS深度优先搜索算法

    优先扩展最新产生的(即最深的)节点的搜索方法 深度优先搜索沿着状态空间某条单一的路径从起始节点向下 进行下去;只有当搜索到达一个没有后裔的状态时,它才考 虑另一条替代的路径。 状态空间搜索树的深度可能为无限深,往往给出一个节点扩 展的最大深度—深度界限

    在这里插入图片描述

  • 贪婪算法(本文未利用)

    贪婪算法的话,它是一种特殊的DFS算法,若设计得不好得话就会直接退化为DFS算法。在这里得话可以利用每个元素到目标点的曼哈顿距离来作为贪婪算法的引导元素。也可以利用在正确位置的元素的个数作为引导。

  • 代价优先算法(本文未利用)

    代价算法的话,一般以当前深度作为代价。优先搜索深度小的。

  • A*算法

    A*算法结合了贪婪算法与代价优先算法,利用两者的和作为代价利用广度优先的数据结构为基础来进行搜索。

在这里插入图片描述

代码实现解释


1.定义八数码类

首先定义了一个八数码类,此类生成的对象是用来存储八数码数据的。八数码类的对象相当于状态空间。此类中包含了四类数据,分别为八数码的排列顺序、父节点、深度、A*算法对应的代价。下面为八数码类。

# 八数码矩阵
class Ef:
    def __init__(self, value, parent=0, depth=1, hscore=0):
        self.value = value
        self.parent = parent  # 定义父节点 若不输入父节点 则自定义其为根 也就是说当parent为0时为根
        self.depth = depth #深度 默认为1
        self.fscore = depth + hscore #A*算法的代价

2.定义操作类

在完成八数码类的编写后,接着的是后继函数即操作。对于后继函数,我的做法是再次定义一个Op类。此类中的函数只有两个,分别为初始化类与空白移动类。在初始化类中,我对传入的八数码对象进行了复制赋值(之所以怎么做是因为Python中的对象类似于指针而不是真正实体)。然后设置了遍历寻找八数码对象中0的位置索引。最后设置了方向参数字典,这样做可以缩减代码量。

在对函数初始化完后,开始编写移动函数,这个函数才是操作类中的主体,这个类的功能主要就是将0与某个方向的数进行替换。一开始编写这个函数时其实分成了四个函数来写的,即上下左右。但是后面发现这些函数的重复性大,于是将不同方向的特定参数整理成了字。将四段代码整理成了一段只要传入字典中的某个值即可移动0。最后返回的是移动成功后的嵌套列表。补充:函数内部拥有一定的边界判别语句,若超界了会返回0。下图为操作类的功能图。

在这里插入图片描述

# 包含所有操作的类 注意python赋值后的对象还是同一个对象 所以要用copy
class Op:
    def __init__(self, ef):
        self.ef_value = copy.deepcopy(ef.value)
        for i in range(0, 3):  # 获取空位置的索引
            for j in range(0, 3):
                if self.ef_value[i][j] == 0:
                    self.j, self.i = j, i
                    break
        self.direction = {'left': [self.j == 0, 0, -1], 'right': [self.j == 2, 0, 1], \
                          'up': [self.i == 0, -1, 0], 'down': [self.i == 2, 1, 0]}  # 方向配置字典

    def move(self, direc='left'):  # 交换操作
        op = self.direction[direc]
        if op[0]:  # 如果在第一列则无法交换 返回0
            return 0
        else:  # 否则交换
            temp = self.ef_value[self.i + op[1]][self.j + op[2]]
            self.ef_value[self.i + op[1]][self.j + op[2]] = self.ef_value[self.i][self.j]
            self.ef_value[self.i][self.j] = temp
            return self.ef_value

3.编写Solution类

完成以上的类的编写后,开始编写程序的主体代码。对于主体,我也还是写了一个Solution类。这个类中的数据主要包含Open表、Closed表、开始状态、目标状态。下图为Solution类各项数据的图解。

在这里插入图片描述

class Solution:
    def __init__(self, ef):
        self.openT = []  # 定义open表  注意需要用到python自带的队列库
        self.openT.append(ef)  # 一开始将其添加进open表
        self.closeT = []  # 定义close表
        self.start_state = ef  # 定义开始状态
        self.des_state = [[1, 2, 3], [8, 0, 4], [7, 6, 5]]  # 定义最终状态
        self.des_state_dict = {1:[0,0],2:[0,1],3:[0,2],8:[1,0]
                               ,0:[1,1],4:[1,2],7:[2,0],6:[2,1],5:[2,2]} #字典格式

初始化完Solution类后,我定义了多个基础的函数,这些函数基本上都是判断函数。包括状态是否到达目标状态判断函数、状态是否重复判断函数、是否可解函数。对于前两个,函数本体基本上都是用推导式一句完成的。而对于是否可解函数相对复杂。此判断首先是把八数码矩阵变成一维的形式,然后从第一个位置开始(除0外)记录每个元素前面比此元素大的个数,并把这些个数相加。如果最后得到的是偶数则有解否则无解。下图为判断函数的代码截图。*参考:*http://t.csdn.cn/0vyzV

    def iSolve(self,ef): #八数码是否有解判断 有解则返回1
        #转一维列表
        onedi = [ef.value[0][i] for i in range(3)] + [ef.value[1][2]] + \
                [ef.value[2][i] for i in range(2, -1, -1)] + [ef.value[1][i] for i in range(2)]
        oxe = 0 #计算逆序
        for i in range(1, 9):
            if onedi[i] != 0:
                for j in range(i):
                    oxe += 1 if onedi[j] > onedi[i] else 0
        return 1 if oxe % 2 == 0 else 0

4.extend函数.

除了以上的基础函数外,还有一个十分重要的基础函数。此函数是用来拓展的。此函数内部包含过滤机制,如果拓展生成的嵌套列表在closed表的话就丢弃,如果不在的话就计算深度并把父节点、深度、代价、嵌套列表传入一个新的八数码对象中,然后添加到open表中。

    def extend(self, ef):  # 拓展节点
        ex_direct = ['up', 'down', 'left', 'right']
        for d in ex_direct:
            temp = Op(ef).move(d)  # 由于这里用到了 copy深度复制  所以就要用一下方法阻止循环
            if temp:  # 如果可以上移则执行并且上行的结果不在closeT
                for i in self.closeT:  # 这里还可以重构
                    if i == temp:
                        break
                else:
                    ef_d = Ef(temp, ef, ef.depth+1, self.h(temp))  # 定义一个新对象 值为返回的上行结果 父节点为ef
                    #若要改h(n)在上面改
                    self.openT.append(ef_d)

在这里插入图片描述

5.BFS算法

在一切都铺垫好后开始编写搜索算法,首先写的是BFS算法函数。进入函数后首先开始记录当前时间并把它命定义为start_time。然后判断传入的八数码对象是否有解,若无解则放回“No Solution!”,否则进入下面操作。判断Open表是否为空,若为空则放回”Failure”否则进入下面操作。检测Open表队首是否为目标状态,若不为目标状态则对队首元素进行拓展,并把队首纳入closed表中然后弹出。若已经是目标则遍历目标的父节点直到无父节点。然后打印这些父节点与程序运行时间与节点深度。以下为流程图

在这里插入图片描述

    def BFS(self):  # 广度搜索
        start_time = time.time()
        if self.iSolve(self.openT[0]):
            while self.openT:  # 判断openT是否空表
                if self.isDes(self.openT[0]):
                    result = []
                    pointer = self.openT[0]
                    result.append(pointer.value)
                    while pointer.parent:
                        pointer = pointer.parent
                        result.append(pointer.value)
                    print(f'当前深度:{self.openT[0].depth}\n程序运行时间:{time.time() - start_time}s'
                          f'\n以下为推导过程(BFS)')
                    while result:
                        print(result.pop())  # 逆序打印
                    return "Success"
                else:
                    self.closeT.append(self.openT[0].value)  # 给closeT添加值
                    self.extend(self.openT[0])  # 若不是结果的话则拓展ef
                    self.openT.pop(0)  # 出队
            else:
                return "Failure"
        else:
            return 'No Solution!'

6.DFS算法

对于DFS其代码与BFS的类似,不同的地方在于其利用的数据结构是栈而不是队列,所以它首先检测的是最后一个元素是否是目标,并且也是首先对最后一个元素进行拓展。除此之外,DFS还对此进行了深度的限制。下图为我制作的程序在DFS上的流程图。

在这里插入图片描述

    def DFS(self,depth=20): #深度搜索 需要传入深度参数 默认为100
        start_time = time.time()
        if self.iSolve(self.openT[0]):
            while self.openT:  # 判断openT是否空表且是否超过深度
                if self.isDes(self.openT[-1]): #检测倒数第一个
                    result = []
                    pointer = self.openT[-1]
                    result.append(pointer.value)
                    while pointer.parent:
                        pointer = pointer.parent
                        result.append(pointer.value)
                    print(f'当前深度:{self.openT[-1].depth}\n程序运行时间:{time.time() - start_time}s'
                          f'\n以下为推导过程(DFS)')
                    while result:
                        print(result.pop())  # 逆序打印
                    return "Success"
                else:
                    self.closeT.append(self.openT[-1].value)  # 给closeT添加值
                    if self.openT[-1].depth < depth: #深度限制
                        self.extend(self.openT.pop())  # 若不是结果的话则拓展ef
                    else:
                        self.openT.pop()
            else:
                return "Failure"
        else:
            return 'No Solution!'

7.A*算法

而A*算法大体上的程序结构和DFS与BFS是一致的,但是其利用的是优先队列。每一次拓展后都会根据代价的值对OPEN表进行排序,取代价最小的到队首然后对队首进行判断是否为目标,若为目标则打印结果否则进行拓展并排序。而这里的代价有g(n)与h(n)组成,g(n)是当前状态的深度利用的是DFS中的深度接口,而h(n)则是自己设计的。我设计了两种h(n),第一种是八数码九宫格里面各个元素与目标元素的差异个数。另外一种是各个元素到目标元素的最短距离的距离之和。附件中提供的程序利用的是第一种,第二种在代码中也有但是需要更改下接口。下图为A*算法的流程图。

在这里插入图片描述

    def astar(self):
        start_time = time.time()
        if self.iSolve(self.openT[0]):
            while self.openT:  # 判断openT是否空表且是否超过深度
                if self.isDes(self.openT[0]): #检测倒数第一个
                    result = []
                    pointer = self.openT[0]
                    result.append(pointer.value)
                    while pointer.parent:
                        pointer = pointer.parent
                        result.append(pointer.value)
                    print(f'当前深度:{self.openT[0].depth}\n程序运行时间:{time.time() - start_time}s'
                          f'\n以下为推导过程(A*)')
                    while result:
                        print(result.pop())  # 逆序打印
                    return "Success"
                else:
                    self.closeT.append(self.openT[0].value)  # 给closeT添加值
                    self.extend(self.openT[0])  # 若不是结果的话则拓展ef
                    self.openT.pop(0)  # 出队
                    self.openT.sort(key=lambda x:x.fscore) #排序 根据fscore排序
            else:
                return "Failure"
        else:
            return 'No Solution!'

运行结果显示


以上为程序设计的描述部分。对程序设计完后我对程序进行了一些测试,包括不可解八数码的测试,三种算法的测试。以下为测试结果。图9是不可解八数码的测试,结果返回正确。

在这里插入图片描述

下图分别对应的是A*、BFS、DFS三种算法,三者均是对同一个八数码的测试。由此可以看出三者的运行时间有一定的区别。

在这里插入图片描述

代码附件


源代码下载

https://download.csdn.net/download/weixin_51735061/85375158

程序可视化


在这里插入图片描述

上面的为演示,做法在https://blog.csdn.net/weixin_51735061/article/details/125656323

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

人工智能实验——八数码难题 的相关文章

  • 树莓派上使用VSCode配置pyqt环境

    树莓派上在VSCode配置pyqt环境 第一次写博客 xff0c 这两天在树莓派上通过pyqt开发嵌入式软件 xff0c 本人一开始想用在windows上常用的pycharm配置pyqt xff0c 但是发现pycharm安装需要的java
  • postgres 错误duplicate key value violates unique constraint 解决方案

    SELECT setval 39 tablename id seq 39 SELECT MAX id FROM tablename 43 1 主要是 xff1a serial key其实是由sequence实现的 xff0c 当你手动给se
  • React 的生命周期

    挂载 当组件实例被创建并插入 DOM 中时 xff0c 其生命周期调用顺序如下 xff1a constructor 在 React 组件挂载之前 xff0c 会调用它的构造函数 getDerivedStateFromProps 在调用 re
  • Python去掉txt重复行

    coding utf 8 34 34 34 作者 xff1a sunli 日期 xff1a 2022年01月05日 34 34 34 coding utf 8 readDir 61 34 D1 txt 34 writeDir 61 34 D
  • 软件开发的四种模型

    1 gt 瀑布模型 xff1a xff08 1 瀑布模型的特点 xff1a 是线性模型的一种 xff0c 每一个阶段只执行一次 xff1b 这种模型是靠文档驱动的 xff08 2 瀑布模型的优缺点 优点 xff1a 开发的各个阶段比较清晰
  • IDEA 设置 背景 图片 详细步骤(结尾附高清背景图片)

    先上效果图 xff0c 原图在结尾 第一步 xff0c 找到搜索界面 xff0c 在搜索界面搜索 Set Background Image 之后 xff0c 找到想设置的图片的存储路径 接下来设置不透明度Opacity xff0c 越向右
  • Ubuntu 18.04下创建新用户/目录、修改用户权限及删除用户的方法

    Ubuntu 18 04下创建新用户 目录 修改用户权限及删除用户的方法 以下介绍在Ubuntu 18 04系统下创建新用户 目录 修改用户权限及删除用户的正确方法 在Ubuntu系统上创建新用户使用 sudo useradd 用户名 命令
  • 栈和队列练习题

    1 20分 回文序列是指正读反读均相同的字符序列 xff0c 如 abba 和 abdba 均是回文 xff0c 但 good 不是回文 试写一个算法判定给定的字符串是否为回文序列 span class token keyword int
  • mysql数据库忘记密码了怎么办

    本人用的mysql8版本 看到网上很多教程 xff0c 什么修改配置文件my ini 在8版本根本没用 以下是8版本解决办法 亲测可用 1 用管理员身份打开命令行工具 xff08 强调 xff1a 管理员身份 xff09 2 停止mysql
  • Java字符串匹配算法

    定义 串 string 是由零个或多个字符组成的有限序列又名叫字符串 一般地 xff0c 由n个字符串构成的串记作 S 61 a0a1 an 1 n 0 其中a i xff08 1 i n xff09 n是个有限的数值串一般记为S是串的名称
  • win10 vmvare打开虚拟机蓝屏重启,禁用device/credential guard 解决方法

    目录 解决方法在此 win10系统安装的vmware15一打开虚拟机就蓝屏重启 家人们我改了大半天 xff0c 试了友友们各种方法 xff0c 终于发现 xff0c 全都不好使 xff01 11 xff01 xff01 xff01 xff0
  • 数据结构算法设计题

    线性表 1 已知长度为n的线性表采用顺序存储结构 写一个算法 xff0c 删除线性表中所有值为x的元素 方法一 用k记录顺序表L中等于x的元素个数 xff0c 边扫描L边统计k 并将不等于x的元素前移k个位置 xff0c 最后修改L的长度
  • Elasticsearch Java API的基本使用

    说明 在明确了ES的基本概念和使用方法后 xff0c 我们来学习如何使用ES的Java API 本文假设你已经对ES的基本概念已经有了一个比较全面的认识 客户端 你可以用Java客户端做很多事情 xff1a 执行标准的index get d
  • lut调色预设怎么安装,LUT预设导入FCPX/PR/AE/PS/LR/达芬奇等软件教程

    lut调色预设怎么安装 xff0c LUT预设导入FCPX PR AE PS LR 达芬奇等软件教程 lut调色预设是一套深受设计师喜爱的调色软件 xff0c 通过使用LUT可以迅速达到很好的胶片质感和色彩 xff0c 在此基础上稍作调整即
  • macbook pro如何外接显示器?macbook 外接显示器教程

    13寸MacBook Pro屏幕是不是有点小了 xff1f 不知道你有没有萌生外接显示器的方法 xff01 接下来就为大家展示一下macbook pro如何外接显示器 xff01 先说说外接显示器有什么好处 1 拓展了工作空间 13寸的Ma
  • 腾讯视频 for Mac缓存的视频在哪?找不到腾讯视频缓存文件怎么办

    腾讯视频 for Mac提供丰富多彩的节目 xff0c 有时候我们会想要将缓存下来观看过的视频给删除 xff0c 但是根本找不到腾讯视频缓存文件 xff0c 那么我们要怎样才知道它的缓存路径呢 和小编一起来看看腾讯视频 for Mac缓存的
  • Mac OS小技巧:MAC电脑如何设置一键切换输入法

    我们在电脑上进行输入时经常会切换中英文输入不同的文字 xff0c 在windows系统上输入法切换直接按快捷键shift 43 ctrl就可以实现 xff0c 但是Mac系统的输入法设置与Windows系统的输入法设置不同 xff0c 但是
  • 全网最快的M1 MacBook Air详细测评

    简要总结这款 M1 MacBook Air xff1a 1 M1性能表现超出预期的好 xff0c 速度快到堪称恐怖 2 与Intel Mac一样功能强大 xff0c 甚至更强大 3 M1发热大幅降低 xff0c 续航大幅提升 4 兼容性不是
  • Mac技巧|如何阻止 iCloud 同步某个文件夹?

    使用 iCloud 的过程中 xff0c 难免遇到有些文件夹你不希望同步 比如游戏制作 xff0c 视频剪辑等的工程文件 xff0c iCloud 的持续同步机制会使得这些文件夹中的部分文件持续处于被上传且不可用状态 今天小编就给大家带来了
  • parallels desktop M1版安装Windows10教程

    近期有些朋友购入了新的M1 mac xff0c 可发现无法安装windows 现在 xff0c Parallels发布了与M1 Mac兼容的Parallels 16的技术预览版本 xff0c 可以安装ARM版本的win10 接下来 xff0

随机推荐

  • parallels desktop M1版安装Windows10教程

    近期有些朋友购入了新的M1 mac xff0c 可发现无法安装windows 现在 xff0c Parallels发布了与M1 Mac兼容的Parallels 16的技术预览版本 xff0c 可以安装ARM版本的win10 接下来 xff0
  • macOS怎样备份?备份Mac文件的最佳方法

    备份macOS绝不是一个坏主意 xff0c 您的机器可能会损坏 xff0c 故障或变得更糟 无论出现什么问题 xff0c 备份都可以帮助您恢复正常工作 如何使用Time Machine和iCloud备份Mac 要使用Time Machine
  • Office 2019 for Mac激活失败,显示未找到许可证怎么办?

    无法激活office 2019 xff1f office 2019激活后提示找不到许可证 xff1f 今日小编找到一个解决办法 xff1a 原来是在启动程序中注册了office的授权系统监控程序 com microsoft office l
  • Mac 外接显示器色彩不正常解决方案

    使用 MacBook和MacMini使用外接第三方非 Apple 认证的显示器会有色彩问题 xff0c 可能是显示器颜色整体发灰 xff0c 也有可能绿色特别绿 这是因为Apple封闭的系统识别的显示器较少 xff0c 第三方厂商也未很好的
  • mybatis-xml配置

    xff08 一 xff09 先配置datasource properties配置文件 xff1a xff08 此步可省略 xff09 jdbc driver 61 com mysql jdbc Driver jdbc url 61 jdbc
  • ArchiCAD 24 Mac版3D建筑模型设计和分析软件新功能介绍

    ArchiCAD 24 Mac破解版全新上线 xff0c 有哪些新增功能 xff1f 小编给大家带来了这篇ArchiCAD 24 Mac版3D建筑模型设计和分析软件新功能介绍的文章 xff0c 希望可以帮到你 设计 创建集成模型 使用Arc
  • MacBook不断重启的 5 个原因以及如何解决此问题

    您的 Mac 是否突然无故重启 xff1f 您外出回来时 xff0c 突然发现您的 Mac 正在神秘地关闭并重新启动 xff0c 这非常令人生气 如果重新启动问题变得更加严重 xff0c 您的 MacBook可能根本无法使用 小编将为您带来
  • 如何使用Super Vectorizer在Mac上快速矢量化图像?

    如何在 Mac 上将 PDF 转换为SVG矢量 xff1f 有需要的朋友快来跟小编看看具体做法吧 xff01 步骤 1 xff1a 在 Mac 上打开 Super Image Vectorizer 将图像文件导入 Super Vectori
  • Mac电脑怎么使用ping命令?

    电脑出问题了 xff0c 上不了网 xff0c 想排查下电脑的问题出在哪儿就需要用到ping xff0c 但是如果是Mac电脑该如何ping呢 xff1f 其实在Mac 自带的 终端 中使用ping命令 xff0c 下面小编教你如何在Mac
  • 安装VMware Workstation Pro 16 教程,Ubuntu 18 桌面版安装教程

    目录 1 VMware Workstation 16 Pro 安装教程 2 Ubuntu 18 桌面版安装教程 1 VMware Workstation 16 Pro 安装教程 1 第一步 xff1a 到官网进行下载软件 xff0c 下载
  • STM32 创建LED工程,点亮LED

    容忍5V电压 FT 61 FIve Tolerate 允许5V 寄存器就是特殊的存储器 上拉输入和下拉输入 如果输入啥都不接 xff0c IO口输入电平极容易受外部电平干扰 xff0c 加上拉电阻就是为了保护输入引脚的电平 为了避免引脚悬空
  • C语言枚举使用技巧

    什么是C语言枚举 C语言枚举是一种用户自定义数据类型 xff0c 它允许程序员定义一个变量 xff0c 并将其限制为一组预定义的常量 这些常量被称为 枚举值 xff0c 并且可以通过名称进行引用 在C语言中 xff0c 枚举值是整数类型 x
  • 关于win10系统打开VMware虚拟机蓝屏的解决方案

    先说结论 xff1a 不要急着更改系统配置甚至重装系统 xff0c 首先检查自己的VMware版本 xff0c 如果为16 1或以前 xff0c 请将原先的版本升级为VMware17 0版本 xff01 xff01 xff01 本人当前电脑
  • 洛谷P1025

    这道题类似于把n个苹果放到k个盘子里且不能空盘子的问题 递归 xff08 dfs xff09 做法 include lt bits stdc 43 43 h gt define LL long long using namespace st
  • windows权限维持之shift后门

    原理 xff1a 沾滞键的目的是为了帮助那些按键有困难的人设计的 xff0c 在Windows系统下连续按5次shift键后 xff0c 系统就会执行C Windows System32下的sethc exe xff0c 也就是启用了沾滞键
  • PostgreSQL数据库smallint、bigint转到Oracle,要用什么类型替代? 是number么,那长度分别是多少?...

    个人意见 xff0c 仅供参考 xff1a smallint是有符号或无符号2字节的整数 xff0c 范围是0 xff5e 65 536 xff0c 5位整数 bigint是有符号或无符号8字节的整数 xff0c 范围是0 xff5e 18
  • 网络安全计算机基础

    计算机网络概念 xff1a 实际上是将分布在不同地理位置 xff0c 且具有独立功能的计算机 通过通信链路以及通信设备 xff0c 在网络操作系统 xff0c 网络管理软件及网络通信协议的管理和协调下实现信息传输与资源共享形成的计算机系统
  • ImportError:No module named ‘PIL‘

    运行时报错 xff1a ImportError No module named 39 PIL 原因是缺失一个pillow的数据包 xff0c 不能直接 pip install PIL xff0c 会提示找不到这个安装包 xff0c 需使用如
  • c++中#与##的作用

    1 c 43 43 中 用于把转换成字符串 define T A A 没有使用 using namespace std int main cout lt lt 34 T 2 34 lt lt T 2 lt lt endl cout lt l
  • 人工智能实验——八数码难题

    人工智能实验 八数码难题 人工智能实验 八数码难题 人工智能实验 八数码难题八数码难题简介八数码难题所用到的算法简介代码实现解释运行结果显示代码附件程序可视化 八数码难题简介 八数码问题指的是定义一个3 times 3的格子 xff0c 然