1.实验题目

A*算法求解N数码问题,要求程序内,输入给定初始状态和目标状态,输出所需步数,过程状态及时间(程序可直接运行,无需再手动输入)。

2.实验目的及要求

  • 熟悉和掌握启发式搜索的定义、估价函数和算法过程
  • 利用A*算法求解N数码难题,理解求解流程和搜索顺序
  • 熟练掌握numpy库的相关函数

3.实验原理

A*算法是一种启发式图搜索算法,其特点在于对估价函数的定义上。对于一般的启发式图搜索,总是选择估价函数f值最小的结点作为扩展结点。因此,f是根据需要找到一条最小代价路径的观点来估算结点的,所以,可考虑每个结点n的估价函数值为两个分量:从起始结点到结点n的实际代价以及从结点n到达目标结点的估价代价。
启发式图搜索的基本特点:如何寻找并设计一个与问题有关的h(n)以及构出f(n)=g(n)+h(n),然后以f(n)的大小来排列待扩展状态的次序,每次选择f(n)的最小值进行扩展。

  • open表:保留所有已生成而未扩展的状态
  • closed表:记录已扩展后的状态
    进入open表的状态是根据估值的大小插入到表中合适的位置,每次从表中优先取出启发估价函数值最小的状态加以扩展。

4.实验内容

  1. 以8数码问题为例实现A*算法的求解程序
    original state:
2 8 3
1 6 4
7 5

target state:

1 2 3
8 4
7 6 5

估价函数f(n)=g(n)+h(n)
g(n)=d(n) ------结点n在搜索树中的深度
h(n)可选择h1(n) — 结点n中“不在位”的数码个数 或 h2(n)=p(n)–当前状态到终点的曼哈顿距离
2. 在求解8数码问题的A* 算法程序中,设置相同的初始状态和目标状态,针对不同的估价函数,求得问题的解,并比较它们对搜索算法性能的影响,包括扩展结点数、生成结点数等
3. 画出A*算法求解框图

5.实验分析

每移动一次空格,就产生一种状态。使用BFS来搜索,但这里使用优先队列而不是普通的队列,这样就可以利用A*算法的核心——评估函数f(n)=g(n)+h(n),对每一种状态用评估函数进行优先队列的排序(只要你给了评估函数的值,优先队列会自己帮我们排序)。
搜索过程如下:

6.代码实现

from queue import PriorityQueue
import datetimeclass node:def __lt__(self,other):return self.cost < other.costdef __init__(self,n,s,p):self.num = n#str的数组self.step = s#当前已经走了的步数,intself.zeroPos = p#0的位置,intself.cost = 0self.parent = None#父指针self.setCost()def setCost(self):global descount = 0for i in range(len(des)):if self.num[i] != des[i]:count += 1self.cost = count + self.stepdef setParent(self,father):self.parent = fatherdef swap(li,first,second):temp = li[first]li[first] = li[second]li[second] = tempdef format_p(s,N):for i in range(N):print('\t'.join(s[i*N:(i+1)*N]))print()def makeChangeId(N):#根据N实现changeIdli = []MAX = N**2for i in range(MAX):temp = []row = i//N#行col = i%N#列if row is not 0:#上,如果行为0,那么肯定不往上移动了temp.append(i-N)else:temp.append(-1)if col is not 0:#左temp.append(i-1)else:temp.append(-1)if row is not N-1:#下temp.append(i+N)else:temp.append(-1)        if col is not N-1:#右temp.append(i+1)else:temp.append(-1)li.append(temp)return lidef bfs(start,zeroPos):#start is str's list#zeroPos is intglobal changeId,visit,que,des,N#该函数返回最后一个状态即最后一个nodestartNode = node(start,0,zeroPos)que.put(startNode)while(not que.empty()):outNode = que.get()strList = outNode.num#这里是liststrTuple = tuple(strList)#状态表示,这里是tupleif strTuple in visit:continuevisit[strTuple] = 1pos = outNode.zeroPos#零的位置for i in range(4):if changeId[pos][i] != -1:swap(strList,pos,changeId[pos][i])               joinTuple = tuple(strList)if strList == des:print('bingo')swap(strList,pos,changeId[pos][i])#找到了先交换回去,因为这里strList是状态对象的成员了,直接返回的话,就不会执行#下面那句swap了,所以这里得加上一句swapreturn outNodeif joinTuple not in visit:new = node(strList.copy(),outNode.step+1,changeId[pos][i])#注意这里必须使用copy,因为不复制传进去的就只是个引用,会导致所有node的成员都是同一个listnew.setParent(outNode)que.put(new)swap(strList,pos,changeId[pos][i])visit = dict()
que = PriorityQueue()
print('Please input N:')
N = eval(input())
print('Please input the original state:')
src = input().split()#和之前不同,这里存的都是str的list
print('Please input the target state:')
des = input().split()
for i in range(len(src)):if src[i] == '0':break
start_t = datetime.datetime.now()
changeId = makeChangeId(N)
last = bfs(src,i)result = [des]#先装des,用作栈使用def findroot(last,result):result.append(last.num)if last.parent == None:returnelse:findroot(last.parent,result)findroot(last,result)end_t = datetime.datetime.now()
print('The transition from original state to the target state:')
while(len(result)):format_p(result.pop(),N)
print('Step number:'+str(last.step+1)+'steps')
print("time = ", (end_t - start_t).total_seconds(), "s")
print('end')

A*算法求解N数码问题(AI实验一)相关推荐

  1. 【人工智能实验】A*算法求解8数码问题

    目录 实验一 A*算法求解8数码问题 一.实验目的 二.实验原理 三.实验结果 四.实验总结 附录代码 推荐文章 实验一 A*算法求解8数码问题 一.实验目的 熟悉和掌握启发式搜索的定义.估价函数和算 ...

  2. 【人工智能导论】A*算法求解15数码问题 Java

    完整源码 - Eclipse项目文件 - GitHub地址 题目描述 关于本算法 两个晚上写完的,不足之处多多指教- 启发函数的选择: 一开始选用不在位数码个数+节点深度作为启发函数,效果不是很好. ...

  3. 15数码 java_A*算法求解15数码问题

    目录 一.问题描述 二.算法简介 三.算法步骤 四.评估函数 五.参考资料 六.源代码(Java实现) 一.问题描述 利用A*算法进行表1到表2的转换,要求空白块移动次数最少. 转换规则为:空白块只可 ...

  4. A*算法求解15数码问题

    目录 一.问题描述 二.算法简介 三.算法步骤 四.评估函数 五.参考资料 六.源代码(Java实现) 一.问题描述 利用A*算法进行表1到表2的转换,要求空白块移动次数最少. 转换规则为:空白块只可 ...

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

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

  6. matlab 求解最短路问题,matlab算法求解最短路问题.doc

    matlab算法求解最短路问题.doc 组合优化实验报告实验序号日期班级姓名学号实验名称最短路问题实验所用软件及版本MATLABR2008B1.实验目的1.掌握最短路问题的一种求解算法,并能编程实现该 ...

  7. a星算法实现8数码问题c语言,A星算法求八数码问题实验报告.doc

    A星算法求八数码问题实验报告.doc 人工智能实验报告实验名称八数码问题姓名xx学号2012210 xx xx计算机学院 2014年1月14日1 实验目的 掌握A*的思想,启发式搜索,来求解在代价最小 ...

  8. AlphaBeta剪枝算法求解博弈树最优选择 头歌实验平台

    AlphaBeta剪枝算法求解博弈树最优选择 头歌实验平台 前言 一.AlphaBeta剪枝是什么? 1.由来, 最大最小决策树 2.发展 3. AlphaBeta剪枝 二.实验算法伪代码 三.实验算 ...

  9. 八数码问题a*算法c语言,八数码问题的A*算法求解

    A*算法是启发式搜素算法中较为出名和高效的算法之一,其关键是对于启发式函数的实际,启发式函数h(x)需要尽可能的接近实际的 .下面是人工智能八数码问题使用A*算法求解的源码放在博客上记录一下.程序使用 ...

最新文章

  1. kafka模拟生产-消费者以及自定义分区
  2. Python教程:import与from ... import ...的区别
  3. GNU make manual 翻译( 一百零四)
  4. python信用卡违约预测分析_Python数据分析及可视化实例之银行信用卡违约预测(24)...
  5. 线上讲座——全国海关中心架构师王翔畅谈设计模式
  6. 连续与离散变量的函数分布计算
  7. mac安装指定版本的ruby_Mac 下安装Ruby环境
  8. java粘包_Java网络通信基础系列-Netty粘包与拆包
  9. Java 判断IP地址为内网IP还是公网IP (针对IPv地址)
  10. 禁止div被拖动 css,【Web前端问题】div在拖动时出现禁止图标
  11. 中国不承认国际驾驶证
  12. 关于人工神经网络的论文,人工神经网络参考文献
  13. Arcgis js api 点聚合
  14. OKR教练:OKRs-E如何帮你落地OKR
  15. 换电脑了大量数据如何迁移?
  16. K8S使用ceph-csi持久化存储之cephfs部署验证快照
  17. 一键生成各种姿势的火柴人gif:在线录制真人视频即可转换 | 代码开源
  18. abd命令 之 按键精灵 lua: huiyitool.lua
  19. Elasticsearch学习2 SpringBoot整合 测试复杂检索
  20. 【15分钟读万字文】聚焦人的需求,思考下一代互联网基础平台

热门文章

  1. 不用Python获取小红书收藏夹内的视频
  2. Quercus 介绍: 这个TMD对我太用了,终于在JAVA和PHP找到平衡点了
  3. Biome-BGC简介
  4. jpa双向多对多关系
  5. 高性能嵌入式RK3399应用于智能会议平板解决方案
  6. moment typescript报错TS2307
  7. 地方标准、行业标准、国家标准查询网址汇总
  8. vim 键盘图,桌面背景的最佳选择
  9. scrapy爬动态网址哔哩哔哩
  10. Python 入门之类的基础语法