人工智能实验报告完整版八数码+验证
人工智能实验总结
总结
宽度优先搜索法
在有解的情形总能保证搜索到最短路经,也 就是移动最少步数的路径。但宽度优先搜索法的 最大问题在于搜索的结点数量太多,因为在宽度 优先搜索法中,每一个可能扩展出的结点都是搜 索的对象。随着结点在搜索树上的深度增大,搜 索的结点数会很快增长,并以指数形式扩张,从 而所需的存储空间和搜索花费的时间也会成倍增 长。
1 2
0 1 0 1
0 0 1 1
0 1 1 0
神经网络设计
用两层神经网络来实现,其中隐层为随机 感知器层(net1),神经网络元数目设计为 3,其权值和阈值是随机的,它的输出作为 输出层(分类层)的输入;输出层为感知 器层(net2),其神经元数为1,这里仅对 该层进行训练。
程序运行结果
随机感知器层的权值向量 iw1 = 0.4267 -0.6556 -0.5439 0.9376 -0.1007 -0.2886 随机感知器层的阈值向量 b1 = 0.4074 0.0441 0.8658
运行结果分析
上面实验结果可以看出,城市数目为30的 时候,当迭代次数为100,算法收敛慢,在 迭代次数内最优解没有达到稳定,没有搜 索到最好的解。 迭代次数为200和250的时候,算法基本达 到收敛,最优解在100代以后趋于稳定,表 明搜索到问题的最优解。
运行结果
当城市数目改变的时候: CityNum=50;最大代数gnmax=100;
程序运行结果
第二层感知器层的权值向量和阈值向量 iw2 = -3 -2 2 b2 = 2
人工智能实验报告
人工智能九宫格重移——搜索成员:赵春杰 2009210665羊森 2009210653黄鑫 2009210周成兵 2009210664王素娟 20092106441.问题描述:八数码问题也称为九宫问题。
在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同。
棋盘上还有一个空格,与空格相邻的棋子可以移到空格中。
要求解决的问题是:给出一个初始状态和一个目标状态,找出一种从初始转变成目标状态的移动棋子步数最少的移动步骤。
所谓问题的一个状态就是棋子在棋盘上的一种摆法。
棋子移动后,状态就会发生改变。
解八数码问题实际上就是找出从初始状态到达目标状态所经过的一系列中间过渡状态。
2.九宫重移有无答案检查(逆序数)我们把每个9宫格横向展开,如第一个123456789,我们把左边数大于右边数的组数称为这个九宫格的逆序数,显然123456789的逆序数为0;考虑横向平移,那么逆序数的增量为2或0或-2;纵向平移,逆序数的增量为4或0或-4;但147258369的逆序数为奇数。
所以147258369是无解的情况。
由此也可以类推当将9宫格展开后,如果数据序列的逆序数为奇数,则此数据序列对应的九宫格是无解的。
3.BFS算法队列: Queue open = new Queue();存放待扩展的节点List: List<Bfstr> closed = new List<Bfstr>();存放已被扩展过的节点ArrayList map = new ArrayList();//存放答案HashTale: Hashtable table = new Hashtable();构造哈希表以方便查找3.1.BFS算法介绍广度优先搜索算法BFS基本思想:从图中某顶点v出发,逐层对节点进行拓展,并考察是否为目标节点,在第n层节点没有全部扩展并考察前,不对第n+1层节点进行扩展。
八数码问题
+0*6!+
3*7!+(98)*
8!=
55596<9!
具体的原因可以去查查一些数学书,其中
123456789的哈希值是
0最小,876543210
的哈希值是(9!1)
最大,而其他值都在
0到(
9!1)
中,且均唯一。
Q5:如何使搜索只求得最佳的解?
要寻找这一系列中间状态的方法是搜索,但搜索很容易遇到时间和空间上的问题。以下就是搜
索的基本原理:
由
137246852状态可以衍生三个状态,假如选择
了
123746855,则又衍生三个状态,继续按某策略进
行选择,一直到衍生出的新状态为目标状态
END为止。
容易看出,这样的搜索类似于从树根开始向茎再向叶
括两步操作
ld,可能与平时玩这类游戏的习惯不符合,但这是为了和
ACM例题相统一。
对应地,每种操作引起的状态变化如下:
r:num值++
l:num值u:
有点复杂
int
t0=
9num%
10+
1
int
t1=
num/1e(t0)
int
t2=
t1%1000
END,所以优先级高。
在计算
difference和
manhattan时,推荐都将空格忽略,因为在
difference中空格可有可无,对整
体搜索影响不大。
考虑下面两个状态(左需要
3步到达
END态,右需要
4步到达
人工智能实验报告
****大学人工智能基础课程实验报告(2011-2012学年第一学期)启发式搜索王浩算法班级: *********** 学号: ********** 姓名: ****** 指导教师: ******成绩:2012年 1 月 10 日实验一 启发式搜索算法1. 实验内容:使用启发式搜索算法求解8数码问题。
⑴ 编制程序实现求解8数码问题A *算法,采用估价函数()()()()w n f n d n p n ⎧⎪=+⎨⎪⎩, 其中:()d n 是搜索树中结点n 的深度;()w n 为结点n 的数据库中错放的棋子个数;()p n 为结点n 的数据库中每个棋子与其目标位置之间的距离总和。
⑵ 分析上述⑴中两种估价函数求解8数码问题的效率差别,给出一个是()p n 的上界的()h n 的定义,并测试使用该估价函数是否使算法失去可采纳性。
2. 实验目的熟练掌握启发式搜索A *算法及其可采纳性。
3. 实验原理使用启发式信息知道搜索过程,可以在较大的程度上提高搜索算法的时间效率和空间效率;启发式搜索的效率在于启发式函数的优劣,在启发式函数构造不好的情况下,甚至在存在解的情形下也可能导致解丢失的现象或者找不到最优解,所以构造一个优秀的启发式函数是前提条件。
4.实验内容 1.问题描述在一个3*3的九宫格 里有1至8 八个数以及一个空格随机摆放在格子中,如下图:初始状态 目标状态现需将图一转化为图二的目标状态,调整的规则为:每次只能将空格与其相邻的一个数字进行交换。
实质是要求给出一个合法的移动步骤,实现从初始状态到目标状态的转变。
2.算法分析 (1)解存在性的讨论对于任意的一个初始状态,是否有解可通过线性代数的有关理论证明。
按数组存储后,算出初始状态的逆序数和目标状态的逆序数,若两者的奇偶性一致,则表明有解。
(2)估价函数的确定通过对八数码的特性的研究,找出一个相对好的函数,f(n)=d(n)+h(n)其中h(n)=2*compare(n)+3*S(n);d(n)为已搜索的深度;(compare(n)为当前节点与目标结点相同位置不相同的个数,S(n)为当前节点的无序度。
人工智能九宫格重移——搜索的实验报告
人工智能九宫格重移——搜索1.问题描述:八数码问题也称为九宫问题。
在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同。
棋盘上还有一个空格,与空格相邻的棋子可以移到空格中。
要求解决的问题是:给出一个初始状态和一个目标状态,找出一种从初始转变成目标状态的移动棋子步数最少的移动步骤。
所谓问题的一个状态就是棋子在棋盘上的一种摆法。
棋子移动后,状态就会发生改变。
解八数码问题实际上就是找出从初始状态到达目标状态所经过的一系列中间过渡状态。
2.九宫重移有无答案检查(逆序数)我们把每个9宫格横向展开,如第一个123456789,我们把左边数大于右边数的组数称为这个九宫格的逆序数,显然123456789的逆序数为0;考虑横向平移,那么逆序数的增量为2或0或-2;纵向平移,逆序数的增量为4或0或-4;但147258369的逆序数为奇数。
所以147258369是无解的情况。
由此也可以类推当将9宫格展开后,如果数据序列的逆序数为奇数,则此数据序列对应的九宫格是无解的。
3.BFS算法队列: Queue open = new Queue();存放待扩展的节点List: List<Bfstr> closed = new List<Bfstr>();存放已被扩展过的节点ArrayList map = new ArrayList();//存放答案HashTale: Hashtable table = new Hashtable();构造哈希表以方便查找3.1.BFS算法介绍广度优先搜索算法BFS基本思想:从图中某顶点v出发,逐层对节点进行拓展,并考察是否为目标节点,在第n层节点没有全部扩展并考察前,不对第n+1层节点进行扩展。
对九宫重排问题,即构造广度优先搜索树,从初始状态,利用广度优先搜索算法逐步找到目标状态的节点。
3.2.状态空间表示状态空间用一维数组表示,每个节点存放在Bfstr结构体中的字符now中,从第一行开始从左往右给九宫格标号0……8,字符串now元素下标代表格子位置,而now数组中对应数组的值代表九宫格中存放的数码,用数值9代表空格。
昆明理工大学人工智能实验报告
昆明理工大学信息工程与自动化学院学生实验报告(2013——2014 学年第一学期)课程名称:人工智能导论开课实验室:信自楼234室2013年11月5日一、实验问题1、用软件编程解决八数码问题二、实验目的1、熟悉人工智能求解八数码问题,以及对人工智能深入了解。
2、熟悉状态空间的盲目搜索、启发式搜索,和A*算法。
3、熟悉人工智能系统中的问题求解过程。
三、实验原理1、将初始节点s放入open表中2、若open表为空则推出3、移出open表中的第一个节点N放入close表中,并冠以顺序编号n,4、若目标节点Sg=N,则搜索成功,结束5、若N不可扩展,则转入第2步四、程序框图五、实验结果及分析1、通过逆序数的奇数偶数来判断。
因为在空白移动过程中,数码的逆序数不改变。
左右移动,数码序列不变。
上下移动,数码序列中某个数字则移动了两位。
八数码问题为3*3矩阵,3为奇数,故逆序数不作改变。
故可通过判断当前状态S的逆序数以及目标状态的数字序列的逆序数的奇偶性是否相同来判断该问题是否可解。
2、是否达到目标节点,将当前节点和目标节点进行比较3、对于f(n)的考虑,f(n)是否最小,选择最小的扩展,若几个相等的状态同时出现,则随机选一个。
4、将Open表中的所有节点进行排序选择估价函数f(n)最优的进行扩展。
第二种选择就是选择当前层扩展的节点中选择最优的f(n)进行扩展。
六、结论1、尽管明白怎么样解决八数码问题,但用电脑编程还是不会编。
虽然学过C 语言,由于不用也生疏了。
以后对学过的只是温故而知新。
2、通过本次试验我对启发式搜索有了更加深入的了解。
在实验中通过对两种启发式搜索所扩在的节点数来看更加有效 能在复杂情况下求得更加优质的解避免不必要的节点的扩展。
使搜索的速度更快。
3、八数码的启发式搜索、A 算法等用书面的形式很容易表示出来,但用计算机能读懂的语言(如C 语言)表示,这个转换的的过程很困难。
七、源程序及注释#include<stdio.h>#include<conio.h>int n,m;typedef struct Node{char matrix[10];/*存储矩阵*/char operate;/*存储不可以进行的操作,L代表不能左移R代表不能右移U代表不能上移D 代表不能下移*/char extend;/*是否可以扩展,Y代表可以,N代表不可以*/int father;/*指向产生自身的父结点*/}Node;char start[10]={"83426517 "};char end[10]={"1238 4765"};Node base[4000];int result[100];/*存放结果的base数组下标号,逆序存放*/int match()/*判断是否为目标*/{int i;for(i=0;i<9;i++){if(base[n-1].matrix[i]!=end[i]){return 0;}}return 1;}void show()/*显示矩阵的内容*/{int i=1;while(m>=0){int mm=result[m];//clrscr();printf("\n\n\n 状态方格\t\t步骤%d",i);printf("\n\n\n\n\n\t\t\t%c\t%c\t%c\n",base[mm].matrix[0],base[mm].matrix[1],base[mm].matr ix[2]);printf("\n\n\t\t\t%c\t%c\t%c\n",base[mm].matrix[3],base[mm].matrix[4],base[mm].matrix[5]) ;printf("\n\n\t\t\t%c\t%c\t%c\n",base[mm].matrix[6],base[mm].matrix[7],base[mm].matrix[8]) ;//sleep(1);m--;i++;}}void leave()/*推理成功后退出程序之前要执行的函数,主要作用是输出结果*/{ n--; while(base[n].father!=-1){ result[m]=n;m++;n=base[n].father;}result[m]=0;result[m+1]='\0';show();//clrscr();printf("\n\n\n\n\n\n\n\n\n\t\t\t\t搜索结束\n\n\n\n\n\n\n\n\n\n"); getch();//exit(0);}int left(int x)/*把下标为X的数组中的矩阵的空格左移*/ {int i,j;char ch;for(i=0;i<9;i++){if(base[x].matrix[i]==' ')break;}if(i==0||i==3||i==6||i==9){ return 0;}for(j=0;j<9;j++){ base[n].matrix[j]=base[x].matrix[j];}ch=base[n].matrix[i-1];base[n].matrix[i-1]=base[n].matrix[i];base[n].matrix[i]=ch;base[n].operate='R';base[n].extend='Y';base[n].father=x;base[x].extend='N';n++;if(match(i)) leave();return 1;}int right(int x)/*把下标为X的数组中的矩阵的空格右移*/ { int i,j; char ch;for(i=0;i<9;i++){if(base[x].matrix[i]==' ')break;if(i==2||i==5||i==8||i==9){ return 0;}for(j=0;j<9;j++){ base[n].matrix[j]=base[x].matrix[j];}ch=base[n].matrix[i+1];base[n].matrix[i+1]=base[n].matrix[i];base[n].matrix[i]=ch;base[n].operate='L';base[n].extend='Y';base[n].father=x;base[x].extend='N';n++; if(match(i))leave();return 1;}int up(int x)/*把下标为X的数组中的矩阵的空格上移*/ { int i,j; char ch;for(i=0;i<9;i++){ if(base[x].matrix[i]==' ')break;}if(i==0||i==1||i==2||i==9){ return 0;}for(j=0;j<9;j++){ base[n].matrix[j]=base[x].matrix[j];}ch=base[n].matrix[i-3];base[n].matrix[i-3]=base[n].matrix[i];base[n].matrix[i]=ch;base[n].operate='D';base[n].extend='Y';base[n].father=x;base[x].extend='N';n++;if(match(i))leave();return 1;}int down(int x)/*把下标为X的数组中的矩阵的空格下移*/int i,j;char ch;for(i=0;i<9;i++){ if(base[x].matrix[i]==' ') break;}if(i==6||i==7||i==8||i==9){ return 0;}for(j=0;j<9;j++){ base[n].matrix[j]=base[x].matrix[j];}ch=base[n].matrix[i+3];base[n].matrix[i+3]=base[n].matrix[i];base[n].matrix[i]=ch;base[n].operate='U';base[n].extend='Y';base[n].father=x;base[x].extend='N';n++; if(match(i))leave(); return 1;}main(){ int i;char a[20],b[20];n=1;1./*以下是输入初始和目标矩阵,并把输入的0转换为空格*/ printf("3*3方格初始状态:");scanf("%s",a);printf("3*3方格结束状态:");scanf("%s",b);for(i=0;i<9;i++){if(a[i]=='0'){ start[i]=' '; continue; }if(b[i]=='0'){ end[i]=' '; continue; }start[i]=a[i]; end[i]=b[i];}start[9]='\0'; end[9]='\0';for(i=0;i<9;i++){ base[0].matrix[i]=start[i]; }base[0].operate='N';base[0].extend='Y';base[0].father=-1;/*以上是为第一个base数组元素赋值*/ for(i=0;n<4000;i++){if(base[i].extend=='Y'){if(base[i].operate=='L'){right(i);up(i);down(i);}if(base[i].operate=='R'){left(i);up(i);down(i);}if(base[i].operate=='U'){left(i);right(i);down(i);}if(base[i].operate=='D'){left(i);right(i);up(i);}if(base[i].operate=='N'){left(i);right(i);up(i);down(i);}}}leave();}。
人工智能实验报告-八数码演示程序文件
人工智能实验报告八数码演示程序姓名:学号:所学专业:报告题目:提交日期:计算机科学与技术专业八数码演示程序2010年4月9日八数码演示程序1.问题描述1.1八数码问题的解释八数码问题是人工智能经典难题之一。
问题是在3×3 方格盘上,放有八个数码,剩下一个为空,每一空格其上下左右的数码可移至空格。
问题给定初始位置和目标位置,要求通过一系列的数码移动,将初始位置转化为目标位置。
本文介绍用A星算法,采用估计值h(n)(曼哈顿距离)和g(m)(当前深度)的和作为估计函数。
1.2八数码问题的搜索形式描述初始状态:初始状态向量,规定向量中各分量对应的位置,各位置上的初始数字<0,1,3,4,5,6,7,8,2>后继函数:移动规则,按照某条规则移动数字得到的新向量<0,1,3,4,5,6,7,8,9>转移到<4,1,3,0,5,6,7,8,2>目标测试:新向量是否是目标状态,也即为<0,1,2,3,4,5,6,7,8>路径耗散函数:在搜索时,每深入一层则当前步数代价加1,代价总和由当前步数和可能还需要移动的步数之和。
1.3 解决方案介绍首先,A*算法需要个估价(评价)函数:f(x)=g(x)+h(x)g(x)通常表示移动至当前状态需要的步数,h(x)则是启发函数。
在算法进行的时候,我们将对每一个可能移动到的状态做评价,计算其f(x),然后将其放入一个OPEN数组中,最后我们选取OPEN中f(x)值最小的状态作为下一步,再重复上述过程,因为f(x)值最小的状态意味着它最有可能(不是一定)最接近最终状态。
2.算法介绍2.1 搜索算法一般介绍A*算法是一种启发式搜索算法,是常用的最短路搜寻算法,在游戏领域中有广泛的应用。
所谓启发式算法,它与常规的搜索方法最大的不同是在执行过程中始终有一个提示性的信息在引导着算法的进行,使得我们不断靠近目标而不是盲目的遍历,这个提示信息就是由启发函数产生的,启发函数的好坏将直接影响算法的效率,从几篇文献看来,A*算法和广度优先、深度优先算法相比是有很明显的效率优势的。
山东大学人工智能实验一八数码问题
山东大学计算机科学与技术学院 人工智能课程实验报告
学号:2420430689 实验题目: 八数码问题 实验学时: 2 实验日期: 姓名: QQ 班级: 2014 级 1 班
实验目的: 熟悉和掌握启发式搜索的定义、估价函数和算法过程,并利用启发式搜 索算法求解八数码难题,理解求解流程和搜索顺序。 硬件环境: PC 机 软件环境: eclipse 实验步骤与内容: 1、根据实验指导书及课本上关于八数码问题的算法介绍编写程序代码如下:
this.num = num; } public int getDepth() { return depth; } pubth = depth; } public int getEvaluation() { return evaluation; } public void setEvaluation(int evaluation) { this.evaluation = evaluation; } public int getMisposition() { return misposition; } public void setMisposition(int misposition) { this.misposition = misposition; } public EightPuzzle getParent() { return parent; } public void setParent(EightPuzzle parent) { this.parent = parent; } /** * 判断当前状态是否为目标状态 * @param target * @return */ public boolean isTarget(EightPuzzle target){ return Arrays.equals(getNum(), target.getNum()); } /** * 求 f(n) = g(n)+h(n); * 初始化状态信息 * @param target */ public void init(EightPuzzle target){ int temp = 0; for(int i=0;i<9;i++){
人工智能-A算法求解8数码问题
实验四 A*算法求解8数码问题一、实验目的熟悉和掌握启发式搜索的定义、估价函数和算法过程,并利用A*算法求解8数码难题,理解求解流程和搜索顺序。
二、实验原理A*算法是一种启发式图搜索算法,其特点在于对估价函数的定义上。
对于一般的启发式图搜索,总是选择估价函数f值最小的节点作为扩展节点。
因此,f 是根据需要找到一条最小代价路径的观点来估算节点的,所以,可考虑每个节点n的估价函数值为两个分量:从起始节点到节点n的实际代价g(n)以及从节点n 到达目标节点的估价代价h(n),且h(n)<=h*(n),h*(n)为n节点到目标节点的最优路径的代价。
八数码问题是在3×3的九宫格棋盘上,排放有8个刻有1~8数码的将牌。
棋盘中有一个空格,允许紧邻空格的某一将牌可以移到空格中,这样通过平移将牌可以将某一将牌布局变换为另一布局。
针对给定的一种初始布局或结构(目标状态),问如何移动将牌,实现从初始状态到目标状态的转变。
如图1所示表示了一个具体的八数码问题求解。
图1 八数码问题的求解三、实验内容1、参考A*算法核心代码,以8数码问题为例实现A*算法的求解程序(编程语言不限),要求设计两种不同的估价函数。
2、在求解8数码问题的A*算法程序中,设置相同的初始状态和目标状态,针对不同的估价函数,求得问题的解,并比较它们对搜索算法性能的影响,包括扩展节点数、生成节点数等。
3、对于8数码问题,设置与图1所示相同的初始状态和目标状态,用宽度优先搜索算法(即令估计代价h(n)=0的A*算法)求得问题的解,记录搜索过程中的扩展节点数、生成节点数。
4、提交实验报告和源程序。
四.实验截图五.源代码#include<iostream>#include"stdio.h"#include"stdlib.h"#include"time.h"#include"string.h"#include<queue>#include<stack>using namespace std;const int N=3;//3*3棋?盘ìconst int Max_Step=32;//最?大洙?搜?索÷深?度èenum Direction{None,Up,Down,Left,Right};//方?向ò,?分?别纄对?应畖上?下?左哩?右?struct Chess//棋?盘ì{int chessNum[N][N];//棋?盘ì数簓码?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);//估à价?函ˉ数簓struct Chess * Search(struct Chess* Begin,struct Chess * Target);//A*搜?索÷函ˉ数簓int main(){//本?程ì序ò的?一?组哩?测a试?数簓据Y为a/*初?始?棋?盘ì*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<<"请?输?入?初?始?棋?盘ì,?各÷数簓字?用?空?格?隔?开a:阰"<<endl;for(i=0;i<N;i++){for(int j=0;j<N;j++){cin>>Begin->chessNum[i][j];}}cout<<"请?输?入?目?标括?棋?盘ì,?各÷数簓字?用?空?格?隔?开a:阰"<<endl;for(i=0;i<N;i++){for(int j=0;j<N;j++){cin>>Target.chessNum[i][j];}}//获?取?初?始?棋?盘ìAppraisal(Begin,&Target);Begin->Parent=NULL;Begin->BelockDirec=None;Target.Value=0;cout<<"初?始?棋?盘ì:";PrintChess(Begin);cout<<"目?标括?棋?盘ì:";PrintChess(&Target);ChessList=Search(Begin,&Target);//搜?索÷//打洙?印?if(ChessList){/*将?返う?回?的?棋?盘ì列表括?利?用?栈?将?其?倒?叙e*/Chess *p=ChessList;stack<Chess *>Stack;while(p->Parent!=NULL){Stack.push(p);p=p->Parent;}cout<<"搜?索÷结á果?:"<<endl;int num=1;while(!Stack.empty()){cout<<"第台?<<num<<"步?: ";num++;PrintChess(Stack.top());Stack.pop();}cout<<"\n完?成é!"<<endl;}elsecout<<"搜?索÷不?到?结á果?,?搜?索÷深?度è大洙?于?2\n"<<endl;return 0;}//打洙?印?棋?盘ìvoid PrintChess(struct Chess *TheChess){cout<<"(评à估à值μ为a";cout<<TheChess->Value;cout<<")"<<endl;for(int i=0;i<N;i++){cout<<" ";for(int j=0;j<N;j++){cout<<TheChess->chessNum[i][j]<<" ";}cout<<endl;}}//移?动ˉ棋?盘ìstruct Chess * MoveChess(struct Chess * TheChess,Direction Direct,bool CreateNewChess) {struct Chess * NewChess;//获?取?空?闲D格?位?置?int i,j;for(i=0;i<N;i++){bool HasGetBlankCell=false;for(j=0;j<N;j++){if(TheChess->chessNum[i][j]==0){HasGetBlankCell=true;break;}}if(HasGetBlankCell)break;}int ii=i,jj=j;bool AbleMove=true;//判D断?是?否?可é以?移?动ˉswitch(Direct){case Up:i++;if(i>=N)AbleMove=false;break;case Down:i--;if(i<0)AbleMove=false;break;case Left:j++;if(j>=N)AbleMove=false;break;case Right:j--;if(j<0)AbleMove=false;break;};if(!AbleMove)//不?可é以?移?动ˉ则ò返う?回?原-节ú点?{return TheChess;}if(CreateNewChess){NewChess=new Chess();for(int x=0;x<N;x++){for(int y=0;y<N;y++)NewChess->chessNum[x][y]=TheChess->chessNum[x][y];//创洹?建¨新?棋?盘ì,?此?时骸?值μ与?原-棋?盘ì一?致?}}elseNewChess=TheChess;NewChess->chessNum[ii][jj] = NewChess->chessNum[i][j];//移?动ˉ数簓字?NewChess->chessNum[i][j]=0;//将?原-数簓字?位?置?设Θ?置?为a空?格?return NewChess;}//估à价?函ˉ数簓int Appraisal(struct Chess * TheChess,struct Chess * Target){int Value=0;for(int i=0;i<N;i++){for(int j=0;j<N;j++){if(TheChess->chessNum[i][j]!=Target->chessNum[i][j])Value++;}}TheChess->Value=Value;return Value;}//A*搜?索÷函ˉ数簓struct Chess * Search(struct Chess* Begin,struct Chess * Target){Chess *p1,*p2,*p;int Step=0;//深?度èp=NULL;queue<struct Chess *> Queue;Queue.push(Begin);//初?始?棋?盘ì入?队ó//搜?索÷do{p1=(struct Chess *)Queue.front();Queue.pop();//出?队ófor(int i=1;i<=4;i++)//分?别纄从洙?四?个?方?向ò推?导?出?新?子哩?节ú点? {Direction Direct=(Direction)i;if(Direct==p1->BelockDirec)//跳?过y屏á蔽?方?向òcontinue;p2=MoveChess(p1,Direct,true);//移?动ˉ数簓码?if(p2!=p1)//数簓码?是?否?可é以?移?动ˉ{Appraisal(p2,Target);//对?新?节ú点?估à价?if(p2->Value<=p1->Value)//是?否?为a优?越?节ú点?{p2->Parent=p1;switch(Direct)//设Θ?置?屏á蔽?方?向ò,防え?止1往?回?推?{case Up:p2->BelockDirec=Down;break;case Down:p2->BelockDirec=Up;break;case Left:p2->BelockDirec=Right;break;case Right:p2->BelockDirec=Left;break;}Queue.push(p2);//存?储洹?节ú点?到?待鋣处鋦理え?队ó列if(p2->Value==0)//为a0则ò,搜?索÷完?成é{p=p2;i=5;}}else{delete p2;//为a劣ⅷ?质ê节ú点?则ò抛×弃úp2=NULL;}}}Step++;if(Step>Max_Step)return NULL;}while(p==NULL || Queue.size()<=0);return p;}六、实验报告要求1、分析不同的估价函数对A*搜索算法性能的影响等。
八数码问题,实验报告
八数码问题,实验报告八数码实验报告利用人工智能技术解决八数码游戏问题1.八数码游戏问题简介九宫排字问题(又称八数码问题)是人工智能当中有名的难题之一。
问题是在3×3方格盘上,放有八个数码,剩下第九个为空,每一空格其上下左右的数码可移至空格。
问题给定初始位置和目标位置,要求通过一系列的数码移动,将初始位置转化为目标位置。
2.八数码游戏问题的状态空间法表示①建立一个只含有初始节点S0的搜索图G,把S0放入OPEN表中②建立CLOSED表,且置为空表③判断OPEN表是否为空表,若为空,则问题无解,退出④选择OPEN表中的第一个节点,把它从OPEN表移出,并放入CLOSED表中,将此节点记为节点n⑤考察节点n是否为目标节点,若是,则问题有解,成功退出。
问题的解就是沿着n到S0的路径得到。
若不是转⑥⑥扩展节点n生成一组不是n的祖先的后继节点,并将它们记为集合M,将M中的这些节点作为n的后继节点加入图G中⑦对未在G中出现过的(OPEN和CLOSED表中未出现过的)集合M中的节点, 设置一个指向父节点n的指针,并把这些节点放入OPEN表中;对于已在G中出现过的M中的节点,确定是否需要修改指向父节点的指针;对于已在G中出现过并已在closed表中的M中的节点,确定是否需要修改通向他们后继节点的指针。
⑧按某一任意方式或某种策略重排OPEN表中节点的顺序⑨转③3.八数码游戏问题的盲目搜索技术宽度优先搜索:1、定义如果搜索是以接近起始节点的程度依次扩展节点的,那么这种搜索就叫做宽度优先搜索(breadth-first search)。
2、特点这种搜索是逐层进行的;在对下一层的任一节点进行搜索之前,必须搜索完本层的所有节点。
3、宽度优先搜索算法(1) 把起始节点放到OPEN表中(如果该起始节点为一目标节点,则求得一个解答)。
(2) 如果OPEN是个空表,则没有解,失败退出;否则继续。
(3) 把第一个节点(节点n)从OPEN表移出,并把它放入CLOSED 的扩展节点表中。
人工智能实验报告-八数码(五篇模版)
人工智能实验报告-八数码(五篇模版)第一篇:人工智能实验报告-八数码《人工智能》实验一题目实验一启发式搜索算法1.实验内容:使用启发式搜索算法求解8数码问题。
⑴ 编制程序实现求解8数码问题A*算法,采用估价函数⎧⎪w(n),f(n)=d(n)+⎨pn⎪⎩()其中:d(n)是搜索树中结点n的深度;w(n)为结点n的数据库中错放的棋子个数;p(n)为结点n的数据库中每个棋子与其目标位置之间的距离总和。
⑵ 分析上述⑴中两种估价函数求解8数码问题的效率差别,给出一个是p(n)的上界的h(n)的定义,并测试使用该估价函数是否使算法失去可采纳性。
2.实验目的熟练掌握启发式搜索A算法及其可采纳性。
3.数据结构与算法设计该搜索为一个搜索树。
为了简化问题,搜索树节点设计如下:typedef struct Node//棋盘 {//节点结构体int data[9];double f,g;struct Node * parent;//父节点}Node,*Lnode;int data[9];数码数组:记录棋局数码摆放状态。
struct Chess * Parent;父节点:指向父亲节点。
下一步可以通过启发搜索算法构造搜索树。
1、局部搜索树样例:*2、搜索过程搜索采用广度搜索方式,利用待处理队列辅助,逐层搜索(跳过劣质节点)。
搜索过程如下:(1)、把原棋盘压入队列;(2)、从棋盘取出一个节点;(3)、判断棋盘估价值,为零则表示搜索完成,退出搜索;(4)、扩展子节点,即从上下左右四个方向移动棋盘,生成相应子棋盘;(5)、对子节点作评估,是否为优越节点(子节点估价值小于或等于父节点则为优越节点),是则把子棋盘压入队列,否则抛弃;(5)、跳到步骤(2);3、算法的评价完全能解决简单的八数码问题,但对于复杂的八数码问题还是无能为力。
现存在的一些优缺点。
1、可以改变数码规模(N),来扩展成N*N的棋盘,即扩展为N 数码问题的求解过程。
人工智能实验报告完整版八数码+验证解读
把数码问题就是把一串数字变成下面这个样子:1 2 38 0 47 6 5实现方法1.过程表示源代码:#include<stdio.h>static int style[9]={1,2,3,6,7,4,5,8,0};//输入的数码//2,5,4,3,0,7,1,8,6 3,2,1,8,0,4,7,6,5 1,0,4,2,7,3,8,5,6 1,0,3,8,2,4,7,6,5static int arrayStep41[6]={5,4,3,6,7,8};//第四步和第六步共用的数组,所以设为全局量static int arrayStep71[4]={3,6,7,4};static int local;//空格的位置int i,j;//所用到的变量int number=0;//记录移动步数void print();void step1();void step2();void step3();void step4();void step5();void step6();void step7();void step8();void step9();void exchange(int x,int y);void judge();void judge()//判断空格位置{number = 0;for(i=0;i<9;i++){if(style[i]==0){local=i;return;}}}void exchange(int x,int y)//交换两个数{int temp;print();temp=style[x];style[x]=style[y];style[y]=temp;local=y;number++;}void step1(){int arrayStep11[5]={3,0,1,2,5};int arrayStep12[6]={6,7,8,5,2,1};if((style[2]!=0)&&style[2]!=1)return;else{if(local==2){if(style[1]==1)exchange(2,5);elseexchange(2,1);return;}else{if(local==4){exchange(4,1);i=2;while(local!=5){exchange(arrayStep11[i],arrayStep11[i+1]);i++;}return;}for(i=0;i<3;i++){if(arrayStep11[i]==local){while(local!=5){exchange(arrayStep11[i],arrayStep11[i+1]);i++;}return;}}for(i=0;i<4;i++){if(arrayStep12[i]==local){while(local!=1){exchange(arrayStep12[i],arrayStep12[i+1]);i++;}return;}}}}return;}void step2(){int arrayStep21[8]={0,3,6,7,8,5,4,1};for(i=0;i<8;i++){if(arrayStep21[i]==local){while(style[0]!=1){exchange(arrayStep21[i%8],arrayStep21[(i+1)%8]);i++;}break;}}}void step3(){int arrayStep31[8]={2,1,4,3,6,7,8,5};for(i=0;i<8;i++){if(arrayStep31[i]==local){while(style[1]!=2){exchange(arrayStep31[i%8],arrayStep31[(i+1)%8]);i++;}break;}}}void step4(){for(i=0;i<6;i++){if(arrayStep41[i]==local){while((style[4]!=3)){exchange(arrayStep41[i%6],arrayStep41[(i+1)%6]);i=(i+1)%6;}while(local!=3){exchange(arrayStep41[i%6],arrayStep41[(i+5)%6]);i=(i+5)%6;}break;}}}void step5(){int arrayStep51[9]={3,0,1,4,5,2,1,0,3};i=0;do{exchange(arrayStep51[i],arrayStep51[i+1]);i++;}while(local!=3);}void step6(){for(i=0;i<6;i++){if(arrayStep41[i]==local){while(style[5]!=4){exchange(arrayStep41[i%6],arrayStep41[(i+1)%6]);i++;}if(local==8)exchange(8,7);break;}}return;}void step7(){for(i=0;i<4;i++){if(arrayStep71[i]==local){while(style[4]!=5){exchange(arrayStep71[i%4],arrayStep71[(i+1)%4]);i=(i+1)%4;}while(local!=3){exchange(arrayStep71[i%4],arrayStep71[(i+3)%4]);i=(i+3)%4;}break;}}}void step8(){int arrayStep81[13]={3,0,1,2,5,4,7,8,5,2,1,0,3};i=0;do{exchange(arrayStep81[i],arrayStep81[i+1]);i++;}}void step9(){for(i=0;i<4;i++){if(arrayStep71[i]==local){while(style[7]!=6){exchange(arrayStep71[i%4],arrayStep71[(i+1)%4]);i=(i+1)%4;}while(local!=4){exchange(arrayStep71[i%4],arrayStep71[(i+3)%4]);i=(i+3)%4;}break;}}}void print(){for(j=0;j<9;j++){if(style[j]==0)printf(" \t");elseprintf("%d\t",style[j]);if((j+1)%3==0)printf("\n");}printf("************ %d ***********\n",number);}void loop(){printf("请输入数码:\n");for(i=0;i<9;i++)scanf("%d",&style[i]);judge();step1();step2();step3();{step4();step5();}step6();if(style[8]!=5){step7();step8();}step9();print();if(!((style[3]==8)&&(style[6]==7)))printf("用书上所给算法来看此数码错误!\n"); }void main(){while(1)loop();}2.深度优先实现/***************说明***********************用宽度优先搜索算法实现八数码问题******************************************/#include<iostream>#include<stdio.h>#include<fstream>#include<stdlib.h>#include "string.h"#include "assert.h"#include "windows.h"using namespace std;int wholeStyle[9] = {2,8,3,1,6,4,7,0,5};int standard1[9] = {1,2,3,8,0,4,7,6,5};int local,i,j;int startKey = 0,endKey = 0,equalKey = 1,tempSpace;struct node *openHead,*open; //open表struct node *closedHead,*closed; //closed表struct node *tempNode; //临时节点struct node *answer; //找到的路径int num = 0;struct node{int style[9];struct node *next;struct node *father;};void updateData() //更新要判断数据{int i;printf("请输入八数码原始状态:\n");for(i = 0;i < 9;i++)scanf("%d",&wholeStyle[i]);printf("请输入八数码最终状态:\n");for(i = 0;i < 9;i++)scanf("%d",&standard1[i]);}void judge1(struct node *head)//判断空格位置{for(i = 0;i < 9;i++){if(head->style[i] == 0){local = i;return;}}}int judge2(struct node *head) //判断是否与标准八数码相等,不相等返回值为0 {for(i = 0;i < 9;i++){if(head->style[i] != standard1[i]){if((i == 3)&&(head->style[3] == standard1[6]));else if((i == 6)&&(head->style[6] == standard1[3]));elsereturn 0;}}return 1;}void judge3() //判断新生成的八数码是否就是最终状态或者在open、closed表中出现{if(judge2(tempNode))endKey = 1;else{while(openHead->next->next->style[0] != 9){for(i = 0;i < 9;i++){if(openHead->next->next->style[i] != tempNode->style[i]){equalKey = 1;break;}elseequalKey = 0;}if(equalKey)//不相等openHead = openHead->next;elsebreak;}openHead = open->next;if(equalKey)//不相等{while(closedHead->next->style[0] != 9){for(i = 0;i < 9;i++){if(closedHead->next->style[i] != tempNode->style[i]){equalKey = 1;break;}elseequalKey = 0;}if(!equalKey)//相等break;elseclosedHead = closedHead->next;}closedHead = closed->next;}if(equalKey)//不相等{open->next = tempNode;tempNode->next = openHead;tempNode->father = openHead->next;open = open->next;}}}void print(struct node *temp) //输出八数码表{for(j = 0;j < 9;j++){if(temp->style[j] == 0)printf(" \t");elseprintf("%d\t",temp->style[j]);if((j + 1) % 3 == 0)printf("\n");}}void write2txt(){ofstream out("F:\\out_details.txt",ios::app);if( out.fail() ){cerr<<"未找到文件"<<endl;}out<<" 第"<<++num<<"步\n";out<<"open table:\n";while(openHead->next->style[0] != 9){for(i = 0;i < 9;i ++){out<<openHead->next->style[i]<<"\t";if((i+1) % 3 == 0)out<<"\n";}out<<"\n";openHead = openHead->next;}openHead = openHead->next;out<<"*********************\n";out<<"closed table:\n";while(closedHead->next->style[0] != 9){for(i = 0;i < 9;i ++){out<<closedHead->next->style[i]<<"\t";if((i + 1) % 3 ==0)out<<"\n";}out<<"\n";closedHead = closedHead->next;}closedHead = closedHead->next;out<<"-----------------------------------\n";out.close();}void main(){//updateData();//输入八数码数据for(i = 0;i < 9;i++) //判断初始状态是否已经为最终状态{if(wholeStyle[i] == standard1[i]);else{if((i == 3)&&(wholeStyle[i] == standard1[6]));else if((i == 6)&&(wholeStyle[i] == standard1[3]));else{startKey = 1;break;}}}if(!startKey){printf("不用判断!\n");return;}printf("要判断!\n");openHead = new node();open = new node();openHead->style[0] = 9;openHead->next = open;for(i = 0;i < 9;i++)open->style[i] = wholeStyle[i];open->next = openHead;open->father = openHead;closedHead = new node();closed = new node();closedHead->style[0] = 9;closedHead->next = closedHead;closed = closedHead;while(open->style[0] != 9)//当open表不为空时一直循环{judge1(openHead->next);if(local % 3 > 0)//右移{equalKey = 1;tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = openHead->next->style[i];tempSpace = tempNode->style[local - 1];tempNode->style[local - 1] = tempNode->style[local];tempNode->style[local] = tempSpace;judge3();}if(endKey)break;if(local > 2)//下移{equalKey = 1;tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = openHead->next->style[i];tempSpace = tempNode->style[local - 3];tempNode->style[local - 3] = tempNode->style[local];tempNode->style[local] = tempSpace;judge3();}if(endKey)break;if(local % 3 < 2)//左移{equalKey = 1;tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = openHead->next->style[i];tempSpace = tempNode->style[local + 1];tempNode->style[local + 1] = tempNode->style[local];tempNode->style[local] = tempSpace;judge3();}if(endKey)break;if(local < 6)//上移{equalKey = 1;tempNode = new node();//tempNode = malloc(sizeof(struct node));for(i = 0;i < 9;i++)tempNode->style[i] = openHead->next->style[i];tempSpace = tempNode->style[local + 3];tempNode->style[local + 3] = tempNode->style[local];tempNode->style[local] = tempSpace;judge3();}if(endKey)break;closed->next = openHead->next; //把open的标头添加到closed表中openHead->next = openHead->next->next;closed = closed->next;closed->next = closedHead;write2txt();}open->next = tempNode;//把找到的新节点添加到open表中tempNode->next = openHead;tempNode->father = openHead->next;open = open->next;closed->next = openHead->next; //把open的标头添加到closed表中openHead->next = openHead->next->next;closed = closed->next;closed->next = closedHead;write2txt();answer = new node();tempNode = new node();tempNode = open;while(tempNode->style[0] != 9)//将结果路径存于answer{answer = tempNode;tempNode = tempNode->father;tempNode->next = answer;}num = 0;while(answer->next->style[0] != 9)//输出answer{printf("***********第%d步***********\n",num++);print(answer);answer = answer->next;printf("\n");}printf("***********第%d步***********\n",num++);print(answer);if(answer->style[3] != standard1[3])printf("\n!!输入的八数码不合法,不能从初始状态到最终状态\n\n\n\n");return;}3.宽度优先:/***************说明***********************用宽度优先搜索算法实现八数码问题******************************************/#include<iostream>#include<stdio.h>#include<fstream>#include<stdlib.h>#include "string.h"#include "assert.h"#include "windows.h"using namespace std;int wholeStyle[9] = {2,8,3,1,6,4,7,0,5};int standard1[9] = {1,2,3,8,0,4,7,6,5};int local,i,j;int startKey = 0,endKey = 0,equalKey = 1,tempSpace; struct node *openHead,*open; //open表struct node *closedHead,*closed; //closed表struct node *tempNode; //临时节点struct node *answer; //找到的路径int num = 0;struct node{int style[9];struct node *next;struct node *father;};void updateData() //更新要判断数据{int i;printf("请输入八数码原始状态:\n");for(i = 0;i < 9;i++)scanf("%d",&wholeStyle[i]);printf("请输入八数码最终状态:\n");for(i = 0;i < 9;i++)scanf("%d",&standard1[i]);}void judge1(struct node *head)//判断空格位置{for(i = 0;i < 9;i++){if(head->style[i] == 0){local = i;return;}}}int judge2(struct node *head) //判断是否与标准八数码相等,不相等返回值为0{for(i = 0;i < 9;i++){if(head->style[i] != standard1[i]){if((i == 3)&&(head->style[3] == standard1[6]));else if((i == 6)&&(head->style[6] == standard1[3]));elsereturn 0;}}return 1;}void judge3() //判断新生成的八数码是否就是最终状态或者在open、closed表中出现{if(judge2(tempNode))endKey = 1;else{while(openHead->next->next->style[0] != 9){for(i = 0;i < 9;i++){if(openHead->next->next->style[i] != tempNode->style[i]){equalKey = 1;break;}elseequalKey = 0;}if(equalKey)//不相等openHead = openHead->next;elsebreak;}openHead = open->next;if(equalKey)//不相等{while(closedHead->next->style[0] != 9){for(i = 0;i < 9;i++){if(closedHead->next->style[i] != tempNode->style[i]){equalKey = 1;break;}elseequalKey = 0;}if(!equalKey)//相等break;elseclosedHead = closedHead->next;}closedHead = closed->next;}if(equalKey)//不相等{open->next = tempNode;tempNode->next = openHead;tempNode->father = openHead->next;open = open->next;}}}void print(struct node *temp) //输出八数码表{for(j = 0;j < 9;j++){if(temp->style[j] == 0)printf(" \t");elseprintf("%d\t",temp->style[j]);if((j + 1) % 3 == 0)printf("\n");}}void write2txt(){ofstream out("F:\\out_details.txt",ios::app);if( out.fail() ){cerr<<"未找到文件"<<endl;}out<<" 第"<<++num<<"步\n";out<<"open table:\n";while(openHead->next->style[0] != 9){for(i = 0;i < 9;i ++){out<<openHead->next->style[i]<<"\t";if((i+1) % 3 == 0)out<<"\n";}out<<"\n";openHead = openHead->next;}openHead = openHead->next;out<<"*********************\n";out<<"closed table:\n";while(closedHead->next->style[0] != 9){for(i = 0;i < 9;i ++){out<<closedHead->next->style[i]<<"\t";if((i + 1) % 3 ==0)out<<"\n";}out<<"\n";closedHead = closedHead->next;}closedHead = closedHead->next;out<<"-----------------------------------\n";out.close();}void main(){//updateData();//输入八数码数据for(i = 0;i < 9;i++) //判断初始状态是否已经为最终状态{if(wholeStyle[i] == standard1[i]);else{if((i == 3)&&(wholeStyle[i] == standard1[6]));else if((i == 6)&&(wholeStyle[i] == standard1[3]));else{startKey = 1;break;}}}if(!startKey){printf("不用判断!\n");return;}printf("要判断!\n");openHead = new node();open = new node();openHead->style[0] = 9;openHead->next = open;for(i = 0;i < 9;i++)open->style[i] = wholeStyle[i];open->next = openHead;open->father = openHead;closedHead = new node();closed = new node();closedHead->style[0] = 9;closedHead->next = closedHead;closed = closedHead;while(open->style[0] != 9)//当open表不为空时一直循环{judge1(openHead->next);if(local % 3 > 0)//右移{equalKey = 1;tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = openHead->next->style[i];tempSpace = tempNode->style[local - 1];tempNode->style[local - 1] = tempNode->style[local];tempNode->style[local] = tempSpace;judge3();}if(endKey)break;if(local > 2)//下移{equalKey = 1;tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = openHead->next->style[i];tempSpace = tempNode->style[local - 3];tempNode->style[local - 3] = tempNode->style[local];tempNode->style[local] = tempSpace;judge3();}if(endKey)break;if(local % 3 < 2)//左移{equalKey = 1;tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = openHead->next->style[i];tempSpace = tempNode->style[local + 1];tempNode->style[local + 1] = tempNode->style[local];tempNode->style[local] = tempSpace;judge3();}if(endKey)break;if(local < 6)//上移{equalKey = 1;tempNode = new node();//tempNode = malloc(sizeof(struct node));for(i = 0;i < 9;i++)tempNode->style[i] = openHead->next->style[i];tempSpace = tempNode->style[local + 3];tempNode->style[local + 3] = tempNode->style[local];tempNode->style[local] = tempSpace;judge3();}if(endKey)break;closed->next = openHead->next; //把open的标头添加到closed表中openHead->next = openHead->next->next;closed = closed->next;closed->next = closedHead;write2txt();}open->next = tempNode;//把找到的新节点添加到open表中tempNode->next = openHead;tempNode->father = openHead->next;open = open->next;closed->next = openHead->next; //把open的标头添加到closed表中openHead->next = openHead->next->next;closed = closed->next;closed->next = closedHead;write2txt();answer = new node();tempNode = new node();tempNode = open;while(tempNode->style[0] != 9)//将结果路径存于answer{answer = tempNode;tempNode = tempNode->father;tempNode->next = answer;}num = 0;while(answer->next->style[0] != 9)//输出answer{printf("***********第%d步***********\n",num++);print(answer);answer = answer->next;printf("\n");}printf("***********第%d步***********\n",num++);print(answer);if(answer->style[3] != standard1[3])printf("\n!!输入的八数码不合法,不能从初始状态到最终状态\n\n\n\n");return;}4.A算法/***************说明************************* A算法实现八数码问题********************************************/#include<iostream>#include<fstream>#include<iomanip>using namespace std;void print(struct node *temp);int wholeStyle[9] = {2,8,3,1,6,4,7,0,5};int standard1[9] = {1,2,3,8,0,4,7,6,5};int local,i,j;int tempSpace;struct node *openHead,*open; //open表struct node *closedHead,*closed; //closed表struct node *tempNode; //临时节点struct node *answer; //找到的路径int num = 0;bool endKey;struct node{int depth;int judgement_based;int style[9];struct node *next;struct node *father;};void updateData() //更新要判断数据{int i;cout<<"请输入八数码原始状态:"<<endl;for(i = 0;i < 9;i++)cin>>wholeStyle[i];cout<<"请输入八数码最终状态:"<<endl;for(i = 0;i < 9;i++)cin>>standard1[i];}int judge1(struct node *head)//判断空格位置{for(i = 0;i < 9;i++){if(head->style[i] == 0)return i;}}int evaluation_function(struct node *head) //计算不在正确位置的点的个数{int not_correct_position = 0;for(i = 0;i < 9;i++)if((head->style[i] != 0)&&(head->style[i] != standard1[i]))not_correct_position++;return not_correct_position;}void print(struct node *temp) //输出八数码表{for(j = 0;j < 9;j++){if(temp->style[j] == 0)cout<<" \t";elsecout<<temp->style[j]<<"\t";if((j + 1) % 3 == 0)cout<<endl;}}void write2txt() //将过程记录到文本文档中{ofstream out("F:\\out_details4.txt",ios::app);if( out.fail() ){cerr<<"未找到文件"<<endl;}out<<" 第"<<++num<<"步\n";out<<"open table:\n";while(openHead->next->style[0] != 9){for(i = 0;i < 9;i ++){out<<openHead->next->style[i]<<"\t";if((i+1) % 3 == 0)out<<"\n";}out<<"估值:";out<<openHead->next->judgement_based<<"\n";openHead = openHead->next;}openHead = openHead->next;out<<"*********************\n";out<<"closed table:\n";while(closedHead->next->style[0] != 9){for(i = 0;i < 9;i ++){out<<closedHead->next->style[i]<<"\t";if((i + 1) % 3 ==0)out<<"\n";}out<<"深度:"<<closedHead->next->depth<<" 估值:"<<closedHead->next->judgement_based<<"\n";closedHead = closedHead->next;}closedHead = closedHead->next;out<<"-----------------------------------\n";out.close();}void basic_exchange_oper() //每一次基本的交换都要进行的动作{if(judge1(tempNode) != judge1(closed->father))//当新生成节点的空格位置与closed父亲节点的空格位置不相等{tempNode->father = closed; //新生成节点的指向它的父亲节点tempNode->depth = closed->depth + 1;//深度加1tempNode->judgement_based = evaluation_function(tempNode) + tempNode->depth;//计算估值while(openHead->next->style[0] != 9){if(tempNode->judgement_based > openHead->next->judgement_based){openHead = openHead->next;}else{tempNode->next = openHead->next;openHead->next = tempNode;openHead = open->next;return;}}//插入的值比最后一个还大进行下面的操作openHead = open->next;//先恢复表头否则Head指向为最后一个open->next = tempNode;tempNode->next = openHead;open = open->next;return;}}void main(){//updateData();//输入八数码数据openHead = new node(); //初始化open表open = new node();openHead->style[0] = 9;openHead->next = open;for(i = 0;i < 9;i++)open->style[i] = wholeStyle[i];open->next = openHead;open->father = openHead;open->depth = 0;open->judgement_based = evaluation_function(open) + open->depth;//这行可以不写closedHead = new node(); //初始化closed表closed = new node();closedHead->style[0] = 9;closedHead->next = closedHead;closed = closedHead;int min_judgement1 = open->judgement_based;while(open->style[0] != 9)//当open表不为空时一直循环{//updateData();//输入八数码数据write2txt();closed->next = openHead->next; //把open表中第一组八数码移到closed表中openHead->next = openHead->next->next;closed = closed->next;closed->next = closedHead;if(openHead->next->style[0] == 9)//如果是第一次则open暂时指向openHead open = openHead;if(closed->judgement_based == closed->depth)//判断新移进closed表中的八数码的f 值是否等于它的层数{cout<<"succeed!"<<endl;write2txt();answer = new node();while(closed->style[0] != 9) //将结果存于answer表中{answer = closed;closed = closed->father;closed->next = answer;}num = 0;while(answer->style[0] != 9) //控制台显示步骤{cout<<"******第"<<num++<<"步***********\n";print(answer);cout<<endl;answer = answer->next;}return;}else //如果closed表末的八数码是最终状态则拓展新的八数码{local = judge1(closed);if(local % 3 > 0)//右移{tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = closed->style[i];tempSpace = tempNode->style[local - 1];tempNode->style[local - 1] = tempNode->style[local];tempNode->style[local] = tempSpace;basic_exchange_oper();}if(local < 6)//上移{tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = closed->style[i];tempSpace = tempNode->style[local + 3];tempNode->style[local + 3] = tempNode->style[local];tempNode->style[local] = tempSpace;basic_exchange_oper();}if(local > 2)//下移{tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = closed->style[i];tempSpace = tempNode->style[local - 3];tempNode->style[local - 3] = tempNode->style[local];tempNode->style[local] = tempSpace;basic_exchange_oper();}if(local % 3 < 2)//左移{tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = closed->style[i];tempSpace = tempNode->style[local + 1];tempNode->style[local + 1] = tempNode->style[local];tempNode->style[local] = tempSpace;basic_exchange_oper();}}}cout<<"false!"<<endl;}神经网络实验群神经网络实验一、实验目的:理解反向传播网络的结构和原理,掌握反向传播算法对神经元的训练过程,了解反向传播公式。
人工智能_八数码实验报告【范本模板】
西安郵電大学人工智能实验报告书(三)学院:自动化学院专业:智能科学与技术班级:智能1403姓名:刘忠强时间:2016—3—29一、实验目的1. 熟悉人工智能系统中的问题求解过程;2。
熟悉状态空间的盲目搜索策略;3.掌握盲目收索算法,重点是宽度优先收索和深度优先收索.二、实验算法广度优先收索是一种先生成的节点先扩展的策略。
它的过程是:从初始节点开始逐层向下扩展,再第n层节点还没有完全搜索之前,不进如第n+1层节点.Open表中的节点总是按进入的先后排序,先进入的节点排在前面,够进入的排在后面。
三、程序框图四、实验结果及分析初始状态:目标状态:2 83 2 1 61 6 4 4 0 87 0 5 7 5 3五、源程序及注释#include <iostream〉#include <ctime>#include 〈vector〉using namespace std;const int ROW = 3;const int COL = 3;const int MAXDISTANCE = 10000;const int MAXNUM = 10000;int abs(int a){if (a>0) return a;else return —a;}typedef struct _Node{int digit[ROW][COL];int dist; // 距离int dep; // 深度int index; // 索引值} Node;Node src, dest;vector〈Node〉 node_v; // 储存节点bool isEmptyOfOPEN(){ //判断Open表是否空for (int i = 0; i 〈 node_v.size(); i++){if (node_v[i]。
dist != MAXNUM)return false;}return true;}bool isEqual(int index, int digit[][COL]) { //判断节点是否与索引值指向的节点相同for (int i = 0; i 〈 ROW; i++)for (int j = 0; j 〈 COL; j++){if (node_v[index].digit[i][j] != digit[i][j])return false;}return true;}ostream& operator<<(ostream& os, Node& node){for (int i = 0; i < ROW; i++) {for (int j = 0; j 〈 COL; j++)os <〈 node。
人工智能实验报告 八数码问题
实验一 启发式搜索算法姓名:徐维坚 学号:2220103484 日期:2012/6/29一、实验目的:熟练掌握启发式搜索A *算法及其可采纳性。
二、实验内容:使用启发式搜索算法求解8数码问题。
1) 编制程序实现求解8数码问题A *算法,采用估价函数()()()()w n f n d n p n ⎧⎪=+⎨⎪⎩, 其中:()d n 是搜索树中结点n 的深度;()w n 为结点n 的数据库中错放的棋子个数;()p n 为结点n 的数据库中每个棋子与其目标位置之间的距离总和。
2) 分析上述⑴中两种估价函数求解8数码问题的效率差别,给出一个是()p n 的上界 的()h n 的定义,并测试使用该估价函数是否使算法失去可采纳性。
三、实验原理:1. 问题描述:八数码问题也称为九宫问题。
在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同。
棋盘上还有一个空格(以数字0来表示),与空格相邻的棋子可以移到空格中。
要求解决的问题是:给出一个初始状态和一个目标状态,找出一种从初始转变成目标状态的移动棋子步数最少的移动步骤。
所谓问题的一个状态就是棋子在棋盘上的一种摆法。
解八数码问题实际上就是找出从初始状态到达目标状态所经过的一系列中间过渡状态。
2. 原理描述:2.1 有序搜索算法:(1)原理:在搜索过程中,OPEN 表中节点按照其估价函数值以递增顺序排列,选择OPEN 表中具有最小估价函数值的节点作为下一个待扩展的节点,这种搜索方法称为有序搜索。
在本例中,估价函数中的)(n g 取节点深度)(n d ,)(n h 为节点n 的状态与目标状态之间错放的个数,即函数)(n ω。
(2)算法描述:① 把起始节点S 放到OPEN 表中,并计算节点S 的)(S f ;② 如果OPEN 是空表,则失败退出,无解;③ 从OPEN 表中选择一个f 值最小的节点i 。
如果有几个节点值相同,当其中有一个 为目标节点时,则选择此目标节点;否则就选择其中任一个节点作为节点i ;④ 把节点i 从 OPEN 表中移出,并把它放入 CLOSED 的已扩展节点表中;⑤ 如果i 是个目标节点,则成功退出,求得一个解;⑥ 扩展节点i ,生成其全部后继节点。
八数码问题报告
⼋数码问题报告⼋数码问题分析班级:计算机1041学号:01姓名:李守先2013年9⽉26⽇摘要⼋数码问题(Eight-puzzle Problem )是⼈⼯智能中⼀个很典型的智⼒问题。
本⽂以状态空间搜索的观点讨论了⼋数码问题,给出了⼋数码问题的Java 算法与实现的思想, 分析了A*算法的可采纳性等及系统的特点。
关键词九宫重排, 状态空间, 启发式搜索, A*算法1 引⾔九宫重排问题(即⼋数码问题)是⼈⼯智能当中有名的难题之⼀。
问题是在3×3⽅格盘上,放有⼋个数码,剩下⼀个位置为空,每⼀空格其上下左右的数码可移⾄空格。
问题给定初始位置和⽬标位置,要求通过⼀系列的数码移动,将初始状态转化为⽬标状态。
状态转换的规则:空格周围的数移向空格,我们可以看作是空格移动,它最多可以有4个⽅向的移动,即上、下、左、右。
九宫重排问题的求解⽅法,就是从给定的初始状态出发,不断地空格上下左右的数码移⾄空格,将⼀个状态转化成其它状态,直到产⽣⽬标状态。
图1许多学者对该问题进⾏了有益的探索[1,2,4,6]。
给定初始状态,9个数在3×3中的放法共有9!=362880种,其状态空间是相当⼤的。
因此, 有必要考虑与问题相关的启发性信息来指导搜索,以提⾼搜索的效率。
当然,还有个很重要的问题:每个初始状态都存在解路径吗?⽂献给出了九宫重排问题是否有解的判别⽅法:九宫重排问题存在⽆解的情况,当遍历完所有可扩展的状态也没有搜索到⽬标状态就判断为⽆解。
可以根据状态的逆序数来先验的判断是否有解,当初始状态的逆序数和⽬标状态的逆序数的奇偶性相同时,问题有解;否则问题⽆解。
状态的逆序数是定义把三⾏数展开排成⼀⾏,并且丢弃数字 0 不计⼊其中,ηi 是第 i 个数之前⽐该数⼩的数字的个数,则η=Σηi 是该状态的逆序数,图2说明了逆序数计算的过程。
本⽂介绍⽤JAVA 编写九宫重排问题游戏。
游戏规则是,可随机产⽣或由⽤户设置初始状态,由初始状态出发,不断地在空格上下左右的数码移⾄空格,若能排出⽬标状态,则成功。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
把数码问题就是把一串数字变成下面这个样子:1 2 38 0 47 6 5实现方法1.过程表示源代码:#include<stdio.h>static int style[9]={1,2,3,6,7,4,5,8,0};//输入的数码//2,5,4,3,0,7,1,8,6 3,2,1,8,0,4,7,6,5 1,0,4,2,7,3,8,5,6 1,0,3,8,2,4,7,6,5static int arrayStep41[6]={5,4,3,6,7,8};//第四步和第六步共用的数组,所以设为全局量static int arrayStep71[4]={3,6,7,4};static int local;//空格的位置int i,j;//所用到的变量int number=0;//记录移动步数void print();void step1();void step2();void step3();void step4();void step5();void step6();void step7();void step8();void step9();void exchange(int x,int y);void judge();void judge()//判断空格位置{number = 0;for(i=0;i<9;i++){if(style[i]==0){local=i;return;}}}void exchange(int x,int y)//交换两个数{int temp;print();temp=style[x];style[x]=style[y];style[y]=temp;local=y;number++;}void step1(){int arrayStep11[5]={3,0,1,2,5};int arrayStep12[6]={6,7,8,5,2,1};if((style[2]!=0)&&style[2]!=1)return;else{if(local==2){if(style[1]==1)exchange(2,5);elseexchange(2,1);return;}else{if(local==4){exchange(4,1);i=2;while(local!=5){exchange(arrayStep11[i],arrayStep11[i+1]);i++;}return;}for(i=0;i<3;i++){if(arrayStep11[i]==local){while(local!=5){exchange(arrayStep11[i],arrayStep11[i+1]);i++;}return;}}for(i=0;i<4;i++){if(arrayStep12[i]==local){while(local!=1){exchange(arrayStep12[i],arrayStep12[i+1]);i++;}return;}}}}return;}void step2(){int arrayStep21[8]={0,3,6,7,8,5,4,1};for(i=0;i<8;i++){if(arrayStep21[i]==local){while(style[0]!=1){exchange(arrayStep21[i%8],arrayStep21[(i+1)%8]);i++;}break;}}}void step3(){int arrayStep31[8]={2,1,4,3,6,7,8,5};for(i=0;i<8;i++){if(arrayStep31[i]==local){while(style[1]!=2){exchange(arrayStep31[i%8],arrayStep31[(i+1)%8]);i++;}break;}}}void step4(){for(i=0;i<6;i++){if(arrayStep41[i]==local){while((style[4]!=3)){exchange(arrayStep41[i%6],arrayStep41[(i+1)%6]);i=(i+1)%6;}while(local!=3){exchange(arrayStep41[i%6],arrayStep41[(i+5)%6]);i=(i+5)%6;}break;}}}void step5(){int arrayStep51[9]={3,0,1,4,5,2,1,0,3};i=0;do{exchange(arrayStep51[i],arrayStep51[i+1]);i++;}while(local!=3);}void step6(){for(i=0;i<6;i++){if(arrayStep41[i]==local){while(style[5]!=4){exchange(arrayStep41[i%6],arrayStep41[(i+1)%6]);i++;}if(local==8)exchange(8,7);break;}}return;}void step7(){for(i=0;i<4;i++){if(arrayStep71[i]==local){while(style[4]!=5){exchange(arrayStep71[i%4],arrayStep71[(i+1)%4]);i=(i+1)%4;}while(local!=3){exchange(arrayStep71[i%4],arrayStep71[(i+3)%4]);i=(i+3)%4;}break;}}}void step8(){int arrayStep81[13]={3,0,1,2,5,4,7,8,5,2,1,0,3};i=0;do{exchange(arrayStep81[i],arrayStep81[i+1]);i++;}}void step9(){for(i=0;i<4;i++){if(arrayStep71[i]==local){while(style[7]!=6){exchange(arrayStep71[i%4],arrayStep71[(i+1)%4]);i=(i+1)%4;}while(local!=4){exchange(arrayStep71[i%4],arrayStep71[(i+3)%4]);i=(i+3)%4;}break;}}}void print(){for(j=0;j<9;j++){if(style[j]==0)printf(" \t");elseprintf("%d\t",style[j]);if((j+1)%3==0)printf("\n");}printf("************ %d ***********\n",number);}void loop(){printf("请输入数码:\n");for(i=0;i<9;i++)scanf("%d",&style[i]);judge();step1();step2();step3();{step4();step5();}step6();if(style[8]!=5){step7();step8();}step9();print();if(!((style[3]==8)&&(style[6]==7)))printf("用书上所给算法来看此数码错误!\n"); }void main(){while(1)loop();}2.深度优先实现/***************说明***********************用宽度优先搜索算法实现八数码问题******************************************/#include<iostream>#include<stdio.h>#include<fstream>#include<stdlib.h>#include "string.h"#include "assert.h"#include "windows.h"using namespace std;int wholeStyle[9] = {2,8,3,1,6,4,7,0,5};int standard1[9] = {1,2,3,8,0,4,7,6,5};int local,i,j;int startKey = 0,endKey = 0,equalKey = 1,tempSpace;struct node *openHead,*open; //open表struct node *closedHead,*closed; //closed表struct node *tempNode; //临时节点struct node *answer; //找到的路径int num = 0;struct node{int style[9];struct node *next;struct node *father;};void updateData() //更新要判断数据{int i;printf("请输入八数码原始状态:\n");for(i = 0;i < 9;i++)scanf("%d",&wholeStyle[i]);printf("请输入八数码最终状态:\n");for(i = 0;i < 9;i++)scanf("%d",&standard1[i]);}void judge1(struct node *head)//判断空格位置{for(i = 0;i < 9;i++){if(head->style[i] == 0){local = i;return;}}}int judge2(struct node *head) //判断是否与标准八数码相等,不相等返回值为0 {for(i = 0;i < 9;i++){if(head->style[i] != standard1[i]){if((i == 3)&&(head->style[3] == standard1[6]));else if((i == 6)&&(head->style[6] == standard1[3]));elsereturn 0;}}return 1;}void judge3() //判断新生成的八数码是否就是最终状态或者在open、closed表中出现{if(judge2(tempNode))endKey = 1;else{while(openHead->next->next->style[0] != 9){for(i = 0;i < 9;i++){if(openHead->next->next->style[i] != tempNode->style[i]){equalKey = 1;break;}elseequalKey = 0;}if(equalKey)//不相等openHead = openHead->next;elsebreak;}openHead = open->next;if(equalKey)//不相等{while(closedHead->next->style[0] != 9){for(i = 0;i < 9;i++){if(closedHead->next->style[i] != tempNode->style[i]){equalKey = 1;break;}elseequalKey = 0;}if(!equalKey)//相等break;elseclosedHead = closedHead->next;}closedHead = closed->next;}if(equalKey)//不相等{open->next = tempNode;tempNode->next = openHead;tempNode->father = openHead->next;open = open->next;}}}void print(struct node *temp) //输出八数码表{for(j = 0;j < 9;j++){if(temp->style[j] == 0)printf(" \t");elseprintf("%d\t",temp->style[j]);if((j + 1) % 3 == 0)printf("\n");}}void write2txt(){ofstream out("F:\\out_details.txt",ios::app);if( out.fail() ){cerr<<"未找到文件"<<endl;}out<<" 第"<<++num<<"步\n";out<<"open table:\n";while(openHead->next->style[0] != 9){for(i = 0;i < 9;i ++){out<<openHead->next->style[i]<<"\t";if((i+1) % 3 == 0)out<<"\n";}out<<"\n";openHead = openHead->next;}openHead = openHead->next;out<<"*********************\n";out<<"closed table:\n";while(closedHead->next->style[0] != 9){for(i = 0;i < 9;i ++){out<<closedHead->next->style[i]<<"\t";if((i + 1) % 3 ==0)out<<"\n";}out<<"\n";closedHead = closedHead->next;}closedHead = closedHead->next;out<<"-----------------------------------\n";out.close();}void main(){//updateData();//输入八数码数据for(i = 0;i < 9;i++) //判断初始状态是否已经为最终状态{if(wholeStyle[i] == standard1[i]);else{if((i == 3)&&(wholeStyle[i] == standard1[6]));else if((i == 6)&&(wholeStyle[i] == standard1[3]));else{startKey = 1;break;}}}if(!startKey){printf("不用判断!\n");return;}printf("要判断!\n");openHead = new node();open = new node();openHead->style[0] = 9;openHead->next = open;for(i = 0;i < 9;i++)open->style[i] = wholeStyle[i];open->next = openHead;open->father = openHead;closedHead = new node();closed = new node();closedHead->style[0] = 9;closedHead->next = closedHead;closed = closedHead;while(open->style[0] != 9)//当open表不为空时一直循环{judge1(openHead->next);if(local % 3 > 0)//右移{equalKey = 1;tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = openHead->next->style[i];tempSpace = tempNode->style[local - 1];tempNode->style[local - 1] = tempNode->style[local];tempNode->style[local] = tempSpace;judge3();}if(endKey)break;if(local > 2)//下移{equalKey = 1;tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = openHead->next->style[i];tempSpace = tempNode->style[local - 3];tempNode->style[local - 3] = tempNode->style[local];tempNode->style[local] = tempSpace;judge3();}if(endKey)break;if(local % 3 < 2)//左移{equalKey = 1;tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = openHead->next->style[i];tempSpace = tempNode->style[local + 1];tempNode->style[local + 1] = tempNode->style[local];tempNode->style[local] = tempSpace;judge3();}if(endKey)break;if(local < 6)//上移{equalKey = 1;tempNode = new node();//tempNode = malloc(sizeof(struct node));for(i = 0;i < 9;i++)tempNode->style[i] = openHead->next->style[i];tempSpace = tempNode->style[local + 3];tempNode->style[local + 3] = tempNode->style[local];tempNode->style[local] = tempSpace;judge3();}if(endKey)break;closed->next = openHead->next; //把open的标头添加到closed表中openHead->next = openHead->next->next;closed = closed->next;closed->next = closedHead;write2txt();}open->next = tempNode;//把找到的新节点添加到open表中tempNode->next = openHead;tempNode->father = openHead->next;open = open->next;closed->next = openHead->next; //把open的标头添加到closed表中openHead->next = openHead->next->next;closed = closed->next;closed->next = closedHead;write2txt();answer = new node();tempNode = new node();tempNode = open;while(tempNode->style[0] != 9)//将结果路径存于answer{answer = tempNode;tempNode = tempNode->father;tempNode->next = answer;}num = 0;while(answer->next->style[0] != 9)//输出answer{printf("***********第%d步***********\n",num++);print(answer);answer = answer->next;printf("\n");}printf("***********第%d步***********\n",num++);print(answer);if(answer->style[3] != standard1[3])printf("\n!!输入的八数码不合法,不能从初始状态到最终状态\n\n\n\n");return;}3.宽度优先:/***************说明***********************用宽度优先搜索算法实现八数码问题******************************************/#include<iostream>#include<stdio.h>#include<fstream>#include<stdlib.h>#include "string.h"#include "assert.h"#include "windows.h"using namespace std;int wholeStyle[9] = {2,8,3,1,6,4,7,0,5};int standard1[9] = {1,2,3,8,0,4,7,6,5};int local,i,j;int startKey = 0,endKey = 0,equalKey = 1,tempSpace; struct node *openHead,*open; //open表struct node *closedHead,*closed; //closed表struct node *tempNode; //临时节点struct node *answer; //找到的路径int num = 0;struct node{int style[9];struct node *next;struct node *father;};void updateData() //更新要判断数据{int i;printf("请输入八数码原始状态:\n");for(i = 0;i < 9;i++)scanf("%d",&wholeStyle[i]);printf("请输入八数码最终状态:\n");for(i = 0;i < 9;i++)scanf("%d",&standard1[i]);}void judge1(struct node *head)//判断空格位置{for(i = 0;i < 9;i++){if(head->style[i] == 0){local = i;return;}}}int judge2(struct node *head) //判断是否与标准八数码相等,不相等返回值为0{for(i = 0;i < 9;i++){if(head->style[i] != standard1[i]){if((i == 3)&&(head->style[3] == standard1[6]));else if((i == 6)&&(head->style[6] == standard1[3]));elsereturn 0;}}return 1;}void judge3() //判断新生成的八数码是否就是最终状态或者在open、closed表中出现{if(judge2(tempNode))endKey = 1;else{while(openHead->next->next->style[0] != 9){for(i = 0;i < 9;i++){if(openHead->next->next->style[i] != tempNode->style[i]){equalKey = 1;break;}elseequalKey = 0;}if(equalKey)//不相等openHead = openHead->next;elsebreak;}openHead = open->next;if(equalKey)//不相等{while(closedHead->next->style[0] != 9){for(i = 0;i < 9;i++){if(closedHead->next->style[i] != tempNode->style[i]){equalKey = 1;break;}elseequalKey = 0;}if(!equalKey)//相等break;elseclosedHead = closedHead->next;}closedHead = closed->next;}if(equalKey)//不相等{open->next = tempNode;tempNode->next = openHead;tempNode->father = openHead->next;open = open->next;}}}void print(struct node *temp) //输出八数码表{for(j = 0;j < 9;j++){if(temp->style[j] == 0)printf(" \t");elseprintf("%d\t",temp->style[j]);if((j + 1) % 3 == 0)printf("\n");}}void write2txt(){ofstream out("F:\\out_details.txt",ios::app);if( out.fail() ){cerr<<"未找到文件"<<endl;}out<<" 第"<<++num<<"步\n";out<<"open table:\n";while(openHead->next->style[0] != 9){for(i = 0;i < 9;i ++){out<<openHead->next->style[i]<<"\t";if((i+1) % 3 == 0)out<<"\n";}out<<"\n";openHead = openHead->next;}openHead = openHead->next;out<<"*********************\n";out<<"closed table:\n";while(closedHead->next->style[0] != 9){for(i = 0;i < 9;i ++){out<<closedHead->next->style[i]<<"\t";if((i + 1) % 3 ==0)out<<"\n";}out<<"\n";closedHead = closedHead->next;}closedHead = closedHead->next;out<<"-----------------------------------\n";out.close();}void main(){//updateData();//输入八数码数据for(i = 0;i < 9;i++) //判断初始状态是否已经为最终状态{if(wholeStyle[i] == standard1[i]);else{if((i == 3)&&(wholeStyle[i] == standard1[6]));else if((i == 6)&&(wholeStyle[i] == standard1[3]));else{startKey = 1;break;}}}if(!startKey){printf("不用判断!\n");return;}printf("要判断!\n");openHead = new node();open = new node();openHead->style[0] = 9;openHead->next = open;for(i = 0;i < 9;i++)open->style[i] = wholeStyle[i];open->next = openHead;open->father = openHead;closedHead = new node();closed = new node();closedHead->style[0] = 9;closedHead->next = closedHead;closed = closedHead;while(open->style[0] != 9)//当open表不为空时一直循环{judge1(openHead->next);if(local % 3 > 0)//右移{equalKey = 1;tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = openHead->next->style[i];tempSpace = tempNode->style[local - 1];tempNode->style[local - 1] = tempNode->style[local];tempNode->style[local] = tempSpace;judge3();}if(endKey)break;if(local > 2)//下移{equalKey = 1;tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = openHead->next->style[i];tempSpace = tempNode->style[local - 3];tempNode->style[local - 3] = tempNode->style[local];tempNode->style[local] = tempSpace;judge3();}if(endKey)break;if(local % 3 < 2)//左移{equalKey = 1;tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = openHead->next->style[i];tempSpace = tempNode->style[local + 1];tempNode->style[local + 1] = tempNode->style[local];tempNode->style[local] = tempSpace;judge3();}if(endKey)break;if(local < 6)//上移{equalKey = 1;tempNode = new node();//tempNode = malloc(sizeof(struct node));for(i = 0;i < 9;i++)tempNode->style[i] = openHead->next->style[i];tempSpace = tempNode->style[local + 3];tempNode->style[local + 3] = tempNode->style[local];tempNode->style[local] = tempSpace;judge3();}if(endKey)break;closed->next = openHead->next; //把open的标头添加到closed表中openHead->next = openHead->next->next;closed = closed->next;closed->next = closedHead;write2txt();}open->next = tempNode;//把找到的新节点添加到open表中tempNode->next = openHead;tempNode->father = openHead->next;open = open->next;closed->next = openHead->next; //把open的标头添加到closed表中openHead->next = openHead->next->next;closed = closed->next;closed->next = closedHead;write2txt();answer = new node();tempNode = new node();tempNode = open;while(tempNode->style[0] != 9)//将结果路径存于answer{answer = tempNode;tempNode = tempNode->father;tempNode->next = answer;}num = 0;while(answer->next->style[0] != 9)//输出answer{printf("***********第%d步***********\n",num++);print(answer);answer = answer->next;printf("\n");}printf("***********第%d步***********\n",num++);print(answer);if(answer->style[3] != standard1[3])printf("\n!!输入的八数码不合法,不能从初始状态到最终状态\n\n\n\n");return;}4.A算法/***************说明************************* A算法实现八数码问题********************************************/#include<iostream>#include<fstream>#include<iomanip>using namespace std;void print(struct node *temp);int wholeStyle[9] = {2,8,3,1,6,4,7,0,5};int standard1[9] = {1,2,3,8,0,4,7,6,5};int local,i,j;int tempSpace;struct node *openHead,*open; //open表struct node *closedHead,*closed; //closed表struct node *tempNode; //临时节点struct node *answer; //找到的路径int num = 0;bool endKey;struct node{int depth;int judgement_based;int style[9];struct node *next;struct node *father;};void updateData() //更新要判断数据{int i;cout<<"请输入八数码原始状态:"<<endl;for(i = 0;i < 9;i++)cin>>wholeStyle[i];cout<<"请输入八数码最终状态:"<<endl;for(i = 0;i < 9;i++)cin>>standard1[i];}int judge1(struct node *head)//判断空格位置{for(i = 0;i < 9;i++){if(head->style[i] == 0)return i;}}int evaluation_function(struct node *head) //计算不在正确位置的点的个数{int not_correct_position = 0;for(i = 0;i < 9;i++)if((head->style[i] != 0)&&(head->style[i] != standard1[i]))not_correct_position++;return not_correct_position;}void print(struct node *temp) //输出八数码表{for(j = 0;j < 9;j++){if(temp->style[j] == 0)cout<<" \t";elsecout<<temp->style[j]<<"\t";if((j + 1) % 3 == 0)cout<<endl;}}void write2txt() //将过程记录到文本文档中{ofstream out("F:\\out_details4.txt",ios::app);if( out.fail() ){cerr<<"未找到文件"<<endl;}out<<" 第"<<++num<<"步\n";out<<"open table:\n";while(openHead->next->style[0] != 9){for(i = 0;i < 9;i ++){out<<openHead->next->style[i]<<"\t";if((i+1) % 3 == 0)out<<"\n";}out<<"估值:";out<<openHead->next->judgement_based<<"\n";openHead = openHead->next;}openHead = openHead->next;out<<"*********************\n";out<<"closed table:\n";while(closedHead->next->style[0] != 9){for(i = 0;i < 9;i ++){out<<closedHead->next->style[i]<<"\t";if((i + 1) % 3 ==0)out<<"\n";}out<<"深度:"<<closedHead->next->depth<<" 估值:"<<closedHead->next->judgement_based<<"\n";closedHead = closedHead->next;}closedHead = closedHead->next;out<<"-----------------------------------\n";out.close();}void basic_exchange_oper() //每一次基本的交换都要进行的动作{if(judge1(tempNode) != judge1(closed->father))//当新生成节点的空格位置与closed父亲节点的空格位置不相等{tempNode->father = closed; //新生成节点的指向它的父亲节点tempNode->depth = closed->depth + 1;//深度加1tempNode->judgement_based = evaluation_function(tempNode) + tempNode->depth;//计算估值while(openHead->next->style[0] != 9){if(tempNode->judgement_based > openHead->next->judgement_based){openHead = openHead->next;}else{tempNode->next = openHead->next;openHead->next = tempNode;openHead = open->next;return;}}//插入的值比最后一个还大进行下面的操作openHead = open->next;//先恢复表头否则Head指向为最后一个open->next = tempNode;tempNode->next = openHead;open = open->next;return;}}void main(){//updateData();//输入八数码数据openHead = new node(); //初始化open表open = new node();openHead->style[0] = 9;openHead->next = open;for(i = 0;i < 9;i++)open->style[i] = wholeStyle[i];open->next = openHead;open->father = openHead;open->depth = 0;open->judgement_based = evaluation_function(open) + open->depth;//这行可以不写closedHead = new node(); //初始化closed表closed = new node();closedHead->style[0] = 9;closedHead->next = closedHead;closed = closedHead;int min_judgement1 = open->judgement_based;while(open->style[0] != 9)//当open表不为空时一直循环{//updateData();//输入八数码数据write2txt();closed->next = openHead->next; //把open表中第一组八数码移到closed表中openHead->next = openHead->next->next;closed = closed->next;closed->next = closedHead;if(openHead->next->style[0] == 9)//如果是第一次则open暂时指向openHead open = openHead;if(closed->judgement_based == closed->depth)//判断新移进closed表中的八数码的f 值是否等于它的层数{cout<<"succeed!"<<endl;write2txt();answer = new node();while(closed->style[0] != 9) //将结果存于answer表中{answer = closed;closed = closed->father;closed->next = answer;}num = 0;while(answer->style[0] != 9) //控制台显示步骤{cout<<"******第"<<num++<<"步***********\n";print(answer);cout<<endl;answer = answer->next;}return;}else //如果closed表末的八数码是最终状态则拓展新的八数码{local = judge1(closed);if(local % 3 > 0)//右移{tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = closed->style[i];tempSpace = tempNode->style[local - 1];tempNode->style[local - 1] = tempNode->style[local];tempNode->style[local] = tempSpace;basic_exchange_oper();}if(local < 6)//上移{tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = closed->style[i];tempSpace = tempNode->style[local + 3];tempNode->style[local + 3] = tempNode->style[local];tempNode->style[local] = tempSpace;basic_exchange_oper();}if(local > 2)//下移{tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = closed->style[i];tempSpace = tempNode->style[local - 3];tempNode->style[local - 3] = tempNode->style[local];tempNode->style[local] = tempSpace;basic_exchange_oper();}if(local % 3 < 2)//左移{tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = closed->style[i];tempSpace = tempNode->style[local + 1];tempNode->style[local + 1] = tempNode->style[local];tempNode->style[local] = tempSpace;basic_exchange_oper();}}}cout<<"false!"<<endl;}神经网络实验群神经网络实验一、实验目的:理解反向传播网络的结构和原理,掌握反向传播算法对神经元的训练过程,了解反向传播公式。