1、淮北师范大学计算机科学与技术学院 09 级网络工程题目: 人工智能中用 A*算法解决八数码问题 学 号: 20091204067 姓 名: 徐 小 波 专 业: 网络工程 课 程: 人工智能 2012 年 6 月 12 日问题说明:八数码问题是人工智能中一个很典型的智力问题。本文以状态空间搜索的观点讨论了八数码问题,给出了八数码问题的 Java 算法与实现的思想,分析了 A 算法的可采纳性等及系统的特点。关键词九宫重排,状态空间,启发式搜索,A 算法 1 引言九宫重排问题是人工智能当中有名的难题之一。问题是在 33 方格盘上,放有八个数码,剩下一个位置为空,每一空格其上下左右的数码可移至空格。
2、问题给定初始位置和目标位置,要求通过一系列的数码移动,将初始状态转化为目标状态。状态转换的规则:空格四周的数移向空格,我们可以看作是空格移动,它最多可以有个方向的移动,即上、下、左、右。九宫重排问题的求解方法,就是从给定的初始状态出发,不断地空格上下左右的数码移至空格,将一个状态转化成其它状态,直到产生目标状态。 一、 问题描述1.1 待解决问题的解释八数码游戏(八数码问题)描述为:在 33 组成的九宫格棋盘上,摆有八个将牌,每一个将牌都刻有 1-8 八个数码中的某一个数码。棋盘中留有一个空格,允许其周围的某一个将牌向空格移动,这样通过移动将牌就可以不断改变将牌的布局。这种游戏求解的问题是:给
3、定一种初始的将牌布局或结构(称初始状态)和一个目标的布局(称目标状态) ,问如何移动将牌,实现从初始状态到目标状态的转变。 1.2 问题的搜索形式描述(4 要素)初始状态:8 个数字将牌和空格在九宫格棋盘上的所有格局组成了问题的状态空间。其中,状态空间中的任一种状态都可以作为初始状态。后继函数:通过移动空格(上、下、左、右)和周围的任一棋子一次,到达新的合法状态。目标测试:比较当前状态和目标状态的格局是否一致。路径消耗:每一步的耗散值为 1,因此整个路径的耗散值是从起始状态到目标状态的棋子移动的总步数。1.3 解决原理对于八数码问题的解决,首先要考虑是否有答案。每一个状态可认为是一个 19 的
4、矩阵,问题即通过矩阵的变换,是否可以变换为目标状态对应的矩阵?由数学知识可知,可计算这两个有序数列的逆序值,如果两者都是偶数或奇数,则可通过变换到达,否则,这两个状态不可达。这样,就可以在具体解决问题之前判断出问题是否可解,从而可以避免不必要的搜索。如果初始状态可以到达目标状态,那么采取什么样的方法呢?常用的状态空间搜索有深度优先和广度优先。广度优先是从初始状态一层一层向下找,直到找到目标为止。深度优先是按照一定的顺序前查找完一个分支,再查找另一个分支,以至找到目标为止。 广度和深度优先搜索有一个很大的缺陷就是他们都是在一个给定的状态空间中穷举。这在状态空间不大的情况下是很合适的算法,可是当状
5、态空间十分大,且不预测的情况下就不可取了。他的效率实在太低,甚至不可完成。由于八数码问题状态空间共有 9!个状态,对于八数码问题如果选定了初始状态和目标状态,有 9!/2 个状态要搜索,考虑到时间和空间的限制,在这里采用 A*算法作为搜索策略。在这里就要用到启发式搜索启发式搜索就是在状态空间中的搜索对每一个搜索的位置进行评估,得到最好的位置,再从这个位置进行搜索直到目标。这样可以省略大量无畏的搜索路径,提到了效率。在启发式搜索中,对位置的估价是十分重要的。采用了不同的估价可以有不同的效果。启发中的估价是用估价函数表示的,如:f(n) = g(n) + h(n)其中 f(n) 是节点 n 的估价
6、函数,g(n)是在状态空间中从初始节点到 n 节点的实际代价,h(n)是从 n 到目标节点最佳路径的估计代价。 在此八数码问题中,显然 g(n)就是从初始状态变换到当前状态所移动的步数,估计函数 f(n)我们就可采用当前状态各个数字牌不在目标状态未知的个数,即错位数。 二、 算法介绍2.1 搜索算法一般介绍不管哪种搜索,都统一用这样的形式表示:搜索的对象是一个图,它面向一个问题,不一定有明确的存储形式,但它里面的一个结点都有可能是一个解(可行解) ,搜索的目的有两个方面,或者求可行解,或者从可行解集中求最优解。搜索算法可分为两大类:无信息的搜索算法和有信息的搜索算法。无信息的搜索又称盲目搜索,
7、其特点是只要问题状态可以形式化表示,原则上就可用使用无信息的搜索,无信息搜索有如下常见的几种搜索策略:广度优先搜索、代价一致搜索、深度优先搜索、深度有限搜索、迭代深入优先搜索、双向搜索。我们说 DFS 和 BFS 都是蛮力搜索,因为它们在搜索到一个结点时,在展开它的后续结点时,是对它们没有任何认识的,它认为它的孩子们都是一样的优秀 ,但事实并非如此,后续结点是有好有坏的。好,就是说它离目标结点近 ,如果优先处理它,就会更快的找到目标结点,从而整体上提高搜索性能。为了改善上面的算法,我们需要对展开后续结点时对子结点有所了解,这里需要一个估值函数,估值函数就是评价函数,它用来评价子结点的好坏,因为
8、准确评价是不可能的,所以称为估值。这就是我们所谓的有信息搜索。如果估值函数只考虑结点的某种性能上的价值,而不考虑深度,比较有名的就是有序搜索(Ordered-Search) ,它着重看好能否找出解,而不看解离起始结点的距离(深度) 。如果估值函数考虑了深度,或者是带权距离(从起始结点到目标结点的距离加权和) ,那就是 A*如果不考虑深度,就是说不要求最少步数,移动一步就相当于向后多展开一层结点,深度多算一层,如果要求最少步数,那就需要用 A*。简单的来说 A*就是将估值函数分成两个部分,一个部分是路径价值,另一个部分是一般性启发价值,合在一起算估整个结点的价值,考虑到八数码问题的特点,在本实验
9、中使用 A*算法求解。A*搜索是一种效的搜索算法,它把到达节点的耗散 g(n)和从该节点到目标节点的消耗 h(n)结合起来对节点进行评价:f(n)=g(n)+h(n)。当 h(n)是可采纳时,使用 Tree-Search 的 A*算法将是最优的。2.2 算法伪代码算法的功能:产生 8 数码问题的解(由初始状态到达目标状态的过程)输入:初始状态,目标状态输出:从初始状态到目标状态的一系列过程算法描述:Begin:读入初始状态和目标状态,并计算初始状态评价函数值 f;根据初始状态和目标状态,判断问题是否可解;If(问题可解)把初始状态假如 open 表中;While(未找到解 全局静态变量,表示目
10、标状态class eight_numprivate:int num9; 定义八数码的初始状态int not_in_position_num; 定义不在正确位置八数码的个数int deapth; 定义了搜索的深度int eva_function; 评价函数的值,每次选取最小的进行扩展public:eight_num* parent; 指向节点的父节点eight_num* leaf_next; 指向 open 表的下一个节点eight_num* leaf_pre; 指向 open 表的前一个节点初始状态的构造函数eight_num(int init_num9);eight_num(int num1
11、,int num2,int num3,int num4,int num5,int num6,int num7,int num8,int num9)eight_num(void) 计算启发函数 g(n)的值void eight_num:cul_para(void)显示当前节点的状态void eight_num:show()复制当前节点状态到一个另数组中void eight_num:get_numbers_to(int other_num9)设置当前节点状态(欲设置的状态记录的 other 数组中)void eight_num:set_num(int other_num9)eight_num/cl
12、ass definitionclass eight_numprivate:int num9;int not_in_position_num;int deapth;int eva_function;public:eight_num* parent;eight_num* leaf_next;eight_num* leaf_pre;eight_num(int init_num9);eight_num(int num1,int num2,int num3,int num4,int num5,int num6,int num7,int num8,int num9)num0=num1;num1=num2;
13、num2=num3;num3=num4;num4=num5;num5=num6;num6=num7;num7=num8;num8=num9;eight_num(void)for (int i=0;iparent=NULL)deapth=0;elsedeapth=this-parent-deapth+1;eva_function=not_in_position_num+deapth;/构造函数 1eight_num:eight_num(int init_num9)for (int i=0;i5)return 0;elsenumi=numi+3;numi+3=0;return 1;/空格向左移in
14、t move_left(int num9)for (int i=0;iparent)if(*p=num)return 1;return 0;/寻找估价函数最小的叶子节点eight_num* find_OK_leaf(eight_num* start)eight_num *p,*OK;p=OK=start;int min=start-get_evafun();for(p=start;p!=NULL;p=p-leaf_next)if(minp-get_evafun()OK=p;min=p-get_evafun();return OK;/主函数开始int main(void)double time;
15、 clock_t Start,Finish;int memery_used=0,step=0;int num9;int flag=0;/是否输入错误标志,1 表示输入错误int bingo=0;/是否查找成功标志,1 表示成功int i,j;coutnumi;for(j=0;j8|flag=1)i-;couti;return 1;Start=clock( );eight_num *OK_leaf=while(OK_leaf!=NULLif(*OK_leaf=Target)bingo=1;break;p=OK_leaf-leaf_pre;OK_leaf-get_numbers_to(num);i
16、f(move_up(num)new_8num-set_num(num);new_8num-parent=OK_leaf;new_8num-cul_para();new_8num-leaf_pre=p;if(p=NULL)leaf_start=new_8num;elsep-leaf_next=new_8num;p=new_8num;memery_used+;OK_leaf-get_numbers_to(num);if(move_down(num)new_8num-set_num(num);new_8num-parent=OK_leaf;new_8num-cul_para();new_8num-l
17、eaf_pre=p;if(p=NULL)leaf_start=new_8num;elsep-leaf_next=new_8num;p=new_8num;memery_used+;OK_leaf-get_numbers_to(num);if(move_left(num)new_8num-set_num(num);new_8num-parent=OK_leaf;new_8num-cul_para();new_8num-leaf_pre=p;if(p=NULL)leaf_start=new_8num;elsep-leaf_next=new_8num;p=new_8num;memery_used+;O
18、K_leaf-get_numbers_to(num);if(move_right(num)new_8num-set_num(num);new_8num-parent=OK_leaf;new_8num-cul_para();new_8num-leaf_pre=p;if(p=NULL)leaf_start=new_8num;elsep-leaf_next=new_8num;p=new_8num;memery_used+;p-leaf_next=OK_leaf-leaf_next;if(OK_leaf-leaf_next!=NULL)OK_leaf-leaf_next-leaf_pre=p;OK_l
19、eaf-leaf_next=OK_leaf-leaf_pre=NULL;Finish=clock( ); if(bingo=1)time = (double)(Finish-Start)*1000/CLOCKS_PER_SEC;eight_num *p;for (p=OK_leaf-parent;p!=NULL;p=p-parent)coutshow();step+;cout http:/ 南京邮电学院信号与信息处理研究所 李飞; 郑宝玉; 赵生妹;人工神经网络在组织网络化发展评价中的应用 朱启红 张 钢 计算机应用研究 2007 年第 06 期神经网络研究的发展趋势 廖晓峰李传东 (重庆大学计算机学院,重庆)中科院半导体研究所半导体人工神经网络实验室 http:/宁波市农业专家系统 http:/:4000/专家系统的现状及发展趋势 方景文; 机器人, Robot, 编辑部邮箱 1986 年 06期 主体与协同: 专家系统的发展方向 中科院计算所 张子云 曹鹏(计算机世界报2007 年 102 日第 41 期 B11)专家系统的原理、现状和发展趋势 杨叔子; 郑小军; 水利电力机械, Water Consevancy & Electric Power Machinery 1987 年 05 期 Matlab Nerual toolbox 李述铜