一 题目要求:

八数码问题的A星搜索算法实现
        要求:设计估价函数,并采用c或python编程实现,以八数码为例演示A星算法的搜索过程,争取做到直观、清晰地演示算法,代码要适当加注释。
        八数码难题:在3×3方格棋盘上,分别放置了标有数字1,2,3,4,5,6,7,8的八张牌,初始状态S0可自己随机设定,使用的操作有:空格上移,空格左移,空格右移,空格下移。试采用A*算法编一程序实现这一搜索过程.

二 构造状态空间:

这个题目的状态空间描述为一组整数对(r,s,t,u,v,w,x,y,z)。
        每个字母分别对应八数码的每个位置,如下表所示。

r s t
u v w
x y z

表1-八数码状态空间对应关系

三 对题目的理解:

这个题目也应该采用树形结构来解,我觉得难点有二:

  1. 如何建立每个节点的数据结构;
  2. 因为是A*算法,所以公式f=g+h启发信息,如何在编程中体现。
    这里我是用Python写的算法,结点的数据结构如下:
class Point:def __init__(self, r, s, t, u, v, w, x, y, z):self.r = rself.s = sself.t = tself.u = uself.v = vself.w = wself.x = xself.y = yself.z = zself.g = 0self.f = 0  # f = g+hself.father = Noneself.node = [r, s, t, u, v, w, x, y, z]

首先定义了八数码问题的9个位置的值。比较重要的是Point结点的father属性,指明了子节点与父节点的关系,保证了树形结构的准确性。然后定义了g属性,来保存节点的深度,f属性为g+h的和,这样就保证了启发信息。

  1. 后来遇到个Python特有的bug,就是def了一个函数,然后传参,就算我用=号复制了一个list,原来的参数也会被改变,因为他们的指针都是一样的。解决方法是用copy.copy(list),这样复制就不是同一个指针了。

四 算法代码:

见报告最后。

五 代码解释:

  1. 首先定义了open表、closed表,声明了Point类,定义了初始节点init(2, 0, 3, 1, 8, 4, 7, 6, 5)和目的节点(1, 2, 3, 8, 4, 5, 0, 7, 6)。
  2. 在开始进行A_star(A*)算法之前,先定义几个函数:
    1) getKey:找出Point节点中0(即空格)的位置索引;
    2) up:空格上移函数。把某节点的空格和上方位置的值交换(考虑了溢出问题,即第一行不能up);
    3) down:空格下移函数。同上;
    4) left:空格左移函数。同上;
    5) right:空格右移函数。同上;
    6) h:启发函数。将某个节点与目的节点比较,返回位置不同的数目;
    7) equal:判断两个节点是否相同;
    8) open_sort:把open表里面的节点,按照属性f的值,排序;
    9) in_list:判断节点是否在open表或者closed表已经存在。
  3. 开始编写A*算法:
    1) 首先,先把初始节点init放入到OPEN表中,然后遍历OPEN表;
    2) 如果OPEN中取出的节点是目的节点goal,那么结束遍历;否则把这个节点从OPEN表取出,放入CLOUSED表;
    3) 然后根据此节点,来得到它的子节点,通过上、下、左、右四个方向来获取四个新节点,然后对四个节点遍历;
    4) 把该节点的f属性、father属性、g属性指定好。判断该new节点是否已经出现在open表中,如果已经出现了而且它的f属性值更好,说明它更优,那么把之前的移除,把这个插入。Open表同理。如果该new节点在open表和closed表都没有,那么把它直接插入到open表。最后根据f属性的值,对open表的节点排序
    4 最后打印一下路径,就可显示出解。

六 算法输出分析:

如图1是以初始节点init(2, 0, 3, 1, 8, 4, 7, 6, 5)和目的节点(1, 2, 3, 8, 4, 5, 0, 7, 6)运行的程序输出。根据OPEN表画出树形图如图2。

图1-程序输出

图2-分析过程

附:Python算法

import copy
import operatorOPEN = []  # open表
CLOSED = []  # closed表class Point:def __init__(self, r, s, t, u, v, w, x, y, z):self.r = rself.s = sself.t = tself.u = uself.v = vself.w = wself.x = xself.y = yself.z = zself.g = 0self.f = 0  # f = g+hself.father = Noneself.node = [r, s, t, u, v, w, x, y, z]init = Point(2, 0, 3, 1, 8, 4, 7, 6, 5)  # 初始节点
goal = Point(1, 2, 3, 8, 0, 4, 7, 6, 5)  # 目标# 返回空位的index值
def getKey(s):return s.node.index(0)def up(s, key):if key - 3 >= 0:arr = copy.copy(s.node)arr[key], arr[key - 3] = arr[key - 3], arr[key]return Point(arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6], arr[7], arr[8])else:return Nonedef down(s, key):if key + 3 <= 8:arr = copy.copy(s.node)arr[key], arr[key + 3] = arr[key + 3], arr[key]return Point(arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6], arr[7], arr[8])else:return Nonedef left(s, key):if key != 0 and key != 3 and key != 6:arr = copy.copy(s.node)arr[key], arr[key - 1] = arr[key - 1], arr[key]return Point(arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6], arr[7], arr[8])else:return Nonedef right(s, key):if key != 2 and key != 5 and key != 8:arr = copy.copy(s.node)arr[key], arr[key + 1] = arr[key + 1], arr[key]return Point(arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6], arr[7], arr[8])else:return None# 启发函数
def h(s, p=goal):flag = 0for i in range(0, 9):if s.node[i] != p.node[i]:flag += 1return flagdef equal(a, b):if a.node == b.node:return True# 将open_list以f值进行排序
def open_sort(l):the_key = operator.attrgetter('f')  # 指定属性排序的keyl.sort(key=the_key)# 扩展节点时在open表和closed表中找原来是否存在相同属性的节点
def in_list(new, l):for item in l:if new.node == item.node:return True, itemreturn False, Nonedef A_star(s):global OPEN, CLOSEDOPEN = [s]CLOSED = []while OPEN:  # open表非空get = OPEN[0]  # 取出open表第一个元素getif get.node == goal.node:  # 判断是否为目标节点return getOPEN.remove(get)  # 将get从open表移出CLOSED.append(get)  # 将get加入closed表# 以下得到一个get的新子节点new并考虑是否放入OPENkey = getKey(get)for i in range(0, 4):  # 四个方向if i == 0:new = up(get, key)elif i == 1:new = down(get, key)elif i == 2:new = left(get, key)elif i == 3:new = right(get, key)if new == None:  # 状态非法或new折返了pass# 如果要拓展的节点满足以上情况,将它的父亲设为当前节点,计算f,并对open_list排序else:new.father = getnew.g = get.g + 1  # 与起点的距离new.f = get.g + h(new)  # f = g + h# 如果new在open表中(只关注m,c,b的值)if in_list(new, OPEN)[0]:old = in_list(new, OPEN)[1]if new.f < old.f:  # new的f<open表相同状态的fOPEN.remove(old)OPEN.append(new)open_sort(OPEN)else:pass# 继续,如果new在closed表中elif in_list(new, CLOSED)[0]:old = in_list(new, CLOSED)[1]if new.f < old.f:# 将old从closed删除,并重新加入openCLOSED.remove(old)OPEN.append(new)open_sort(OPEN)else:passelse:OPEN.append(new)open_sort(OPEN)print('OPEN:')for o in OPEN:print(o.node,o.f,o.g)# 递归打印路径
def printPath(f):if f is None:returnprintPath(f.father)print(f.node)if __name__ == '__main__':final = A_star(init)if final:print('有解,解为:')printPath(final)else:print('无解!')

AI 八数码A_star算法问题-实验报告相关推荐

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

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

  2. c语言八数码A星算法代码解析,八数码问题c语言a星算法详细实验报告含代码解析...

    八数码问题c语言a星算法详细实验报告含代码解析 (13页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 14.9 积分 一.实验内容和要求 八数码问题:在3 ...

  3. led数码显示控制plc实验_实验三LED数码显示控制PLC实验报告.doc

    实验三LED数码显示控制PLC实验报告 广州大学学生实验报告 开课学院及实验室:工程北529 2015年 5 月28 日 学院机械与电气工程年级.专业.班姓名学号实验课程名称 电气控制与可编程控制器成 ...

  4. 银行家算法的实验报告

    银行家算法的实验报告 一.实验内容 银行家算法是避免死锁的一种重要方法,本实验要求编写和调试一个简单的银行家算法程序. 1.设计进程对各类资源最大申请表示及初值的确定. 2.设定系统提供资源的初始状况 ...

  5. 南京邮电大学c语言实验报告4,南京邮电大学算法设计实验报告——动态规划法...

    <南京邮电大学算法设计实验报告--动态规划法>由会员分享,可在线阅读,更多相关<南京邮电大学算法设计实验报告--动态规划法(12页珍藏版)>请在人人文库网上搜索. 1.实 验 ...

  6. python实现循环赛日程表问题的算法_循环赛日程表的分治算法实现实验报告gxl.doc...

    循环赛日程表的分治算法实现实验报告gxl PAGE PAGE 2 深 圳 大 学 实 验 报 告 课程名称: 算法设计与分析 实验项目名称: 分治算法 --矩阵相乘的Strassen算法及时间复杂性分 ...

  7. python实现循环赛日程表问题的算法_循环赛日程表的分治算法实现实验报告_gxl.doc...

    循环赛日程表的分治算法实现实验报告_gxl 深 圳 大 学 实 验 报 告 课程名称: 算法设计与分析 实验项目名称: 分治算法 --矩阵相乘的Strassen算法及时间复杂性分析 或--循环赛日程表 ...

  8. 数码显示实验报告C语言,数码问题C语言A星算法详细实验报告含代码(9页)-原创力文档...

    一.实验内容和要求 八数码问题:在3×3的方格棋盘上,摆放着1到8这八个数码,有1个方格是空的,其初始状态如图1所示,要求对空格执行空格左移.空格右移.空格上移和空格下移这四个操作使得棋盘从初始状态到 ...

  9. led数码显示控制plc实验_实验三 LED数码显示控制 PLC实验报告

    广州大学学生实验报告 开课学院及实验室:工程北 529 2015 年 5 月 28 日 学院 机械与电气 工程 年级. 专 业.班 姓名 学号 实验课程名称 电气控制与可编程控制器 成绩 实验项目名称 ...

最新文章

  1. C++中substr()函数用法详解
  2. python在线读-python初级实战-----主机在线情况监控web
  3. JavaScript Set Homepage and Favorite
  4. 如何成为有效学习的高手(许岑)——思维导图
  5. [vue] 如果现在让你从vue/react/angularjs三个中选择一个,你会选哪个?说说你的理由
  6. 【职业生涯】这样的开发人员每个团队都想要
  7. SenchaTouch2.3.1 中使用listpaging以及pullrefresh插件 做的分页示例
  8. oracle外关联更新操作,记要oracle 关联更新的例子
  9. TFS 无法找到新加的Windows用户
  10. 杭电3068 最长回文 最长回文的manacher算法
  11. cdh 安装_使用Cloudera的CDH部署Hadoop:第二步,安装JDK
  12. 【MIKE21】批处理依次打开模型文件运行模型
  13. 最小二乘法 c 语言程序,最小二乘法的嵌入式C语言实现
  14. 计算机电缆国家标准是什么,计算机电缆执行标准是什么
  15. 海贼王剧场版:Z 剧情详解(附TS无字幕版地址)
  16. 无线路由器使用交换机模式上网不稳定
  17. RadioButtonList功能汇总
  18. Matlab绘图-很详细,很全面
  19. ONVIFclient搜索设备获取rtsp解决开发笔记(精华文章)
  20. refind 0.10.3 配置文件refind.conf简单分析

热门文章

  1. react antd form 表单清空
  2. SpringMVC 如何实现将消息的websocket
  3. 第六课.Python函数(三)
  4. mysql的配置文件几个_mysql多实例(多个配置文件方式)
  5. 全变量进气系统伺服马_三种伺服电动缸系统的特点
  6. 中科院微生物所王军课题组建立靶向RNA的病原检测新方法mtNGS和mtTGS
  7. NC:王金锋等揭示阴道菌群异位对子宫健康的影响
  8. 宏基因组蚂蚁森林公益合种树项目,支持祖国绿化事业,让世界更美好
  9. MetaPhlAn2:宏基因组物种组成分析
  10. R语言单变量分析实战:汇总统计(Summary Statistics)、频率表(Frequency Table)、图表(charts: boxplot、histogram、density)