八数码问题(人工智能实验)

991 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

备注

大连海事大学人工智能实验一:八数码、十五数码问题python求解

一、实验环境

Python3.7,Pycharm

代码的介绍: 第三行决定求解八数码问题还是十五数码问题:

image.png

输入求解数码矩阵在代码中17行(八数码)和20行(十五数码)中直接写入:

image.png

二、实验目的

  1. 熟悉掌握启发式搜索算法A*及其可采纳性 

  2. 编写程序实现8数码和15数码问题,采用至少两种估价函数

  3. 分析估价函数求解问题时候的效率差别,分析估价函数对搜索算法的影响

三、实验原理

3.1.设计思想

  1. 根据启发式搜索算法的连续搜索特征,整体上算法选择采用递归思想来设计。

  2. 对整体上估价函数值最小的、未被拓展的矩阵进行拓展,每递归一次将会有一个矩阵被拓展,将其在未被拓展的列表中删除

  3. 为了展示最短移动路径需要将不同的数码矩阵建立联系,算法采用定义类的方法将每一个数码矩阵定义为一个节点,然后在递归拓展时将当前数码矩阵设为其拓展的子数码矩阵的父节点

3.2.解决方案

问题1:空格所在位置不同则移动方式不同,需要多重判断才能确定移动方式

  • 解决方案:采用最常用的多重判断,简单有效。

image.png

问题2:可能出现一个状态重复出现的情况,如空位向左移后再向右移导致状态重复

  • 解决方案:将所有已拓展和未拓展的矩阵都储存在一个列表内,每次拓展的子节点都和其中所有的状态比对,相同则删除。
for PX in P2LIST:
    flag = 0
    ZPLIST=CPLIST+OPLIST
    for PY in ZPLIST:  # 防止出现重复的情况
        if (getp(PX, PY.matrix) == 0):
            flag = 1
    if (flag == 1):
        del P2LIST[f]
    f = f + 1

问题3:PYTHON没有结构体和指针,查看路径时两个节点没有直接联系很难回溯

  • 解决方案:创建类建立父子关系,每次拓展的节点都为被拓展节点的父节点。
class P:
    def __init__(self,matrix,g):
        self.matrix=matrix
        self.father=None
        self.g=g
    def setg(self,g):
            self.g=g
    def setfather(self,B):
        self.father=B

for PX in P2LIST:
    PN=P(PX,P0.g+1)#创建节点
    PN.setfather(P0)#构建关系

3.3.完整代码

gitee链接

欢迎star、fork,(学妹的话私信也不介意)

四、实验结果

4.1输入:

  1. 估价函数:#获取初始矩阵每一数码与目标矩阵位置错位的数目
L1 = np.mat(np.array([4,1,3,2,0,5,7,8,6]).reshape(3, 3))#八数码

L1=np.mat(np.array([0,1,3,4,5,2,6,8,9,10,7,11,13,14,15,12]).reshape(4,4))#十五数码
  1. 估价函数:#获取两个矩阵每一数码与目标数码之间的距离总和
L1 = np.mat(np.array([4,1,3,2,0,5,7,8,6]).reshape(3, 3))#八数码

L1=np.mat(np.array([0,1,3,4,5,2,6,8,9,10,7,11,13,14,15,12]).reshape(4,4))#十五数码

4.2输出:

估价函数1.八数码

image.png

估价函数1.十五数码

image.png

估价函数2.八数码

image.png

估价函数2.十五数码

image.png

五、实验总结

1. 实验数据(运行时间和拓展节点个数):

  • 规定:

估价函数1:(获取初始矩阵每一数码与目标矩阵位置错位的数目)

估价函数2:(获取两个矩阵每一数码与目标数码之间的距离总和)

  • 数据:

估价函数1八数码问题三次用时:0.004987,0.005984,0.006976,创建节点个数:20

估价函数1十五数码问题三次用时:0.009016,0.008026,0.007978,创建节点个数:16

估价函数2八数码问题三次用时:042844,0.045538,0.044170,创建节点个数:18

估价函数2十五数码问题三次用时:0.090118,0.092403,0.082812,创建节点个数:16

 

平均用时八数码十五数码
估价函数10.0059820.008340
估价函数20.0441840.088444

2.实验结论:

从数据来看,两者解决问题用时相差十倍左右,估价函数1相比估价函数2解决问题用时显著更短;两者创造节点个数近乎相等,估价函数1相比估价函数2创造节点个数略多,但相差并不明显。

因此可得出结论,估价函数1求解问题的效率更高。

个人总结:

为了更好地理解八数码问题的求解思路。贴个全部搜索路径图:(以一个八数码问题为例)

image.png