采用A算法解决八数码问题_第1页
采用A算法解决八数码问题_第2页
采用A算法解决八数码问题_第3页
采用A算法解决八数码问题_第4页
采用A算法解决八数码问题_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、人工智能实验一报告题目:采用A*算法解决八数码问题姓名:XXX学号:10S003028专业:计算机科学与技术提交日期:2011-05-04目录1 问题描述 - 2 -1.1 待解决问题的解释- 2 -1.2 问题的搜索形式描述 - 2 -1.3 解决方案介绍(原理) - 3 -2算法介绍 - 4 -2.1 A*搜索算法一般介绍 -4 -2.2 算法伪代码- 4 -3算法实现 - 5 -3.1 实验环境与问题规模 - 5 -3.2 数据结构 - 5 -3.3 实验结果 - 6 -3.4 系统中间及最终输出结果- 6 -4 参考文献 - 7 -5附录源代码及其注释 - 7 -1问题描述所谓八数码问

2、题是指这样一种游戏:将分别标有数字 1, 2, 3,,8的八 块正方形数码牌任意地放在一块3X3的数码盘上。放牌时要求不能重叠。于是, 在3X3的数码盘上出现了一个空格。现在要求按照每次只能将与空格相邻的数 码牌与空格交换的原则,不断移动该空格方块以使其和相邻的方块互换,直至达 到所定义的目标状态。空格方块在中间位置时有上、下、左、右 4个方向可移动, 在四个角落上有2个方向可移动,在其他位置上有3个方向可移动,问题描述如下 图1-1所示:1.1 待解决问题的解释首先,八数码问题包括一个初始状态(START)和目标状态(END),所谓解决 八数码问题就是在两个状态间寻找一系列可过渡状态:(ST

3、ARTSTATE1STATE2.END)这个状态是否存在就是我们要解决的第一个问题:Q1:每一个状态及每一次操作的表示方法?有许多表示方法,比如一个 3*3的八数码盘可以压缩成一个int 值表示,但不适用于15 puzzl蛾大于8的puzzle问题。如果对空间要求很高,应 该还可以再压缩。本文采用一个int表示的方法。表示方法如下:由于int的表 示范围大于1e9,所以我们取一个int的低9位,为了方便寻找空格的位置,int的 个位我们用来放空格的位置(19)。而前8位,按照行从上到下,列从左到右的 顺序依次记录对应位置上的数字。1.2 问题的搜索形式描述八数码问题形式化描述:初始状态:初始状

4、态向量:规定向量中各分量对应的位置,各位置上的数字。把3X3的棋盘按从左到右,从上到下的顺序写成一个一维向量。我们可以设定初始状态: 后继函数:按照某种规则移动数字得到的新向量。例如: 目标测试:新向量是都是目标状态。即是目标状态?路径耗散函数:每次移动代价为 1,每执行一条规则后总代价加1。1.3 解决方案介绍(原理)该问题是一个搜索问题。 它是一种状态到另一种状态的变换。 要解决这个问题, 必须先把问题转化为数字描述。 由于八数码是一个3*3 的矩阵, 但在算法中不实用矩阵, 而是将这个矩阵转化为一个一维数组, 使用这个一维数组来表示八数码,但是移动时要遵守相关规则。(1) 可用如下形式的

5、规则来表示数字通过空格进行移动:(2)共 24 条移动规则,对应与每个位置的移动规则。(3)搜索顺序举例:优先移动行数小的棋子(数字 )同一行中优先移动列数大的棋子(4)约束规则:不使离开既定位置的数字数增加八数码的节点扩展应当遵循棋子的移动规则。 按规则, 每一次可以将一个与空格相邻的棋子移动到空格中, 实际上也可以看做空格的相反方向移动。 空格的移动方向可以是上下左右, 当然不能出边界。 棋子的位置, 也就是保存状态的数组元素的下标,空格移动后,相应位置发生变化,在不移出边界的条件下,空格向右,下,左,上移动后,新位置是原位置分别加上1,3, -1, -3。在这里,空格可以用任意数字表示。

6、操作本文用 u r d l 分别表示空格的向上向右向下向左四个操作。图的搜索策略:经分析, 8 数码问题的搜索策略共有:1.广度优先搜索、2.深度优先搜索、3.有界深度优先搜索、4.最好优先搜索、5.局部择优搜索,等等。其中广度优先搜索法是可采纳的, 有界深度优先搜索法是不完备的, 最好优先和局部择优搜索法是启发式搜索法。本实验采用启发式 A* 搜索算法来实现。2 算法介绍问题的求解实际上就是在这个图中找到一条路径可以从开始到结果。 这个寻找的过程就是状态空间搜索。 常用的状态空间搜索有深度优先和广度优先。 广度优先是从初始状态一层一层向下找, 直到找到目标为止。 深度优先是按照一定的顺序前查

7、找完一个分支,再查找另一个分支,以至找到目标为止。启发式搜索就是在状态空间中的搜索对每一个搜索的位置进行评估, 得到最好的位置, 再从这个位置进行搜索直到目标。 这样可以省略大量无畏的搜索路径,提高了效率。1.1 A*搜索算法一般介绍A* 算法实际是一种启发式搜索,所谓启发式搜索,就是利用一个估价函数评估每次的的决策的价值, 决定先尝试哪一种方案, 这样可以极大的优化普通的广度优先搜索。一般来说,从出发点(A)到目的地(B)的最短距离是固定的,我们可以写一个函数judge() 估计 A 到 B 的最短距离,如果程序已经尝试着从出发点 A 沿着某条路线移动到了 C 点 , 那么我们认为这个方案的

8、 A B 间的估计距离为 A 到 C 实际已经行走了的距离H 加上用 judge() 估计出的 C 到B 的距离。如此, 无论我们的程序搜索展开到哪一步, 都会算出一个评估值, 每一次决策后, 将评估值和等待处理的方案一起排序, 然后挑出待处理的各个方案中最有可能是最短路线的一部分的方案展开到下一步,一直循环到对象移动到目的地,或所有方案都尝试过却没有找到一条通向目的地的路径则结束。A* 算法是一个可采纳的最好优先算法。 A* 算法的估价函数可表示为:f(n) = g(n) + h(n)这里,f(n)是估价函数,g(n)是起点到终点的最短路径值,h(n)是n到目标的最断路经的启发值。 由于这个

9、f(n) 其实是无法预先知道的,所以我们用前面的估价函数f(n)做近似。g(n)代替g(n),但g(n)=g(n)才可(大多数情况下都是满足的, 可以不用考虑),h(n)代替h(n),但h(n)=h(n)才可。可以证明应用这样的估价 函数是可以找到最短路径的,也就是可采纳的。1.2 算法伪代码首先定义两个表, open 表用于存放已经生成,且已用启发式函数进行过估计或评价,但尚未产生它们的后继节点的那些结点,这些结点也称未考察结点;closed表用于存放已经生成,且已考察过的结点。设S0为初态,Sg为目标状态。具体过程如下:(1)把S0放入open表,记为f=h,令closed为空表;(2)重

10、复下列过程,直至找到目标结点为止。若open 为空表,则失败;选取open表中未设置过的具有最小f值的结点为最佳节点,并放入 closed表 中(4)若最佳节点不是目标节点,则扩展之,产生后继节点。(5)对每个后继结点进行下列过程:? 建立从该后继结点返回最佳节点的指针;? 计算g (后继结点)=g (最佳节点)+k (最佳节点,后继结点);? Ss:如果该后继节点C open,则称此节点为old,并把它添加至最佳节点 的后继节点中? 比较新旧路径代价,如果个 g (后继节点)g(old),则重新确定old的父 亲节点? 若至 old 节点的代价比较低或一样,则停止扩展节点? 若后继节点不再o

11、pen表中,则看其是否在closed中? 若后继节点在open表中,则转向Ss;? 若后继节点既不在open表中,又不在closed表中,则把它放入open表 中,并填入最佳节点的后裔表,然后走下一步(6)计算 f 值(7)GO LOOP3 算法实现3.1 实验环境与问题规模(1)实验环境: Windows XP(2)实验编程工具: VC+6.0(3)问题规模算法规模小,最大搜索深度不超过32。3.2 数据结构本实验主要采用链表,队列,堆:struct Chess旗盘int cellNN;/ 数码数组int Value;/评估值Direction BelockDirec;/ 所屏蔽方向stru

12、ct Chess * Parent;做节点;queue Queue;队歹!JstackStack;/|Chess *p=ChessList;p=p-Parent;/僻表3.3 实验结果经测试, 程序运行良好, 结果正确。 输入测试数据, 初试状态 ,目标状态,运行结果有解,共经过四步。3.4 系统中间及最终输出结果3.4.1 输入数据结果如下图 3-1 所示:图 3-1 输入数据结果3.4.2 运行中间及最终结果如下图 3-2 所示图 3-2 程序运行结果4 参考文献1Artificial intelligence :;a modern approach 人工智能 : 一种现代方法 作者: R

13、ussell, Stuart J. 出版社:清华大学出版社2 CSDN 博客5 附录源代码及其注释/* 栗丽霞 2011-04-29*/#include #include stdio.h#include stdlib.h#include time.h#include string.h#include #include using namespace std;const int N=3;/3*3 棋盘const int Max_Step=32;/ 最大搜索深度enum DirectionNone,Up,Down,Left,Right;/ 方向,分别对应上下左右struct Chess棋盘int

14、chessNumNN;/ 棋盘数码int Value;/ 评估值Direction BelockDirec;/ 所屏蔽方向struct Chess * Parent;父节点 ;void PrintChess(struct Chess *TheChess);/ 打印棋盘struct Chess * MoveChess(struct Chess * TheChess,Direction Direct,bool CreateNewChess);/ 移动棋盘数字int Appraisal(struct Chess * TheChess,struct Chess * Target);/ 估价函数stru

15、ct Chess * Search(struct Chess* Begin,struct Chess * Target);/A* 搜索函数int main()/本程序的一组测试数据为/*初始棋盘* 1 4 0* 3 5 2* 6 7 8*/* 目标棋盘* 0 1 2* 3 4 5* 6 7 8*/Chess Target;Chess *Begin,*ChessList;Begin=new Chess;int i;cout请输入初始棋盘,各数字用空格隔开:endl;for(i=0;iBegin-chessNumij;endl;cout请输入目标棋盘,各数字用空格隔开:for(i=0;iN;i+)

16、for(int j=0;jTarget.chessNumij;/获取初始棋盘Appraisal(Begin,&Target);Begin-Parent=NULL;Begin-BelockDirec=None;Target.Value=0;cout 初始棋盘:;PrintChess(Begin);cout 目标棋盘:;PrintChess(&Target);ChessList=Search(Begin,&Target);/ 搜索/打印if(ChessList)/* 将返回的棋盘列表利用栈将其倒叙 */Chess *p=ChessList;stackStack;while(p-Parent!=NU

17、LL)Stack.push(p);p=p-Parent;cout 搜索结果 :endl;int num=1;while(!Stack.empty() cout第num步:;num+;PrintChess(Stack.top();Stack.pop();coutn 完成 !endl;else cout 搜索不到结果,搜索深度大于32nendl;return 0;/打印棋盘void PrintChess(struct Chess *TheChess)cout( 评估值为 ;coutValue;cout)endl;for(int i=0;iN;i+)cout ;for(int j=0;jN;j+)

18、coutchessNumij; coutendl;/移动棋盘struct Chess * MoveChess(struct Chess * TheChess,Direction Direct,bool CreateNewChess)struct Chess * NewChess;/获取空闲格位置int i,j;for(i=0;iN;i+)bool HasGetBlankCell=false;for(j=0;jchessNumij=0)HasGetBlankCell=true;break;if(HasGetBlankCell)break;int ii=i,jj=j;bool AbleMove=t

19、rue;/判断是否可以移动switch(Direct)case Up:i+;if(i=N)AbleMove=false;break;case Down:i-;if(i=N)AbleMove=false;break;case Right:j-;if(j0)AbleMove=false;break;if(!AbleMove)/ 不可以移动则返回原节点return TheChess;if(CreateNewChess)NewChess=new Chess();for(int x=0;xN;x+) for(int y=0;ychessNumxy=TheChess-chessNumxy;/ 创建新棋盘,

20、此 时值与原棋盘一致elseNewChess=TheChess;NewChess-chessNumiijj = NewChess-chessNumij;/ 移动数字NewChess-chessNumij=0;/ 将原数字位置设置为空格return NewChess;/估价函数int Appraisal(struct Chess * TheChess,struct Chess * Target) int Value=0;for(int i=0;ichessNumij!=Target-chessNumij)Value+;TheChess-Value=Value;return Value;/A* 搜索函数struct Chess * Search(struc

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论