人工智能试验-八数码难题
人工智能 八数码实验

人工智能作业八数码问题一、题目八数码问题:初始状态图:目标状态图:二、算符与状态空间算符:左、上、右、下状态空间:状态:A=(X0,X1,X2,X3,X4,X5,X6,X7,X8) 初始状态:S0=(0,4,1,5,2,8,3,6,7);目标状态:Sg=(0,1,7,5,2,8,3,6,4)。
三、搜索树22求解:四、Open 表,Closed 表Open 表: Closed 表:五、程序代码/* 3_13.pro eight puzzle */traceDOMAINSstate=st(in,in,in,in,in,in,in,in,in)in=integerDATABASE-mydatabaseopen(state,integer)closed(integer,state,integer)res(state)mark(state)fail_PREDICATESsolvesearch(state,state)resultsearchingstep4(integer,state)step56(integer,state)equal(state,state)repeatresulting(integer)rule(state,state)GOALsolve.CLAUSESsolve:-search(st(0,4,1,5,2,8,3,6,7),st(0,1,7,5,2,8,3,6,4)),result. search(Begin,End):-retractall(_,mydatabase),assert(closed(0,Begin,0)),assert(open(Begin,0)),assert(mark(End)),repeat,searching,!.result:-not(fail_),retract(closed(0,_,0)),closed(M,_,_),resulting(M), !.result:-beep,write("sorry don't find a road!").searching:-open(State,Pointer),retract(open(State,Pointer)),closed(No,_,_),No2=No+1,asserta(closed(No2,State,Pointer)),!,step4(No2,State).searching:-assert(fail_).step4(_,State):-mark(End),equal(State,End).step4(No,State):-step56(No,State),!,fail.step56(No,StateX):-rule(StateX,StateY),not(open(StateY,_)),not(closed(_,StateY,_)),assertz(open(StateY,No)),fail.step56(_,_):-!.equal(X,X).repeat.repeat:-repeat.resulting(N):-closed(N,X,M),asserta(res(X)),resulting(M).resulting(_):-res(X),write(X),nl,fail.resulting(_):-!.rule(st(X0,X1,X2,X3,X4,X5,X6,X7,X8),st(X8,X1,X2,X3,X4,X5,X6,X7,X0)):-X0=0.rule(st(X0,X1,X2,X3,X4,X5,X6,X7,X8),st(X2,X1,X0,X3,X4,X5,X6,X7,X8)):-X0=0.rule(st(X0,X1,X2,X3,X4,X5,X6,X7,X8),st(X4,X1,X2,X3,X0,X5,X6,X7,X8)):-X0=0.rule(st(X0,X1,X2,X3,X4,X5,X6,X7,X8),st(X6,X1,X2,X3,X4,X5,X0,X7,X8)):-X0=0.rule(st(X0,X1,X2,X3,X4,X5,X6,X7,X8),st(X0,X2,X1,X3,X4,X5,X6,X7,X8)):-X1=0.st(X0,X2,X8,X3,X4,X5,X6,X7,X1)):-X1=0. rule(st(X0,X1,X2,X3,X4,X5,X6,X7,X8), st(X0,X2,X1,X3,X4,X5,X6,X7,X8)):-X2=0. rule(st(X0,X1,X2,X3,X4,X5,X6,X7,X8), st(X0,X1,X3,X2,X4,X5,X6,X7,X8)):-X2=0. rule(st(X0,X1,X2,X3,X4,X5,X6,X7,X8), st(X2,X1,X0,X3,X4,X5,X6,X7,X8)):-X2=0. rule(st(X0,X1,X2,X3,X4,X5,X6,X7,X8), st(X0,X1,X3,X2,X4,X5,X6,X7,X8)):-X3=0. rule(st(X0,X1,X2,X3,X4,X5,X6,X7,X8), st(X0,X1,X2,X4,X3,X5,X6,X7,X8)):-X3=0. rule(st(X0,X1,X2,X3,X4,X5,X6,X7,X8), st(X4,X1,X2,X3,X0,X5,X6,X7,X8)):-X4=0. rule(st(X0,X1,X2,X3,X4,X5,X6,X7,X8), st(X0,X1,X2,X4,X3,X5,X6,X7,X8)):-X4=0. rule(st(X0,X1,X2,X3,X4,X5,X6,X7,X8), st(X0,X1,X2,X3,X5,X4,X6,X7,X8)):-X4=0. rule(st(X0,X1,X2,X3,X4,X5,X6,X7,X8), st(X0,X1,X2,X3,X4,X6,X5,X7,X8)):-X5=0. rule(st(X0,X1,X2,X3,X4,X5,X6,X7,X8), st(X0,X1,X2,X3,X5,X4,X6,X7,X8)):-X5=0. rule(st(X0,X1,X2,X3,X4,X5,X6,X7,X8), st(X0,X1,X2,X3,X4,X5,X7,X6,X8)):-X6=0. rule(st(X0,X1,X2,X3,X4,X5,X6,X7,X8), st(X6,X1,X2,X3,X4,X5,X0,X7,X8)):-X6=0. rule(st(X0,X1,X2,X3,X4,X5,X6,X7,X8), st(X0,X1,X2,X3,X4,X6,X5,X7,X8)):-X6=0. rule(st(X0,X1,X2,X3,X4,X5,X6,X7,X8),rule(st(X0,X1,X2,X3,X4,X5,X6,X7,X8), st(X0,X1,X2,X3,X4,X5,X7,X6,X8)):-X7=0. rule(st(X0,X1,X2,X3,X4,X5,X6,X7,X8), st(X0,X8,X2,X3,X4,X5,X6,X7,X1)):-X8=0. rule(st(X0,X1,X2,X3,X4,X5,X6,X7,X8), st(X8,X1,X2,X3,X4,X5,X6,X7,X0)):-X8=0. rule(st(X0,X1,X2,X3,X4,X5,X6,X7,X8), st(X0,X1,X2,X3,X4,X5,X6,X8,X7)):-X8=0.六、运行结果截图编译后:运行后:。
人工智能8位数码难题的问题求解

#define DOWN 1
#define LEFT 2
#define RIGHT 3
#define Bit char
typedef struct maps
{
Bit detail[9];
int myindex; //记录自己节点在hash表中的位置
Bit position; //记录空格(0)在序列中的位置
实验软硬件要求:网络计算机,c++编程环境
实验内容、方法和步骤(可附页)
我们将八数码难题分布在3×3方格棋盘上,分别放置了标有数字1,2,3,4,5,6,7,8的八张牌,初始状态S0,目标状态如图所示,可以使用的操作有:空格上移,空格左移,空格右移,空格下移。我们将是用广度优先搜索算法来解决这一问题。
int newindex = Parent.myindex ;
Bit *p = Parent.detail;
switch(direct)
{
case UP :
{
newindex -= 3*40320 ;
newindex += ( p[ i - 2 ] > p[ i - 3 ]) ? ( Factorial[ p[ i - 3 ] ] ) : ( - Factorial[ p[ i - 2 ] ] );
}p,*PMap;
Map org; //初始状态
int EndIndex; //目标,上移,下移,左移,右移
int const derection[4] ={ -3 , 3 , -1 , 1 } ;
//可移动的四个方向
int const Factorial[9] = {40320 , 5040 , 720 , 120 , 24 , 6 , 2 , 1 , 1 };
八数码问题 实验报告

八数码问题实验报告八数码问题实验报告引言:八数码问题是一种经典的数学难题,在计算机科学领域有着广泛的研究和应用。
本实验旨在通过探索八数码问题的解法,深入理解该问题的本质,并通过实验结果评估不同算法的效率和准确性。
一、问题描述:八数码问题是一个在3×3的棋盘上,由1至8的数字和一个空格组成的拼图问题。
目标是通过移动棋盘上的数字,使得棋盘上的数字排列按照从小到大的顺序排列,最终形成如下的目标状态:1 2 34 5 67 8二、解法探索:1. 深度优先搜索算法:深度优先搜索算法是一种经典的解决拼图问题的方法。
该算法通过不断尝试所有可能的移动方式,直到找到目标状态或者无法再继续移动为止。
实验结果显示,该算法在八数码问题中能够找到解,但由于搜索空间庞大,算法的时间复杂度较高。
2. 广度优先搜索算法:广度优先搜索算法是另一种常用的解决八数码问题的方法。
该算法通过逐层扩展搜索树,从初始状态开始,逐步扩展所有可能的状态,直到找到目标状态。
实验结果显示,该算法能够找到最短路径的解,但同样面临搜索空间庞大的问题。
3. A*算法:A*算法是一种启发式搜索算法,结合了深度优先搜索和广度优先搜索的优点。
该算法通过使用一个估价函数来评估每个搜索状态的优劣,并选择最有希望的状态进行扩展。
实验结果显示,A*算法在八数码问题中表现出色,能够高效地找到最优解。
三、实验结果与分析:通过对深度优先搜索、广度优先搜索和A*算法的实验,得出以下结论:1. 深度优先搜索算法虽然能够找到解,但由于搜索空间庞大,时间复杂度较高,不适用于大规模的八数码问题。
2. 广度优先搜索算法能够找到最短路径的解,但同样面临搜索空间庞大的问题,对于大规模问题效率较低。
3. A*算法在八数码问题中表现出色,通过合理的估价函数能够高效地找到最优解,对于大规模问题具有较好的效果。
四、结论与展望:本实验通过对八数码问题的解法探索,深入理解了该问题的本质,并评估了不同算法的效率和准确性。
八数码实验报告

八数码实验报告八数码实验报告引言:八数码,也被称为滑块拼图,是一种经典的益智游戏。
在这个实验中,我们将探索八数码问题的解决方案,并分析其算法的效率和复杂性。
通过这个实验,我们可以深入了解搜索算法在解决问题中的应用,并且探讨不同算法之间的优劣势。
1. 问题描述:八数码问题是一个在3x3的方格上进行的拼图游戏。
方格中有8个方块,分别标有1到8的数字,还有一个空方块。
游戏的目标是通过移动方块,将它们按照从左上角到右下角的顺序排列。
2. 算法一:深度优先搜索(DFS)深度优先搜索是一种经典的搜索算法,它从初始状态开始,不断地向前搜索,直到找到目标状态或者无法继续搜索为止。
在八数码问题中,深度优先搜索会尝试所有可能的移动方式,直到找到解决方案。
然而,深度优先搜索在解决八数码问题时存在一些问题。
由于搜索的深度可能非常大,算法可能会陷入无限循环,或者需要很长时间才能找到解决方案。
因此,在实际应用中,深度优先搜索并不是最优的选择。
3. 算法二:广度优先搜索(BFS)广度优先搜索是另一种常用的搜索算法,它从初始状态开始,逐层地向前搜索,直到找到目标状态。
在八数码问题中,广度优先搜索会先尝试所有可能的一步移动,然后再尝试两步移动,依此类推,直到找到解决方案。
与深度优先搜索相比,广度优先搜索可以保证找到最短路径的解决方案。
然而,广度优先搜索的时间复杂度较高,尤其是在搜索空间较大时。
因此,在实际应用中,广度优先搜索可能不太适合解决八数码问题。
4. 算法三:A*算法A*算法是一种启发式搜索算法,它在搜索过程中利用了问题的启发信息,以提高搜索效率。
在八数码问题中,A*算法会根据每个状态与目标状态之间的差异,选择最有可能的移动方式。
A*算法通过综合考虑每个状态的实际代价和启发式估计值,来评估搜索路径的优劣。
通过选择最优的路径,A*算法可以在较短的时间内找到解决方案。
然而,A*算法的实现较为复杂,需要合适的启发函数和数据结构。
人工智能实验报告完整版八数码+验证解读

把数码问题就是把一串数字变为下边这个样子: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,63,2,1,8,0,4,7,6,5 1,0,4,2,7,3,8,5,61,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++;}while(local!=3);}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();if(style[2]!=3){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 表中closed->next = openHead->next; //把 open 的标头增添到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 表中open->next = tempNode;// 把找到的新节点增添到tempNode->next = openHead;tempNode->father = openHead->next;open = open->next;closed 表中closed->next = openHead->next; //把 open 的标头增添到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;// 深度加 1 tempNode->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;}神经网络实验群神经网络实验一、实验目的:理解反向流传网络的构造和原理,掌握反向流传算法对神经元的训练过程,认识反向流传公式。
八数码问题

+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步到达
人工智能实验一 八数码问题

启发中的估价是用估价函数表示的,如:f(n) = g(n) + h(n) 其中 f(n) 是节点 n 的估价函数,g(n)是在状态空间中从初始节点到 n 节点的实际代价, h(n)是从 n 到目标节点最佳路径的估计代价。 在此八数码问题中,显然 g(n)就是从初始状 态变换到当前状态所移动的步数,估计函数 f(n)我们就可采用当前状态各个数字牌不在目标
附录—源代码及其注释 #include "stdafx.h" #include "iostream.h" #include <time.h> #include <stdio.h> #include <dos.h> #include <conio.h> static int target[9]={1,2,3,8,0,4,7,6,5}; //class definition
eight_num(int init_num[9]); eight_num(int num1,int num2,int num3,int num4,int num5,int num6,int num7,int num8,int num9) {
num[0]=num1; num[1]=num2; num[2]=num3; num[3]=num4; num[4]=num5; num[5]=num6; num[6]=num7; num[7]=num8; num[8]=num9; } eight_num(void) { for (int i=0;i<9;i++)
人工智能实验六 A算法8数码问题

我们没有这样区分,而是将所有结点放在一个队列中,并用头指针指示 队列头结点,开始时它就是初始结点。每次都取出队列头的结点进行扩 展,当一个结点不能再扩展时,就将队列头指针加1,让它只向下一个 结点,实际上就是把不能扩展的结点放到了关闭列表中。这样在判断一 个新扩展出的结点是否与已扩展的结点重复、与那一种结点重复时,就 很方便,因为重复结点编号小于队列头指针则它在关闭列表中,重复结 点编号在队列头和尾指针之间则与可扩展结点重复,否则就不重复。 4.八数码问题的A*算法的估价函数 八数码问题的估价函数f(n)由两部分构成, g(n) 是从初始结点到结点n的 实际代价,在此它就是结点深度,也就是从初始结点到该结点的状态变 化次数,这是已知的。而 h(n) 是从结点n到目标结点最佳路径的估计代 价,这是需要定义的。通常取h(n)为当前结点各个位置上的数字(不包 括0)到目标结点同一数字所在位置的距离之和。举例来说,若当前结 点第一个位置(左上角)是3,而目标结点的数字3在最后一个位置(右 下角),那么3的距离就是4(从左上角要移动四步才到达右下角)。其 他各个数字的距离按照同样方法计算,全部数字距离之和就是h(n)。 为了计算结点的估价函数,须先计算函数h(n),如果直接根据状态中数 字的排列进行计算比较困难。在此定义另外两个数组u(9)和v(9),用它 们存储状态中各个数字的位置,因为每一个状态的八个数码存放在数组 p(9)中,u(9)中则按序存放0~8这些数字的位置——它们在p(9)中对应的 下标。例如,如果p(9)中的数字排列是3 5 8 0 2 1 7 6 4,则u(9)中则是3 5
If Equal(Temp, EndNode) Then DispPath head DispNode Nodes(head) Exit Sub End If If SpacMove(Temp, i) Then st = head Calcuf Temp k = Rept(Temp) If k > tail Then Sortf tail = tail + 1
八数码 人工智能实验报告

八数码人工智能实验报告八数码人工智能实验报告引言:八数码是一种经典的数学问题,也是人工智能领域中常用的实验题目之一。
本次实验旨在通过使用搜索算法解决八数码问题,探讨人工智能在解决复杂问题上的应用。
一、问题描述:八数码问题是一种数字排列游戏,使用一个3x3的方格,其中8个方格上各有一个数字,剩下一个方格为空白。
通过移动数字方格,最终将数字按照从小到大的顺序排列,空白方格位于最后一个位置。
例如,初始状态为:1 2 38 47 6 5目标状态为:1 2 34 5 67 8二、算法选择:本次实验采用了A*搜索算法来解决八数码问题。
A*算法是一种启发式搜索算法,通过估计每个搜索节点到达目标状态的代价来进行搜索。
它综合了广度优先搜索和最佳优先搜索的优点,能够高效地找到最优解。
三、实验过程:1. 状态表示:在实验中,我们使用一个3x3的二维数组来表示八数码的状态。
数组中的每个元素代表一个方格的数字,空白方格用0表示。
2. 启发函数:为了评估每个搜索节点到达目标状态的代价,我们需要定义一个启发函数。
本实验中,我们选择了曼哈顿距离作为启发函数。
曼哈顿距离是指每个数字方格与其目标位置之间的水平和垂直距离之和。
3. A*算法:A*算法的核心思想是维护一个优先队列,根据每个搜索节点的估价函数值进行排序。
具体步骤如下:- 将初始状态加入优先队列,并设置初始估价函数值为0。
- 从优先队列中取出估价函数值最小的节点,进行扩展。
- 对于每个扩展节点,计算其估价函数值,并将其加入优先队列。
- 重复上述步骤,直到找到目标状态或者队列为空。
四、实验结果:经过实验,我们发现A*算法能够高效地解决八数码问题。
对于初始状态为随机排列的八数码,A*算法能够在较短的时间内找到最优解。
实验结果表明,A*算法在解决八数码问题上具有较好的性能。
五、实验总结:本次实验通过使用A*搜索算法解决八数码问题,展示了人工智能在解决复杂问题上的应用。
A*算法通过合理的启发函数和优先队列的维护,能够高效地找到最优解。
八数码问题人工智能实验报告

基于人工智能的状态空间搜索策略研究——八数码问题求解(一)实验软件或编程语言或其它编程语言(二)实验目的1. 熟悉人工智能系统中的问题求解过程;2. 熟悉状态空间的盲目搜索和启发式搜索算法的应用;3. 熟悉对八数码问题的建模、求解及编程语言的应用。
(三)需要的预备知识1. 熟悉或编程语言或者其它编程语言;2. 熟悉状态空间的宽度优先搜索、深度优先搜索和启发式搜索算法;3. 熟悉计算机语言对常用数据结构如链表、队列等的描述应用;4. 熟悉计算机常用人机接口设计。
(四)实验数据及步骤1. 实验内容八数码问题:在3×3的方格棋盘上,摆放着1到8这八个数码,有1个方格是空的,其初始状态如图1所示,要求对空格执行空格左移、空格右移、空格上移和空格下移这四个操作使得棋盘从初始状态到目标状态。
437465图1 八数码问题示意图请任选一种盲目搜索算法(深度优先搜索或宽度优先搜索)或任选一种启发式搜索方法(A 算法或 A* 算法)编程求解八数码问题(初始状态任选),并对实验结果进行分析,得出合理的结论。
2. 实验步骤(1)分析算法基本原理和基本流程;程序采用宽度优先搜索算法,基本流程如下:(2)确定对问题描述的基本数据结构,如 Open 表和 Closed 表等;(3)编写算符运算、目标比较等函数;(4)编写输入、输出接口;(5)全部模块联调;(6)撰写实验报告。
(五)实验报告要求所撰写的实验报告必须包含以下内容:1. 算法基本原理和流程框图;2. 基本数据结构分析和实现;3. 编写程序的各个子模块,按模块编写文档,含每个模块的建立时间、功能、输入输出参数意义和与其它模块联系等;4. 程序运行结果,含使用的搜索算法及搜索路径等;5. 实验结果分析;6. 结论;7. 提供全部源程序及软件的可执行程序。
附:实验报告格式一、实验问题二、实验目的三、实验原理四、程序框图五、实验结果及分析六、结论。
人工智能实验报告,包括八数码问题八皇后问题和tsp问题

八数码问题(一)问题描述在一个3*3的方棋盘上放置着1,2,3,4,5,6,7,8八个数码,每个数码占一格,且有一个空格。
这些数码可以在棋盘上移动,其移动规则是:与空格相邻的数码方格可以移入空格。
现在的问题是:对于指定的初始棋局和目标棋局,给出数码的移动序列。
该问题称八数码难题或者重排九宫问题。
(二)问题分析八数码问题是个典型的状态图搜索问题。
搜索方式有两种基本的方式,即树式搜索和线式搜索。
搜索策略大体有盲目搜索和启发式搜索两大类。
盲目搜索就是无“向导”的搜索,启发式搜索就是有“向导”的搜索。
1、启发式搜索由于时间和空间资源的限制,穷举法只能解决一些状态空间很小的简单问题,而对于那些大状态空间的问题,穷举法就不能胜任,往往会导致“组合爆炸”。
所以引入启发式搜索策略。
启发式搜索就是利用启发性信息进行制导的搜索。
它有利于快速找到问题的解。
由八数码问题的部分状态图可以看出,从初始节点开始,在通向目标节点的路径上,各节点的数码格局同目标节点相比较,其数码不同的位置个数在逐渐减少,最后为零。
所以,这个数码不同的位置个数便是标志一个节点到目标节点距离远近的一个启发性信息,利用这个信息就可以指导搜索。
即可以利用启发信息来扩展节点的选择,减少搜索范围,提高搜索速度。
启发函数设定。
对于八数码问题,可以利用棋局差距作为一个度量。
搜索过程中,差距会逐渐减少,最终为零,为零即搜索完成,得到目标棋局。
(三)数据结构与算法设计该搜索为一个搜索树。
为了简化问题,搜索树节点设计如下:struct Chess//棋盘{int cell[N][N];//数码数组int Value;//评估值Direction BelockDirec;//所屏蔽方向struct Chess * Parent;//父节点};int cell[N][N]; 数码数组:记录棋局数码摆放状态。
int Value; 评估值:记录与目标棋局差距的度量值。
Direction BelockDirec; 所屏蔽方向:一个屏蔽方向,防止回推。
人工智能实验报告八数码

人工智能实验报告八数码
人工智能实验报告:八数码
引言
人工智能(AI)是当今世界上最热门的领域之一,它已经在许多领域取得了巨大的成功,包括医疗保健、金融、交通和娱乐等。
在这篇实验报告中,我们将探讨人工智能在解决八数码问题上的应用。
八数码问题是一个经典的智力游戏,它要求玩家将一个3x3的方格中的数字1-8和一个空白格按照一定的规则进行移动,最终达到特定的排列顺序。
这个问题看似简单,但实际上是一个复杂的组合优化问题,需要大量的搜索和计算才能找到最优解。
实验目的
本实验旨在使用人工智能技术解决八数码问题,通过比较不同算法的表现,评估它们在解决这一问题上的效率和准确性。
实验方法
我们使用了两种经典的人工智能算法来解决八数码问题,分别是深度优先搜索(DFS)和A*搜索算法。
我们编写了相应的程序,并在相同的硬件环境下进行了实验。
实验结果
通过实验我们发现,深度优先搜索算法在解决八数码问题上存在着局部最优解的问题,容易陷入死循环。
而A*搜索算法则能够更快地找到最优解,并且在解决问题时所需的搜索次数更少。
结论
本实验结果表明,A*搜索算法在解决八数码问题上表现更优秀,具有更高的效率和准确性。
这为我们在实际应用中选择合适的人工智能算法提供了重要的参考。
未来展望
随着人工智能技术的不断发展,我们相信在解决类似的组合优化问题上会出现更多更高效的算法。
我们将继续深入研究,探索更多的人工智能算法,并将其应用于更广泛的领域,为人类社会带来更多的便利和创新。
八数码问题实验报告

八数码问题实验报告八数码问题实验报告引言:八数码问题,也被称为九宫格问题,是一种经典的数学谜题。
在一个3x3的方格中,摆放有1至8的数字,其中一个位置为空。
目标是通过交换数字的位置,将数字按照从小到大的顺序排列,最终使得空格位于最后一个位置。
本实验旨在通过编程实现八数码问题的求解,并探讨不同算法在解决该问题上的效果和优劣。
实验步骤:1. 算法选择在本次实验中,我们选择了广度优先搜索算法和A*算法作为求解八数码问题的两种不同方法。
广度优先搜索算法是一种盲目搜索算法,它通过逐层扩展搜索树,直到找到目标状态。
而A*算法则是一种启发式搜索算法,它结合了广度优先搜索和启发式函数,通过评估每个状态的代价来指导搜索过程,以找到最优解。
2. 算法实现我们使用Python语言实现了以上两种算法。
首先,我们定义了一个表示状态的类,并实现了状态的初始化、移动、判断是否达到目标状态等基本操作。
然后,我们分别编写了广度优先搜索算法和A*算法的求解函数。
在广度优先搜索算法中,我们使用队列数据结构来保存待扩展的状态,以实现逐层扩展的效果;在A*算法中,我们使用优先队列来保存待扩展的状态,并根据启发式函数的值进行优先级排序。
3. 实验结果我们使用了多个测试样例来验证两种算法的求解效果。
实验结果表明,广度优先搜索算法能够找到解,但是在面对状态空间较大的情况下,搜索时间会呈指数级增长。
而A*算法则能够更快地找到最优解,其效率相对较高。
然而,A*算法需要选择合适的启发式函数,并且对于某些特殊情况,可能会陷入局部最优解而无法找到最优解。
4. 结果分析通过对比两种算法的求解结果,我们可以发现广度优先搜索算法和A*算法在时间效率和解的质量上存在一定的差异。
广度优先搜索算法适用于状态空间较小的情况,但是在状态空间较大时效率较低;而A*算法则能够在较短的时间内找到最优解,但需要对问题进行合理的建模和启发式函数的选择。
因此,在实际应用中,我们需要根据问题的规模和特点来选择合适的算法。
人工智能 八数码难题

实验报告课程名称人工智能_____________实验项目八数码难题______________实验仪器电脑、visual C++_________系别____________ 专业__ _____班级/学号学生姓名_ _________实验日期____成绩_______________________指导教师_________一、实验目的理解并熟悉掌握深度优先搜索和广度优先搜索地方法。
二、实验内容九宫格中有8个数码,其中只有一个空,规则是只能把一个数码移动到空的格子中,要求从一个初始状态移动到一个目标状态所要花费的最少步数【算法分析】解决此类问题的办法是宽度搜索,深度搜索耗时太大无法接受。
当需要移动的步数很多时,普通的宽度搜索仍旧无法满足需要,需要对其进行优化。
这个问题也可以推广到流行的拼图游戏。
【具体步骤】一、确定问题规模(考虑搜索的时间代价)二、确定产生式规则(如果规则太多,则时间代价会很大)三、套用经典宽度搜索框架写程序三、代码和结果#include <stdlib.h>#include <stdio.h>typedef struct Node {int num[9]; //棋盘状态int deepth; //派生的深度g(n)int diffnum; //不在位的数目h(n)int value; //耗散值f(n)=g(n)+h(n)struct Node * pre;struct Node * next;struct Node * parent;}numNode; /* ---------- end of struct numNode ---------- */int origin[9]; //棋盘初始状态int target[9]; //棋盘目标状态int numNode_num,total_step;numNode *open,*close; //Open表和Close表numNode *create_numNode(){return (numNode *)malloc(sizeof(numNode));}numNode *open_getfirst(numNode *head); //返回第一项,并从Open表中删除void open_insert(numNode *head,numNode *item); //向Open表中按序插入新节点void close_append(numNode *head,numNode *item); //向Close表中插入新节点int expand(numNode *item); //扩展节点int print_result(numNode *item); //打印结果numNode *copy_numNode(numNode *orgin);char isNewNode(numNode *open,numNode *close,int num[9]);//是否在Open表或Close表中void print_num(int num[9]); //打印棋盘状态int diff(int num[9]); //求不在位棋子的个数void init(); //初始化,获得棋盘初始状态和目标状态void swap(int *a,int *b);int operate(int num[],int op);void free_list(numNode *head);/** === FUNCTION ======================================================================* Name: 主函數* Description: 程序入口*=============================================================================== ======*/intmain ( int argc, char *argv[] ){//初始化Open表和Close表open=create_numNode();close=create_numNode();open->pre=open->next=close->pre=close->next=NULL;init(); //由用户输入初始和目标状态//初始化初始节点numNode *p1;p1=create_numNode();p1->parent=NULL;p1->deepth=0;int i=0;for ( i=0; i<9; i++){p1->num[i]=origin[i];}open_insert(open,p1);numNode_num=1;p1=open_getfirst(open);while (p1!=NULL){close_append(close,p1);if(expand(p1))return EXIT_SUCCESS;p1=open_getfirst(open);}printf("No solution!\n");return EXIT_SUCCESS;} /* ---------- end of function main ---------- */voidinit ( ){while(1){printf("Please input opriginal status:\nFor example:123456780 stands for\n""1 2 3\n""4 5 6\n""7 8 0\n");char temp[10];scanf("%s",&temp);int i=0;for ( i=0;i<9 && temp[i]-'0'>=0 && temp[i]-'0'<=8; i++) {origin[i]=temp[i]-'0';}printf("Please input target status:\n");scanf("%s",&temp);int j=0;for ( j=0; j<9 && temp[j]-'0'>=0 && temp[j]-'0'<=8; j++){target[j]=temp[j]-'0';}system("cls");if ( i==9&&j==9){break;}}} /* ----- end of function init ----- */voidopen_insert (numNode *head,numNode *item){numNode *p,*q;p=head->next;q=head;while ( p!=NULL && item->value > p->value ){q=p;p=p->next;}q->next=item;item->pre=q;item->next=p;if(p!=NULL){p->pre=item;}} /* ----- end of function open_insert ----- */numNode *open_getfirst (numNode *head){numNode *p;if ( head->next == NULL ){return NULL;}p=head->next;head->next=p->next;if ( p->next != NULL ){p->next->pre=head;}p->pre=NULL;p->next=NULL;return p;} /* ----- end of function open_getfirst ----- */voidclose_append (numNode *head,numNode *item) {item->next=head->next;item->pre=head;head->next=item;if ( item->next!=NULL ){item->next->pre=item;}} /* ----- end of function close_append ----- */intexpand (numNode *p1){numNode * p2;int op=1;for ( op=1; op<=4; op++){p2=copy_numNode(p1);operate(p2->num,op);if(isNewNode(open,close,p2->num)=='N'){p2->parent=p1;p2->deepth=p1->deepth+1;p2->diffnum=diff(p2->num);p2->value=p2->deepth+p2->diffnum;if(p2->diffnum==0){total_step=print_result(p2);printf("Total step: %d\n",total_step);free_list(open);free_list(close);return 1;}else{numNode_num++;open_insert(open,p2);}}elsefree(p2);}return 0;} /* ----- end of function expand ----- */intoperate(int m[], int op){int blank;blank=0;while (m[blank]!=0 && blank<9 )++blank;if (blank==9)return 1;switch (op) {case 1: /* up */if (blank>2)swap(m+blank,m+blank-3);break;case 2: /* down */if (blank<6)swap(m+blank,m+blank+3);break;case 3: /* left */if (blank!=0 && blank!=3 && blank!=6)swap(m+blank,m+blank-1);break;case 4: /* right */if (blank!=2 && blank!=5 && blank!=8)swap(m+blank,m+blank+1);break;default : return 1;}return 0;}voidswap(int *a, int *b){int c;c=*a;*a=*b;*b=c;}numNode *copy_numNode (numNode *origin){numNode *p;p=create_numNode();p->deepth=origin->deepth;p->diffnum=origin->diffnum;p->value=origin->value;int i;for ( i=0; i<9; i++){(p->num)[i]=(origin->num)[i];}return p;} /* ----- end of function copy_numNode ----- */intdiff (int num[9]){int i,diffnum=0;for(i=0;i<9;i++)if(num[i]!=target[i])diffnum++;return diffnum;} /* ----- end of function diff ----- */charisNewNode (numNode *open,numNode *close,int num[9]) {numNode *p;int i=0;p=open->next;while ( p!=NULL ){for ( i=0; i<9; i++){if(p->num[i]!=num[i])break;}if(i==9)return 'O'; //Openp=p->next;}p=close->next;while ( p!=NULL ){for ( i=0; i<9; i++){if(p->num[i]!=num[i])break;}if(i==9)return 'C'; //Closep=p->next;}return 'N';} /* ----- end of function isNewNode ----- */voidfree_list (numNode *head){numNode *p,*q;p=head->next;while ( p!=NULL ){q=p->next;free(p);p=q;}free(head);} /* ----- end of function free_list ----- */voidprint_num (int num[9]){int i;for ( i=0; i<9; i++){printf("%d\t",num[i]);if((i%3)==2)printf("\n");}} /* ----- end of function print_num ----- */intprint_result ( numNode *item){numNode *p;int step;p=item;if(p!=NULL){step=print_result(p->parent);printf("\nStep %d:\n",step+1);print_num(p->num);return step+1;}else{return -1;}}四.实验心得这次试验让我更加深入了解了什么是人工智能,让我了解了人工智能的作用以及含义和人工智能的使用范围以及对于我们未来生活得作用的广大。
人工智能实验报告 八数码

人工智能实验报告八数码人工智能实验报告八数码引言:人工智能(Artificial Intelligence,简称AI)作为一门前沿的学科,已经在各个领域展现出了巨大的应用潜力。
其中,八数码问题作为一个经典的算法问题,被广泛应用于人工智能领域。
本文将对八数码问题进行实验研究,探讨其在人工智能中的应用。
一、八数码问题的定义八数码问题是指在一个3x3的棋盘上,摆放有1至8这8个数字,其中一个格子为空。
玩家需要通过移动数字,使得棋盘上的数字按照从小到大的顺序排列,空格在最后。
八数码问题可以被抽象为一个搜索问题,即找到从初始状态到目标状态的最短路径。
二、实验方法为了解决八数码问题,我们采用了A*算法作为实验方法。
A*算法是一种启发式搜索算法,通过估计目标状态与当前状态之间的代价函数,选择最优的路径进行搜索。
在本次实验中,我们将使用曼哈顿距离作为代价函数进行搜索。
三、实验结果我们使用Python编程语言实现了八数码问题的求解算法,并进行了多组实验。
实验结果表明,A*算法在解决八数码问题上表现出了较好的效果。
在大部分情况下,A*算法能够在较短的时间内找到最优解。
四、实验讨论尽管A*算法在解决八数码问题上表现出了较好的效果,但我们也发现了一些问题。
首先,A*算法在面对复杂的八数码问题时,搜索时间会显著增加。
其次,A*算法在面对某些特定情况时,可能会陷入局部最优解,无法找到全局最优解。
这些问题需要进一步的研究和改进。
五、应用前景八数码问题作为人工智能领域的经典问题,有着广泛的应用前景。
首先,八数码问题可以被应用于游戏设计中,作为一种智能对手的算法。
其次,八数码问题的解决方法可以被应用于路径规划、图像识别等领域,提高算法的效率和准确性。
六、结论通过本次实验,我们对八数码问题进行了深入的研究和探讨。
A*算法作为一种启发式搜索算法,在解决八数码问题上表现出了较好的效果。
然而,八数码问题仍然存在一些挑战和问题,需要进一步的研究和改进。
人工智能-八数码游戏问题

if(The_graph->form[i][j]!=End_graph->form[i][j])
{
valute++;
}
}
}
The_graph->evalue=valute;
return valute;
}
/////////移动数码组
Graph *Move(Graph *The_graph,int Direct,int CreatNew_graph)
e、判断压入队的子节点数码组(优越点)的评估值,为零则表示搜索完成,退出搜索;
f、跳到步骤2;
四、数据结构的设计
数码结构体
typedef struct node//八数码结构体
{
int form[N][N];//数码组
int evalue;//评估值,差距
int udirec;//所屏蔽方向,防止往回推到上一状态,1上2下3左4右
struct node *parent;//父节点
}Graph;
Graph *Qu[MAX]; //队列
Graph *St[MAX]; //堆栈
/////////打印数码组
void Print(;
if(The_graph==NULL)
printf("图为空\n");
#define N 3 //数码组大小
#define Max_Step 50 //最大搜索深度
#define MAX 50
typedef struct node//八数码结构体
{
int form[N][N];//数码组
int evalue;//评估值
int udirect;//所屏蔽方向,防止往回推到上已状态,1上2下3左4右
人工智能:八数码难题的启发式搜索

人工智能基础大作业----八数码难题学院:数学与计算机科学学院2016.12.20一、实验名称八数码难题的启发式搜索二、实验目的八数码问题:在3×3的方格棋盘上,摆放着1到8这八个数码,有1个方格是空的,其初始状态如图1所示,要求对空格执行空格左移、空格右移、空格上移和空格下移这四个操作使得棋盘从初始状态到目标状态。
要求:1.熟悉人工智能系统中的问题求解过程;2.熟悉状态空间的启发式搜索算法的应用;3.熟悉对八数码问题的建模、求解及编程语言的应用。
三、实验设备及软件环境1.实验编程工具:VC++ 6.02.实验环境:Windows7 64位四、实验方法:启发式搜索1.算法描述1.将S放入open表,计算估价函数f(s)2.判断open表是否为空,若为空则搜索失败,否则,将open表中的第一个元素加入close表并对其进行扩展(每次扩展后加入open表中的元素按照代价的大小从小到大排序,找到代价最小的节点进行扩展)注:代价的计算公式f(n)=d(n)+w(n).其中f(n)为总代价,d(n)为节点的度,w(n)用来计算节点中错放棋子的个数。
判断i是否为目标节点,是则成功,否则拓展i,计算后续节点f(j),利用f(j)对open表重新排序2.算法流程图:3.程序源代码:# include<stdio.h># include<string.h># include<malloc.h># include<stdlib.h>typedef struct node {int i,cost,degree,exp,father;int a[3][3];struct node *bef,*late;struct node *son;}treenode;int flag=0,count=1,num=0,i=0;void set(treenode *s);void cpynode(treenode *s1,treenode *s2);void add1(treenode *s,treenode *open);void adjust1(treenode *close);void jscost(treenode *s);void tiaozheng(treenode *open);void sortopen(treenode *open);int test(treenode *s1,treenode *s2);void position(treenode *s,treenode *open,treenode*close,treenode *s1);void printstr(treenode *open);int search(treenode *s1,treenode *s2);void input(treenode *s);int cmpnode(treenode *s1,treenode *s2);void print(treenode *s);void add(treenode *s,treenode *close);void xuhao(treenode *s);void extend(treenode *r1,treenode *s,treenode *s1,treenode *open,treenode *close);void main() {treenode *s0,*s1,*s;treenode *open,*close,*opend,*closed;open=(treenode*)malloc(sizeof(treenode));close=(treenode*)malloc(sizeof(treenode));open->late=NULL;close->late=NULL;opend=open;closed=close;s0=(treenode*)malloc(sizeof(treenode));set (s0);s1=(treenode*)malloc(sizeof(treenode));set(s1);printf("请输入八数码的初始状态:(以空格为分隔)\n");input (s0);printf("请输入八数码的目标状态:(以空格为分隔)\n");input(s1);xuhao(s0);add (s0,opend);while(open->late!=NULL && flag==0) {s=(treenode*)malloc(sizeof(treenode));cpynode(s,open->late);open=open->late;add(s,close);if(test(s,s1)==0){flag=1; }else{position(s,open,close,s1);sortopen(open); };};if(open->late!=NULL) {printf("搜索过程如下:\n ");adjust1(close);printstr(close);printf("\n%d 步,%d 个节点\n",num,count);} else {printf("查找错误 ! \n");}; }void set(treenode *s) {s->i=i;s->father=0;s->degree=0;s->bef=NULL;s->son=NULL;s->late=NULL; };void input(treenode *s) {int j,k;for(j=0;j<3;j++)for(k=0;k<3;k++)scanf("%d",&s->a[j][k]); };int cmpnode(treenode *s1,treenode *s2){ int j,k;for(j=0;j<3;j++)for(k=0;k<3;k++) {if(s1->a[j][k]!=s2->a[j][k])return 0; };return 1; }int test(treenode *s1,treenode *s2) { int j,k,n=0;for(j=0;j<3;j++)for(k=0;k<3;k++) {if(s1->a[j][k]!=s2->a[j][k])n++; };s1->exp=n;return n; };void xuhao(treenode *s) {i++;s->i=i; }void cpynode(treenode *s1,treenode *s2) { int j,k;for(j=0;j<3;j++)for(k=0;k<3;k++)s1->a[j][k]=s2->a[j][k];s1->bef=s2->bef;s1->cost=s2->cost;s1->exp=s2->exp;s1->degree=s2->degree;s1->i=s2->i;s1->father=s2->father; };void print(treenode *s) {int j,k;for(j=0;j<3;j++) {for(k=0;k<3;k++) {printf("%2d",s->a[j][k]); }if(j==1) printf(" n=%2d d=%2df=%2d",s->i,s->degree,s->father);printf("\n"); }printf("\n"); }void position(treenode *s,treenode *open,treenode *close,treenode *s1) {int m,n,t,k;treenode *r1;for(m=0;m<3;m++) {for(n=0;n<3;n++) {k=s->a[m][n];if(k==0)break; };if(k==0) break; }if(m+1<=2&&flag==0) {r1=(treenode*)malloc(sizeof(treenode));cpynode(r1,s);t=r1->a[m+1][n];r1->a[m+1][n] = r1->a[m][n];r1->a[m][n]=t;extend(r1,s,s1,open,close); };if(m-1>=0&&flag==0) {r1=(treenode*)malloc(sizeof(treenode));cpynode(r1,s);t=r1->a[m-1][n];r1->a[m-1][n]=r1->a[m][n];r1->a[m][n]=t;extend(r1,s,s1,open,close); };if(n-1>=0 && flag==0) {r1=(treenode*)malloc(sizeof(treenode));cpynode(r1,s);t=r1->a[m][n-1];r1->a[m][n-1]=r1->a[m][n];r1->a[m][n]=t;extend(r1,s,s1,open,close); };if(n+1<=2 && flag==0) {r1=(treenode*)malloc(sizeof(treenode));cpynode(r1,s);t=r1->a[m][n+1];r1->a[m][n+1]=r1->a[m][n];r1->a[m][n]=t;extend(r1,s,s1,open,close); }; }void printstr(treenode *s) {treenode *t;t=s->late;while(t!=NULL) {num++;print(t);t=t->son; }; }void extend(treenode *r1,treenode *s,treenode *s1,treenode *open,treenode *close) {r1->father=s->i;r1->degree=s->degree+1;if(test(r1,s1)!=0) {jscost(r1);if(search(r1,close)==1 && search(r1,open)==1) { xuhao(r1);add1(r1,open);r1->bef=s;count++; }else free(r1); }else {xuhao(r1);jscost(r1);count++;add(r1,close);r1->bef=s;flag=1; } }int search(treenode *s1,treenode *close) { treenode *r,*t;r=s1;t=close->late;while(t!=NULL) {if(r->exp==t->exp) {if(cmpnode(r,t)==1)return 0; };t=t->late; };return 1; }void add(treenode *s,treenode *close) { treenode *r,*t;t=s;r=close;while(r->late!=NULL)r=r->late;r->late=t;t->late=NULL; }void add1(treenode *s,treenode *open){ treenode *t;t=open;s->late=t->late;t->late=s; }void adjust1(treenode *close) {treenode *s,*t;s=close;s->late->bef=NULL;while(s->late!=NULL)s=s->late;s->son=NULL;while(s->bef!=NULL) {t=s->bef;t->son=s;s=s->bef; }; }void jscost(treenode *s) {s->cost=(s->exp)+s->degree; }void sortopen(treenode *open) {treenode *t,*s,*r;int k;r=(treenode*)malloc(sizeof(treenode));t=open->late;while(t!=NULL && t->late!=NULL) {s=t->late;k=t->cost;while(s!=NULL) {if(k > s->cost) {k=s->cost;cpynode(r,t);cpynode(t,s);cpynode(s,r); }s=s->late; }t=t->late; }; }五、实验结果:1.程序截图2.搜索过程请输入八数码的初始状态:(以空格为分隔)2 8 31 0 47 6 5请输入八数码的目标状态:(以空格为分隔)1 2 38 0 47 6 5搜索过程如下:2 8 31 0 4 n= 1 d= 0 f= 07 6 52 0 31 8 4 n= 3 d= 1 f= 17 6 50 2 31 8 4 n= 8 d=2 f= 37 6 51 2 30 8 4 n=10 d= 3 f= 87 6 51 2 38 0 4 n=12 d= 4 f=107 6 55 步,12 个节点Press any key to continue六、实验分析:在进行搜索的过程中,同时记录了扩展新节点的个数。
八数码试验报告

《人工智能》课程实验报告利用人工智能技术解决八数码游戏问题1.八数码游戏问题简介八数码问题也称为九宫问题。
在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同。
棋盘上还有一个空格,与空格相邻的棋子可以移到空格中。
要求解决的问题是:给出一个初始状态和一个目标状态,找出一种从初始转变成目标状态的移动棋子步数最少的移动步骤。
所谓问题的一个状态就是棋子在棋盘上的一种摆法。
解八数码问题实际上就是找出从初始状态到达目标状态所经过的一系列中间过渡状态。
2.八数码游戏问题的状态空间法表示本程序采用二维数组的方式存储每一步的状态,空位用0表示,例如:初始状态为⎪⎪⎪⎭⎫ ⎝⎛567401382,目标状态为⎪⎪⎪⎭⎫ ⎝⎛567408321。
将所有的中间生成状态列成图表,可以清晰的看出搜索的顺序,直观地理解算法。
例:下图为宽度优先搜索算法对应具体搜索路径:3.八数码游戏问题的盲目搜索技术3.1.1.宽度优先搜索:以接近起始节点的程度依次扩展节点的搜索技术(即:离起始节点近的节点先被扩展),扩展节点的原则是先扩展出来的节点随后优先被扩展(生成其所有的后继节点)。
3.1.2. 算法描述:①把起始节点放到OPEN 表中(如果该起始节点为一目标节点,则得到解)。
②如果OPEN 是个空表,则无解,失败退出;否则继续下一步。
③把第一个节点(记作节点n )从OPEN 表移出,并把它放入CLOSED 的已扩展节点表中。
④扩展节点n ,如果没有后继节点,则转向第②步。
⑤把n 的所有后继节点放到OPEN表的末端,并提供从这些后继节点回到n 的指针。
⑥如果n 的任一个后继节点是个目标节点,则找到一个解(反向追踪得到从目标节点到起始节点的路径),成功退出,否则转向第②步。
3.1.3. 算法流程图:3.2.1.深度优先搜索:深度优先搜索过程是沿着一条路径进行下去,直到深度界限为止,然后再考虑只有最后一步有差别的相同深度或较浅深度可供选择的路径,接着再考虑最后两步有差别的那些路径。
八数码问题,实验报告

八数码问题,实验报告八数码实验报告利用人工智能技术解决八数码游戏问题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、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
昆明理工大学信息工程与自动化学院学生实验报告(2012 —2013 学年第 1 学期)课程名称:人工智能开课实验室:信自楼442 2012 年10月 24日一、上机目的及内容1.上机内容用确定性推理算法求解教材65-66页介绍的八数码难题。
2.上机目的(1)复习程序设计和数据结构课程的相关知识,实现课程间的平滑过渡;(2)掌握并实现在小规模状态空间中进行图搜索的方法;(3)理解并掌握图搜索的技术要点。
二、实验原理及基本技术路线图(方框原理图或程序流程图)(1)设计并实现程序,求解出正确的解答路径;(2)对所设计的算法采用大O符号进行时间复杂性和空间复杂性分析;(3)对一般图搜索的技术要点和技术难点进行评述性分析。
问题描述:在3×3组成的九宫格棋盘上,摆有八个将牌,每一个将牌都刻有1-8八个数码中的某一个数码。
棋盘中留有一个空格,允许其周围的某一个将牌向空格移动,这样通过移动将牌就可以不断改变将牌的布局。
这种游戏求解的问题是:给定一种初始的将牌布局或结构(称初始状态)和一个目标的布局(称目标状态),问如何移动将牌,实现从初始状态到目标状态的转变。
初始状态:8个数字将牌和空格在九宫格棋盘上的所有格局组成了问题的状态空间。
其中,状态空间中的任一种状态都可以作为初始状态。
后继函数:通过移动空格(上、下、左、右)和周围的任一棋子一次,到达新的合法状态。
目标测试:比较当前状态和目标状态的格局是否一致。
路径消耗:每一步的耗散值为1,因此整个路径的耗散值是从起始状态到目标状态的棋子移动的总步数。
三、所用仪器、材料(设备名称、型号、规格等或使用软件)1台PC及VISUAL C++6.0软件四、实验方法、步骤(或:程序代码或操作过程)数据结构static int target[9]={1,2,3,8,0,4,7,6,5}; 全局静态变量,表示目标状态class eight_num{private:int num[9]; 定义八数码的初始状态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_num[9]);eight_num(int num1,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_num[9]){}设置当前节点状态(欲设置的状态记录的other数组中)void eight_num::set_num(int other_num[9]){}eight_num& eight_num::operator=(eight_num& another_8num){}eight_num& eight_num::operator=(int other_num[9]){}int eight_num::operator==(eight_num& another_8num){}int eight_num::operator==(int other_num[9]){}空格向上移int move_up(int num[9]){}空格向下移int move_down(int num[9]){}空格向左移int move_left(int num[9]){}空格向右移int move_right(int num[9]){}判断可否解出int icansolve(int num[9],int target[9]){}判断有无重复int existed(int num[9],eight_num *where){}寻找估价函数最小的叶子节点eight_num* find_OK_leaf(eight_num* start){}}源代码#include "stdafx.h"#include "iostream.h"#include <time.h>#include <stdio.h>#include <dos.h>#include <conio.h>static int target[9]={1,2,3,8,0,4,7,6,5};//class definitionclass eight_num{private:int num[9];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_num[9]);eight_num(int num1,int num2,int num3,int num4,int num5,int num6,int num7,int num8,int num9){num[0]=num1;num[1]=num2;num[2]=num3;num[3]=num4;num[4]=num5;num[5]=num6;num[6]=num7;num[7]=num8;num[8]=num9;}eight_num(void){for (int i=0;i<9;i++)num[i]=i;}void cul_para(void);void get_numbers_to(int other_num[9]);int get_nipn(void){return not_in_position_num;}int get_deapth(void){return deapth;}int get_evafun(void){return eva_function;}void set_num(int other_num[9]);void show(void);eight_num& operator=(eight_num&);eight_num& operator=(int other_num[9]);int operator==(eight_num&);int operator==(int other_num[9]);};//计算启发函数g(n)的值void eight_num::cul_para(void){int i;int temp_nipn=0;for (i=0;i<9;i++)if (num[i]!=target[i])temp_nipn++;not_in_position_num=temp_nipn;if (this->parent==NULL)deapth=0;elsedeapth=this->parent->deapth+1;eva_function=not_in_position_num+deapth; }//构造函数1eight_num::eight_num(int init_num[9]){for (int i=0;i<9;i++)num[i]=init_num[i];}//显示当前节点的状态void eight_num::show(){cout<<num[0];cout<<" ";cout<<num[1];cout<<" ";cout<<num[2];cout<<"\n";cout<<num[3];cout<<" ";cout<<num[4];cout<<" ";cout<<num[5];cout<<"\n";cout<<num[6];cout<<" ";cout<<num[7];cout<<" ";cout<<num[8];cout<<"\n";}//复制当前节点状态到一个另数组中void eight_num::get_numbers_to(int other_num[9]){for (int i=0;i<9;i++)other_num[i]=num[i];}//设置当前节点状态(欲设置的状态记录的other数组中) void eight_num::set_num(int other_num[9]){for (int i=0;i<9;i++)num[i]=other_num[i];}eight_num& eight_num::operator=(eight_num& another_8num) {for (int i=0;i<9;i++)num[i]=another_8num.num[i];not_in_position_num=another_8num.not_in_position_num;deapth=another_8num.deapth+1;eva_function=not_in_position_num+deapth;return *this;}eight_num& eight_num::operator=(int other_num[9]){for (int i=0;i<9;i++)num[i]=other_num[i];return *this;}int eight_num::operator==(eight_num& another_8num){int match=1;for (int i=0;i<9;i++)if(num[i]!=another_8num.num[i]){match=0;break;}if (match==0)return 0;elsereturn 1;}int eight_num::operator==(int other_num[9]) {int match=1;for (int i=0;i<9;i++)if(num[i]!=other_num[i]){match=0;break;}if (match==0)return 0;elsereturn 1;}//class definition over//*************************//空格向上移int move_up(int num[9]){for (int i=0;i<9;i++)if (num[i]==0)break;if (i<3)return 0;else{num[i]=num[i-3];num[i-3]=0;return 1;}}//空格向下移int move_down(int num[9]){for (int i=0;i<9;i++)if (num[i]==0)break;if (i>5)return 0;else{num[i]=num[i+3];num[i+3]=0;return 1;}}//空格向左移int move_left(int num[9]) {for (int i=0;i<9;i++)if (num[i]==0)break;if (i==0||i==3||i==6)return 0;else{num[i]=num[i-1];num[i-1]=0;return 1;}}//空格向右移int move_right(int num[9]) {for (int i=0;i<9;i++)if (num[i]==0)break;if (i==2||i==5||i==8)return 0;else{num[i]=num[i+1];num[i+1]=0;return 1;}}//判断可否解出int icansolve(int num[9],int target[9]){int i,j;int count_num,count_target;for (i=0;i<9;i++)for (j=0;j<i;j++){if(num[j]<num[i]&&num[j]!=0)count_num++;if(target[j]<target[i]&&target[j]!=0)count_target++;}if((count_num+count_target)%2 == 0)return 1;elsereturn 0;}//判断有无重复int existed(int num[9],eight_num *where){eight_num *p;for(p=where;p!=NULL;p=p->parent)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(min>p->get_evafun()){OK=p;min=p->get_evafun();}return OK;}//主函数开始int main(void){double time;clock_t Start,Finish;int memery_used=0,step=0;int num[9];int flag=0;//是否输入错误标志,1表示输入错误int bingo=0;//是否查找成功标志,1表示成功int i,j;cout<<"Please input the number(0 for the blank):\n";for (i=0;i<9;i++){flag=0;cin>>num[i];for(j=0;j<i;j++)if(num[i]==num[j])flag=1;if (num[i]<0||num[i]>8||flag==1){i--;cout<<"Illegle number!\tReinput!\n";}}eight_num S(num),Target(target);S.parent=S.leaf_next=S.leaf_pre=NULL;S.cul_para();memery_used++;cout<<"Now the initial numbers are:\n";S.show();cout<<"And the Target is:\n";Target.show();if(!icansolve(num,target)){cout<<"No one can solve it!\n";cin>>i;return 1;}Start=clock( );eight_num *OK_leaf=&S,*leaf_start=&S,*new_8num,*p;while(OK_leaf!=NULL&&bingo!=1){OK_leaf=find_OK_leaf(leaf_start);if(*OK_leaf==Target){bingo=1;break;}p=OK_leaf->leaf_pre;OK_leaf->get_numbers_to(num);if(move_up(num)&&!existed(num,OK_leaf)) {new_8num=new eight_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)&&!existed(num,OK_leaf)) {new_8num=new eight_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_left(num)&&!existed(num,OK_leaf)) {new_8num=new eight_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_right(num)&&!existed(num,OK_leaf)){new_8num=new eight_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_leaf->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){cout<<" ^\n";p->show();step++;}cout<<"Time cost:";cout<<time;cout<<"ms\n";cout<<"Totaly covered steps:";cout<<step;cout<<"\n";}elsecout<<"Fail to find!";return 0;}五、实验过程原始记录( 测试数据、图表、计算等)目标状态默认为1 2 3 8 0 4 7 6 5 .a)初始状态是3 2 1 8 0 4 7 6 5,用h作为启发函数结果都如下:b)初始状态是1 04 2 7 3 8 5 6,用h作为启发函数结果都如下:b)初始状态是1 0 3 8 2 4 7 6 5,用h作为启发函数结果都如下:六、实验结果、分析和结论其实在这次试验中我有很多不懂的地方。