资源下载地址:https://download.csdn.net/download/sheziqiong/86790565
资源下载地址:https://download.csdn.net/download/sheziqiong/86790565

利用 A *算法解决八数码问题

摘要

利用 A 算法解决八数码问题,比较不同启发函数(h1,h2)的搜索效率,并验证关于 A 算法的命题。

导言

本实验主要使用 A*算法解决八数码问题。

八数码问题主要是由 8 个 1-8 的数字以及一个空格组成一个九宫格,通过移动空格若干次使得九宫格中数字到达以下目标状态:

1 2 3
8 4
7 6 5

对于每个状态,可以往不同方向移动空格使得该状态产生多个不同的新状态作为后继节点,于是对于候选状态的选择策略可以有 BFS、DFS、启发式搜索等。对于八数码问题,我们可以理解成一种路径搜索问题,以其实状态为起点,目标状态为终点,进行搜索。每个节点的可搜索路径为其空格往四个(或更少)方向移动后得到的、不属于其前驱节点的状态。

实验过程

A 算法即对于候选节点每个节点 n,有 f(n),根据 f(n)排序并选择最优者。其中 f(n)定义为

其中 g(n)为起始状态到 n 的距离,h(n)为 n 到目标状态的预估距离。

若进一步规定 h(n)≥0,并且定义:

其中,f*(n)表示起点经过 n 到终点的最优路径搜索费;g*(n)表示起点到 n 的实际最小费用;h*(n)表示 n 到终点的实际最小费用的估计。

当要求 h(n)≤h*(n),就称这种 A 算法为 A*算法。

A*算法解决八数码问题的主要流程如下:

设 S0 为起始状态,Sg 为目标状态:

Open={ S0}

Closed={}

如果 Open={},失败退出

在 Open 表中取出其末尾元素 n,n 放到 Closed 表中

若 n∈Sg,则成功退出。

产生 n 的一切非 n 前驱节点的后继,并构成集合 M。

对 M 中的元素 P,分别作两类处理:

若 P G(G=Open+Closed),说明 P 并未被搜索到过,则将其计算 f(n),并将其插入 Open 表的合适位置,维护 Open 表从大到小的顺序,并将其加入 G 表中。(这里 f(n)=g(n)+h(n),根据不同 h(n)有不同的启发式函数,不同的搜索策略)

若 P∈G,说明 P 已经是别的节点的后序节点,则比较从 n 到 P 以及从 P.father 到 P 的消耗,并决定是否更改 P.father转第三步

在我的代码中,用一个类保存一个状态,每个状态包括一个节点的九宫格信息以及其父节点的指针。即,Tree 的信息跟每个节点的状态存储在一个对象中。

在算法退出后,保存最后得到的目标状态,一路根据其 node.father 追溯到根节点(起始状态),再逆序,即可得到路径。

使用的 f(n)中 h1(n)为九宫格中格子与数字不对应的个数,h2(n)为九宫格中每个格子中数字到正确位置需要消耗(横向纵向移动次数总和),即曼哈顿距离之和。比较两者 Open 表长度和到达目标的步数。

结果分析

运行环境为 windows10,Intel Core i5-8400 2.81GHz,RAM 2667MHz 16GB

编译器 PyCharm,语言 Python3

利用 A*算法求解八数码问题,在输出界面上动态显示 OPEN 表的结点数和评估函值最小的结点

比较两种启发函数(上课和书上讲到的 h1(n)和 h2(n))的搜索效率,在输出界面上动态显示 OPEN 表的结点数、总扩展的结点数和评估函值最小的结点

输出 OPEN 表中在最佳路径上的结点及其评估函数值。

先使用课本上的样例进行测试:

2 8 3
1 6 4
7 5
迭代次数 h1(n) h2(n)
1
2
3
4
5
6
7 结束
路径

观察上表可以看到,h2(n)可以迭代更少次数,而且 Open 表和 G 表讲更短。

随机选取了 5 个可行测例,比较 h1(n)与 h2(n)的效率:

测例 h1(n)(迭代数/耗时) h2(n)(迭代数/耗时)
[1, 2, 4];[3, 8, 6];[5, 0, 7] Step: 6034 ;Cost: 9.5 s Step: 928 ;Cost: 0.30 s
[0, 3, 8];[7, 4, 6];[2, 1, 5] Step: 3126 ;Cost: 2.3 s Step: 240 ;Cost: 0.03 s
[7, 6, 3];[8, 2, 1];[0, 5, 4] Step: 3352 ;Cost: 2.5 s Step: 489 ;Cost: 0.09 s
[0, 7, 8];[5, 1, 3];[2, 4, 6] Step: 2968 ;Cost: 1.9 s Step: 150 ;Cost: 0.02 s
[6, 3, 2];[7, 5, 8];[1, 0, 4] Step: 5902 ;Cost: 8.0 s Step: 611 ;Cost: 0.13 s
[2, 7, 0];[8, 4, 1];[3, 5, 6] Step: 38166 ;Cost: 322.7 s Step: 3730 ;Cost: 3.37 s

可以很清晰比较到两者的差距,具有更多信息的 h2 的将更快搜索到目标。

验证凡 A 算法挑选出来求后继的点 n 必定满足: f(n)≤f(S0):

f*(S0)表示实际最小费用,用

路径长-1 表示。(len(path)表示路径经过的点,减 1 后则为路径边的个数)

随机三个可行测例进行三个测试(使用 h2(n))

f*(S0) f(n)范围
[5, 6, 8], [3, 0, 4], [7, 1, 2] 24 [18, 24]
[5, 7, 6], [0, 2, 4], [1, 8, 3] 25 [17, 25]
[2, 4, 6], [7, 3, 1], [0, 8, 5] 24 [14, 24]

验证 h1(n)的单调性,显示凡 A*算法挑选出来求后继的点 ni 扩展的一个子结点 nj,检查是否满足: h(ni)≤1+h(nj):

这里使用了课本上的测例,随机测例由于步数过多无法写进报告。因此对于随机测例,我在添加了如下代码:

对于每个扩展的 P(即 nj)作判断,若有违反命题的则打印。结果没有打印。

如果将空格看作 0,即九数码问题,利用相似的启发函数 h1(n)和 h2(n),求解相同的问题的搜索图是否相同?

不一样。

当初始起点如左图

把空格看作 0,h1(n)需要迭代步数 6882,h2(n)需要迭代步数 1352而空格不算入 h1(n)和 h2(n)的话,h1(n)需要迭代步数 6507,h2(n)需要迭代步数 1246每次迭代都要取节点并扩展,因此搜索图将是不一样的。

同时它也不是一个 A 算法。假设从目标状态回退一步(即 0 往任意方向与邻居交换),得到的状态的 h1(n)与 h2(n)都是 2,但实际其与目标的距离都是 1,违反了 h(n)<=h(n)的规则。

写出能否达到目标状态的判断方法

将 3*3 的格子以行为顺序排列成一行数组 A。

对于 A 中每个数字 n,定义 f(n)为 A 中数字 n 前面比 n 小的数字的个数。定义 SUM 为 f(1)到 f(8)的总和。

我们可以验证 SUM 的奇偶性将一直保持不变:

当空格左右移动,所有 f(n)都保持不变,SUM 不变

当空格向上移动(设与 n 交换),则在数组 A 中介于空格和 n 中的数有 2 个,记为 a, b。

  • < n and b < n,则 f(n) += 2,SUM += 2
  • < n and b > n,则 f(n) += 1,f(b) -= 1,SUM 不变
  • n and b > n,则 f(a) -= 1,f(b) -= 1,SUM -= 2

当空格向下移动,同理可以发现 SUM 永远以 2 为单位加减变化,其奇偶性不变,因此起点的奇偶性与终点的奇偶性需一样,这是可达的必要条件。

然而其充分性,我没有能力证明。

实际上应该使用 numpy 等提升数组操作的速率,然而发现这点时代码已经成型不方便改动。或者使用 Java,因为该项目不太需要作图。

资源下载地址:https://download.csdn.net/download/sheziqiong/86790565
资源下载地址:https://download.csdn.net/download/sheziqiong/86790565

Python利用A*算法解决八数码问题相关推荐

  1. Astar、A星算法解决八数码问题--python实现

    一.问题描述 数码问题又称9宫问题,与游戏"华容道"类似.意在给定的3*3棋格的8个格子内分别放一个符号,符号之间互不相同,余下的一格为空格.并且通常把8个符号在棋格上的排列顺序称 ...

  2. 题目2:隐式图的搜索问题(A*算法解决八数码)

    数据结构课程实践系列 题目1:学生成绩档案管理系统(实验准备) 题目2:隐式图的搜索问题(A*算法解决八数码) 题目3:文本文件单词的检索与计数(实验准备) 文章目录 数据结构课程实践系列 题目1:学 ...

  3. A*算法解决八数码问题 Java语言实现

    A*算法解决八数码问题 Java语言实现 参考文章: (1)A*算法解决八数码问题 Java语言实现 (2)https://www.cnblogs.com/beilin/p/5981483.html ...

  4. Python实现A*算法解决N数码问题

    Python实现A*算法解决N数码问题 A*算法的描述 A*算法的步骤 问题描述 代码以及测试结果 算法优势 算法存在一些不足 A*算法的描述 A*算法是BFS的一个变种,它把原来的BFS算法的无启发 ...

  5. Nilsson's sequence score算法解决八数码问题解释

    解决了最近一个人工智能关于解决八数码难题的作业. 图可能看不清,除了黑块外其他位置是英文字母ABCDEFGH A*:f(n)=g(n)+h(n) 其中f为总花费,g为已知花费(深度),h为估计花费 关 ...

  6. 全局择优搜索、A*算法、宽度优先算法解决八数码问题

    1问题描述 使用盲目搜索中的宽度优先搜索算法或者使用启发式搜索中的全局择优搜索或A算法,对任意的八数码问题给出求解结果.例如:对于如下具体的八数码问题: 通过设计启发函数,编程实现求解过程,如果问题有 ...

  7. A*算法解决八数码问题 人工智能原理实验报告 启发式搜索 python

    目录 一.实验主要步骤 ①.设计界面输入规则 ②.判断是否有解 ③.求解 二.实验结果展示 三.附录 完整实验程序代码: 一.实验主要步骤 ①.设计界面输入规则 有且仅有9位数字代表数码和空格,从左到 ...

  8. 题目2:隐式图的搜索问题(A*算法解决八数码)代码实现

    从起点 开始,把它加入到一个由方格组成的open list(开放列表) 中,这个open list像是一个购物清单.Open list里的格子是可能会是沿途经过的,也有可能不经过.因此可以将其看成一个 ...

  9. 人工智能实现a*算法解决八数码_小白带你学回溯算法

    微信公众号:小白算法 关注可了解更多算法,并能领取免费资料.问题或建议,请公众号留言;小白算法,简单白话算法,每个人都能看懂的算法 上一期算法回顾--贪婪法:https://mp.weixin.qq. ...

最新文章

  1. 百度“知识增强的跨模态语义理解技术”获国家技术发明奖
  2. kali linux 渗透测试 01 kali介绍
  3. wstring与string相互转换
  4. 小白2分钟学会Visual Studio将引用包打包到NuGet上
  5. 数据库和python的结合_MySQL数据库和Python如何结合?
  6. boost::log::sources::severity_logger用法的测试程序
  7. 米哈游CEO蔡浩宇GDC演讲:《原神》如何打造动人的开放世界?
  8. mockito mock测试框架
  9. CF605E-Intergalaxy Trips【期望dp】
  10. 【渝粤题库】国家开放大学2021春1313学前儿童卫生与保健题目
  11. c语言非法字符有哪些,98行的四则计算器.(支持括号)加入了非法字符的检测
  12. 高通计划通过多层级骁龙5G移动平台 加速5G商业化
  13. Java读取word中表格
  14. 攻防世界(Ctf-Web 新手练习区 Writeup)
  15. 能识别nvme的pe启动_学用系列|Mathpix,送给理科老师们的公式识别神器
  16. 昂达平板不能开机刷机_昂达平板刷机V811 V701 V702 V711刷错固件刷回方法
  17. access里面的表达式运用_Access 如何使用表达式生成器
  18. 雷神simplest_ffmpeg_player解析(四)
  19. 华三H3C端口聚合与链路聚合
  20. 【韧性架构】韧性性工程的重要性

热门文章

  1. ~scanf()和scanf()!=EOF
  2. SAP SD相关配置
  3. WEBGL 2D游戏引擎研发系列 第四章 感想以及矩阵
  4. java netty教程_Netty4.1初学者教程(HelloWorld教程)
  5. 【解决方案】IE浏览器提示 是否停止运行此脚本?此页面上的脚本造成Intenet Explorer运行速度减慢。
  6. c#上位机 源码 控制固高,研华,雷赛这类的运动板卡。偏向 程序运动控制。winform+板卡+sqlite
  7. Android 深入系统完全讲解(二)音视频理解攻略 PDF
  8. show version命令
  9. C语言volatile类型限定符详解
  10. 深山红叶安装到U盘(HDD方式)的另法