人工智能实验报告 八数码难题

合集下载

【精编范文】八数码实验报告-推荐word版 (17页)

【精编范文】八数码实验报告-推荐word版 (17页)

本文部分内容来自网络整理,本司不为其真实性负责,如有异议或侵权请及时联系,本司将立即删除!== 本文为word格式,下载后可方便编辑和修改! ==八数码实验报告篇一:八数码实验报告利用人工智能技术解决八数码游戏问题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表中(如果该起始节点为一目标节点,则求得一个解答)。

人工智能实验报告八数码难题

人工智能实验报告八数码难题

昆明理工大学信息工程与自动化学院学生实验报告(201 —201 学年第一学期)课程名称:开课实验室:年月日一、实验内容八数码难题,问题描述:在3×3方格棋盘上,分别放置了标有数字1,2,3,4,5,6,7,8的八张牌,初始状态S0,目标状态S1如图所示,可以使用的操作有:空格上移,空格左移,空格右移,空格下移。

只允许位于空格左,上,右,下方的牌移入空格。

用广度优先搜索策略寻找从初始状态到目标状态的解路径。

二、实验原理算法思想:这是一种盲目搜索算法。

算法主要思想是从初始结点开始依次沿其上下左右四个方向扩展结点,并逐一检查这些后继结点是否为目标结点,若不等于目标结点则把该后继结点插入到数组末尾。

然后取数组中未扩展的第一个结点重复以上操作,直到得到目标结点为止或在限定步数以内未得到解。

广度优先搜索策略数据结构:void Bfs(){queue<Map> Queue;Queue.push(org);HashTable[ org.myindex ] = -1;while( NOT Queue.empty() ){Map node = Queue.front();Queue.pop( );for(int k =0 ; k < 4; k ++ ){Map tmp = node;tmp.position = node.position + derection[k];if(tmp.position < 0 || tmp.position > 8 || ( k > 1 && tmp.position / 3 != node.position /3 ) ) continue;tmp.myindex = HashValue( node , k );if(0 != HashTable[tmp.myindex] ) continue;tmp.detail[ node.position ] = tmp.detail[ tmp.position ] ;tmp.detail[ tmp.position ] = 0 ;HashTable[tmp.myindex] = node.myindex; // 状态记录到hashtable中if( node.myindex == EndIndex ) return ;Queue.push( tmp );}}return ;}三、所用仪器、材料1台PC及VISUAL C++6.0软件四、实验方法、步骤源代码见同一文件夹中bashuma.cpp部分程序代码:typedef struct Node {int num[9];int deepth;int diffnum;int value;struct Node * pre;struct Node * next;struct Node * parent;}numNode;int main ( int argc, char *argv[] ){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;}void init ( ){while(1){printf("输入初始状态S0(请从左到右依次输入每行数字,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("请输入目标状态S1:\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;}}}int operate(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;}五、实验过程原始记录六、实验总结:人工智能这门课程综合了许多学科的知识,这些知识面十分广,以及它的应用也是十分广泛的,才刚开始学习的时候就会感觉有点复杂,因为它毕竟综合了一些我们还没有学过的知识。

人工智能8位数码难题的问题求解

人工智能8位数码难题的问题求解
#define UP 0
#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;}神经网络实验群神经网络实验一、实验目的:理解反向流传网络的构造和原理,掌握反向流传算法对神经元的训练过程,认识反向流传公式。

八数码问题

八数码问题
1*4!+1*5!
+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步到达

人工智能实验一_八数码问题

人工智能实验一_八数码问题

用A*算法解决八数码问题1 问题描述1.1 待解决问题的解释八数码游戏(八数码问题)描述为:在3×3组成的九宫格棋盘上,摆有八个将牌,每一个将牌都刻有1-8八个数码中的某一个数码。

棋盘中留有一个空格,允许其周围的某一个将牌向空格移动,这样通过移动将牌就可以不断改变将牌的布局。

这种游戏求解的问题是:给定一种初始的将牌布局或结构(称初始状态)和一个目标的布局(称目标状态),问如何移动将牌,实现从初始状态到目标状态的转变。

1.2 问题的搜索形式描述(4要素)初始状态:8个数字将牌和空格在九宫格棋盘上的所有格局组成了问题的状态空间。

其中,状态空间中的任一种状态都可以作为初始状态。

后继函数:通过移动空格(上、下、左、右)和周围的任一棋子一次,到达新的合法状态。

目标测试:比较当前状态和目标状态的格局是否一致。

路径消耗:每一步的耗散值为1,因此整个路径的耗散值是从起始状态到目标状态的棋子移动的总步数。

1.3 解决方案介绍(原理)对于八数码问题的解决,首先要考虑是否有答案。

每一个状态可认为是一个1×9的矩阵,问题即通过矩阵的变换,是否可以变换为目标状态对应的矩阵?由数学知识可知,可计算这两个有序数列的逆序值,如果两者都是偶数或奇数,则可通过变换到达,否则,这两个状态不可达。

这样,就可以在具体解决问题之前判断出问题是否可解,从而可以避免不必要的搜索。

如果初始状态可以到达目标状态,那么采取什么样的方法呢?常用的状态空间搜索有深度优先和广度优先。

广度优先是从初始状态一层一层向下找,直到找到目标为止。

深度优先是按照一定的顺序前查找完一个分支,再查找另一个分支,以至找到目标为止。

广度和深度优先搜索有一个很大的缺陷就是他们都是在一个给定的状态空间中穷举。

这在状态空间不大的情况下是很合适的算法,可是当状态空间十分大,且不预测的情况下就不可取了。

他的效率实在太低,甚至不可完成。

由于八数码问题状态空间共有9!个状态,对于八数码问题如果选定了初始状态和目标状态,有9!/2个状态要搜索,考虑到时间和空间的限制,在这里采用A*算法作为搜索策略。

人工智能实验六 A算法8数码问题

人工智能实验六 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问题

人工智能实验报告,包括八数码问题八皇后问题和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*搜索算法在解决八数码问题上表现更优秀,具有更高的效率和准确性。

这为我们在实际应用中选择合适的人工智能算法提供了重要的参考。

未来展望
随着人工智能技术的不断发展,我们相信在解决类似的组合优化问题上会出现更多更高效的算法。

我们将继续深入研究,探索更多的人工智能算法,并将其应用于更广泛的领域,为人类社会带来更多的便利和创新。

人工智能上机试验报告

人工智能上机试验报告

人工智能上机实验报告人工智能上机实验题目:自动求解八数码难题。

八数码难题:在3×3的方格棋盘上,分别放置了标有数字1,2,3,4,5,6,7,8的八张牌,初始状态S0,目标状态如下图所示,可以使用的操作有:空格左移,空格上移,空格右移,空格下移。

图1 八数码难题的目标状态请上机参考给定的类用C++实现八数码难题的自动求解,给出操作步骤。

参考代码的说明如下:1.CSearchEngine类:搜索引擎基类,你可以在它的基础上编写更好的搜索引擎2.CGSESearchEngine类:使用全局择优搜索算法的搜索引擎3.CEveluation类: 节点估价类, 对棋盘局面进行估值, 以引导搜索4.CMoveGenerator类:走法产生器,对某一局面产生合适的走法具体要求:1.对于指定的(程序内定的)初始问题状态,上机输入调试运行程序,给出自动求解步骤。

2.原估价函数为“不在位”的数码个数,请修改估价函数为“不在位的数码距离正确位置的距离”。

3.选做1:通过输出扩展节点,比较2中两种不同估价函数的效率。

选做2:编写随机生成初始状态的类,增强程序功能。

思考:是不是任意初始状态都能找到解?问题一:上图各节点中的数据,前三行为八个数字的布局,最后一行是评价结果,红色框和箭头指出最优路径。

搜索过程使用广度优先策略。

估价函数为:不在位的数码个数。

以下为运行结果步骤:2 8 31 6 47 0 52 8 31 0 47 6 5press enter to continue the next step:2 0 31 8 47 6 5press enter to continue the next step:0 2 31 8 47 6 5press enter to continue the next step:1 2 30 8 47 6 5press enter to continue the next step:1 2 38 0 47 6 5You've have the solution!问题二: //新的评价函数,不在位的数码距离正确位置的距离int CEvaluation::Evaluate(BYTE byBoard[][3]){BYTE destBoard[3][3] = { {1,2,3}, {8,0,4}, {7,6,5} };int iDist = 0;int i_1, j_1, i_2, j_2;BYTE num;for( num = 0; num <= 8; num ++ ){GetNumPos(byBoard, i_1, j_1, num);GetNumPos(destBoard, i_2, j_2, num);iDist += abs(i_1 - i_2) + abs(j_1 - j_2);}return iDist;}void CEvaluation::GetNumPos(BYTE byBoard[][3], int &i, int &j, BYTE num) {for( i = 0; i < 3; i ++ )for( j = 0; j < 3; j ++ )if( byBoard[i][j] == num )return;}问题三:上图各节点中的数据,前三行为八个数字的布局,最后一行是评价结果,红色框和箭头指出最优路径。

人工智能实验报告 八数码问题

人工智能实验报告 八数码问题

实验一 启发式搜索算法姓名:徐维坚 学号: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 ,生成其全部后继节点。

八数码问题实验报告

八数码问题实验报告

八数码问题实验报告引言八数码问题是一个著名的数学问题,也是一个经典的搜索算法应用场景。

该问题是在一个3x3的棋盘上,分布着1至8这8个数字,其中一个格子是空白的。

目标是通过交换棋盘上的数字,使得棋盘上的数字按照从小到大的顺序排列,空白格子位于最后。

本实验报告将介绍八数码问题的背景、具体实验步骤以及实验结果分析。

实验步骤1.定义状态空间和目标状态:将八数码问题抽象成一个状态空间图。

每个状态表示一个棋盘布局,目标状态是数字按照从小到大的顺序排列,空白格子位于最后。

2.实现状态的表示:使用一个3x3的二维数组来表示棋盘状态,空白格子用0表示。

3.实现状态转移函数:定义合法的移动操作,例如将一个数字移动到空白格子的位置。

根据当前状态和移动操作,得到下一个状态。

4.实现启发式函数:设计一个启发式函数来评估当前状态和目标状态之间的距离。

常用的启发式函数有曼哈顿距离和错位数。

5.实现搜索算法:选择合适的搜索算法,例如A算法或IDA算法。

根据当前状态和目标状态,通过搜索算法找到最优解。

6.实验结果分析:运行实验程序,记录搜索所需的时间和搜索路径长度。

分析不同启发式函数和搜索算法对实验结果的影响。

实验结果分析本次实验中,我们选择了A*算法作为搜索算法,曼哈顿距离作为启发式函数。

经过多次实验,我们发现实验结果受到初始状态的影响较大。

对于某些初始状态,搜索算法可以在较短的时间内找到最优解,而对于其他初始状态,搜索时间较长。

这是因为八数码问题的状态空间非常庞大,搜索算法需要遍历大量的状态才能找到最优解。

另外,我们还发现启发式函数的选择对搜索效率有一定的影响。

曼哈顿距离作为一种常用的启发式函数,可以提供较好的搜索效果。

而对于某些特定的初始状态,如果选择了错误的启发式函数,可能会导致搜索算法无法找到最优解。

在实验过程中,我们还发现A算法在某些情况下会陷入局部最优解,而无法找到全局最优解。

这是因为A算法的搜索过程是基于启发式函数的估计值,存在一定的不确定性。

人工智能实验报告 八数码

人工智能实验报告 八数码

人工智能实验报告八数码人工智能实验报告八数码引言:人工智能(Artificial Intelligence,简称AI)作为一门前沿的学科,已经在各个领域展现出了巨大的应用潜力。

其中,八数码问题作为一个经典的算法问题,被广泛应用于人工智能领域。

本文将对八数码问题进行实验研究,探讨其在人工智能中的应用。

一、八数码问题的定义八数码问题是指在一个3x3的棋盘上,摆放有1至8这8个数字,其中一个格子为空。

玩家需要通过移动数字,使得棋盘上的数字按照从小到大的顺序排列,空格在最后。

八数码问题可以被抽象为一个搜索问题,即找到从初始状态到目标状态的最短路径。

二、实验方法为了解决八数码问题,我们采用了A*算法作为实验方法。

A*算法是一种启发式搜索算法,通过估计目标状态与当前状态之间的代价函数,选择最优的路径进行搜索。

在本次实验中,我们将使用曼哈顿距离作为代价函数进行搜索。

三、实验结果我们使用Python编程语言实现了八数码问题的求解算法,并进行了多组实验。

实验结果表明,A*算法在解决八数码问题上表现出了较好的效果。

在大部分情况下,A*算法能够在较短的时间内找到最优解。

四、实验讨论尽管A*算法在解决八数码问题上表现出了较好的效果,但我们也发现了一些问题。

首先,A*算法在面对复杂的八数码问题时,搜索时间会显著增加。

其次,A*算法在面对某些特定情况时,可能会陷入局部最优解,无法找到全局最优解。

这些问题需要进一步的研究和改进。

五、应用前景八数码问题作为人工智能领域的经典问题,有着广泛的应用前景。

首先,八数码问题可以被应用于游戏设计中,作为一种智能对手的算法。

其次,八数码问题的解决方法可以被应用于路径规划、图像识别等领域,提高算法的效率和准确性。

六、结论通过本次实验,我们对八数码问题进行了深入的研究和探讨。

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. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

昆明理工大学信息工程与自动化学院学生实验报告(2012 —2013 学年第 1 学期)课程名称:人工智能开课实验室:信自楼442 2012 年10月 24日一、上机目的及内容1.上机内容用确定性推理算法求解教材65-66页介绍的八数码难题。

2.上机目的(1)复习程序设计和数据结构课程的相关知识,实现课程间的平滑过渡;(2)掌握并实现在小规模状态空间中进行图搜索的方法;(3)理解并掌握图搜索的技术要点。

二、实验原理及基本技术路线图(方框原理图或程序流程图)(1)设计并实现程序,求解出正确的解答路径;(2)对所设计的算法采用大O符号进行时间复杂性和空间复杂性分析;(3)对一般图搜索的技术要点和技术难点进行评述性分析。

三、所用仪器、材料(设备名称、型号、规格等或使用软件)1台PC及VISUAL C++6.0软件四、实验方法、步骤(或:程序代码或操作过程)流程图:源代码:Source files:主函数main:#include <iostream>#include "Node.h"#include "Queue.h"#include "Search.h"#include "Tree.h"void CreateNode1(std::vector<int>& s){s.push_back(2);s.push_back(8);s.push_back(3);s.push_back(1);s.push_back(0);s.push_back(4);s.push_back(7);s.push_back(6);s.push_back(5);}void CreateNode4(std::vector<int>& d) {d.push_back(2);d.push_back(8);d.push_back(3);d.push_back(1);d.push_back(6);d.push_back(4);d.push_back(7);d.push_back(0);d.push_back(5);}void CreateNode8(std::vector<int>& d) {d.push_back(0);d.push_back(2);d.push_back(3);d.push_back(1);d.push_back(8);d.push_back(4);d.push_back(7);d.push_back(6);d.push_back(5);}void CreateNode20(std::vector<int>& d) {d.push_back(2);d.push_back(0);d.push_back(8);d.push_back(1);d.push_back(4);d.push_back(3);d.push_back(7);d.push_back(6);d.push_back(5);}void CreateNode27(std::vector<int>& d) {d.push_back(1);d.push_back(2);d.push_back(3);d.push_back(8);d.push_back(0);d.push_back(4);d.push_back(7);d.push_back(6);d.push_back(5);}void CreateNode_test1(std::vector<int>& d) {d.push_back(7);d.push_back(6);d.push_back(5);d.push_back(4);d.push_back(0);d.push_back(1);d.push_back(3);d.push_back(8);d.push_back(2);}void test_expand(){std::vector<int> s;CreateNode1(s);std::vector<int> d;CreateNode4(d);Node source(s);Node dest(d);source.Display();Search search(&source);std::cout << source.Expand(dest, search); }void test_search(){std::vector<int> s;CreateNode1(s);std::vector<int> d;CreateNode4(d);Node source(s);Node dest(d);source.Display();dest.Display();Search search(&source);search.Find( & dest);search.DisplayRoute();}void test_search2level(){std::vector<int> s;CreateNode1(s);std::vector<int> d;CreateNode8(d);Node source(s);Node dest(d);source.Display();dest.Display();Search search(&source);search.Find( & dest);search.DisplayRoute();}void test_search_lab1(){std::vector<int> s;CreateNode1(s);std::vector<int> d;CreateNode27(d);Node source(s);Node dest(d);source.Display();dest.Display();Search search(&source);search.Find( & dest);search.DisplayRoute();}int main(int argc, char** argv) {// test_expand();// test_search();// test_search2level();// test_search_lab1();std::vector<int> s;CreateNode1(s);std::vector<int> d;CreateNode27(d);Node source(s);Node dest(d);source.Display();dest.Display();Search search(&source);search.Find( & dest);search.DisplayRoute();return 0;}Node函数:#include <iostream>#include <math.h>#include "Node.h"bool IsOpposite(OP opa, OP opb){if (LEFT==opa && RIGHT == opb)return true;if (RIGHT==opa && LEFT == opb)return true;if (UP==opa && DOWN == opb)return true;if (DOWN==opa && UP == opb)return true;return false;}Node::Node(std::vector<int> const& state) : m_state(state), m_pParent(NULL), m_children(), m_op(EMPTY){}void ShowOP(OP op){switch (op){case EMPTY:std::cout << "EMPTY";break;case UP:std::cout << "UP";break;case DOWN:std::cout << "DOWN";break;case LEFT:std::cout << "LEFT";break;case RIGHT:std::cout << "RIGHT";break;default:exit(-1);}}void ShowOPs(std::vector<OP> const& ops){for (int id=0; id<ops.size(); ++id){ShowOP(ops[id]);std::cout << " ";}std::cout << std::endl;}bool Node::Expand(Node const& destNode, Search& search){int spaceId = FindEmptySpaceId();std::cout << "space is at " << spaceId << std::endl;std::vector<OP> legalOPs = GenerateLegalOperators(spaceId);ShowOPs(legalOPs);while ( legalOPs.size() > 0 ){OP op = legalOPs[ legalOPs.size() - 1 ];legalOPs.pop_back();Node* pChild = CreateChild(op);if ( *pChild == destNode ){search.SetDestPt(pChild);return true;}search.GetQueue().EnQueue(pChild);}return false;}void Node::Display() const{for(int i=0; i<m_state.size(); ++i){std::cout << m_state[i] << " ";}std::cout << std::endl;std::cout << " pParent: " << m_pParent << std::endl;std::cout << " op: ";ShowOP(m_op);std::cout << std::endl;std::cout << " ";for(int j=0; j<m_children.size(); ++j){std::cout << m_children[j] << " ";}std::cout << std::endl;}void Node::DisplayRoute() const{std::vector<OP> routeOps;Node const* pNode = this;while ( NULL != pNode ){routeOps.push_back(pNode->m_op);pNode = pNode->m_pParent;}for(int id=routeOps.size()-2; id>=0 ; --id){ShowOP( routeOps[id] );std::cout << " ";}std::cout << std::endl;}bool Node::operator==(Node const& v) const{for (int id=0; id<m_state.size(); ++ id){if ( m_state[id] != v.m_state[id] )return false;}return true;}Node* Node::CreateChild(OP op){std::vector<int> childState = m_state;int exchangePos1 = FindEmptySpaceId();int exchangePos2 = CalIdBasedOP(op, exchangePos1);int temp = childState[exchangePos1];childState[exchangePos1] = childState[exchangePos2];childState[exchangePos2] = temp;Node* child = new Node(childState);child->m_pParent = this;child->m_op = op;m_children.push_back(child);return child;}int Node::FindEmptySpaceId() const{for (int id=0; id<m_state.size(); ++id){if ( 0 == m_state[id] ){return id;}}return -1;}std::vector<OP> Node::GenerateLegalOperators(int spaceId) const {std::vector<OP> allPossibleOps;allPossibleOps.push_back(UP);allPossibleOps.push_back(DOWN);allPossibleOps.push_back(LEFT);allPossibleOps.push_back(RIGHT);std::vector<OP> ops;for (int id=0; id<allPossibleOps.size(); ++id){OP op = allPossibleOps[id];if( IsOpposite(op, m_op) ){continue;}if ( IsWithinRange(op, spaceId) ){ops.push_back(op);}}return ops;}int Node::CalIdBasedOP(OP op, int spaceId) const {switch (op){case UP:spaceId -= int( sqrt( m_state.size() ) );break;case DOWN:spaceId += int( sqrt( m_state.size() ) );break;case LEFT:--spaceId;break;case RIGHT:++spaceId;break;default:return -1;}return spaceId;}bool Node::IsWithinRange(OP op, int spaceId) const {spaceId = CalIdBasedOP(op, spaceId);if (spaceId >= 0 && spaceId < m_state.size()) {return true;}return false;}Queue函数:#include "Queue.h"void Queue::EnQueue(Node* pNode){m_queue.push_back(pNode);}Node* Queue::DeQueue(){if ( m_queue.size() == 0 ){return NULL;}Node* pNode = m_queue[0];m_queue.pop_front();return pNode;}Search函数:#include "Search.h"#include "Node.h"Search::Search(Node* root): m_queue(), m_pDestNode( NULL ){m_queue.EnQueue(root);}Node* Search::Select(){return m_queue.DeQueue();}void Search::Find(Node* destNode){bool isFound = false;while ( !isFound ){Node* pNode = Select();pNode->Display();isFound = pNode->Expand(*destNode, *this);}}void Search::DisplayRoute() const{m_pDestNode->DisplayRoute();}Heard files:Node:#ifndef PROGECT_1_NODE#define PROGECT_1_NODE#include <vector>#include "Search.h"enum OP{EMPTY,UP,DOWN,LEFT,RIGHT};bool IsOpposite(OP opa, OP opb);class Node{public:Node(std::vector<int> const& state);bool Expand(Node const& destNode, Search& search);void Display() const;void DisplayRoute() const;bool operator==(Node const& v) const;private:Node* CreateChild(OP op);int FindEmptySpaceId() const;std::vector<OP> GenerateLegalOperators(int spaceId) const;int CalIdBasedOP(OP op, int spaceId) const;bool IsWithinRange(OP op, int spaceId) const;std::vector<int> m_state;Node *m_pParent;std::vector<Node*> m_children;OP m_op;};#endif // PROGECT_1_NODEQueue:#ifndef PROGECT_1_QUEUE#define PROGECT_1_QUEUE#include <deque>class Node;class Queue{public:void EnQueue(Node* pNode);Node* DeQueue();private:std::deque<Node*> m_queue;};#endif // PROGECT_1_QUEUESearch:#ifndef PROGECT_1_SEARCH#define PROGECT_1_SEARCHclass Node;class Search{public:Search(Node* root);Queue& GetQueue(){return m_queue;}void Find(Node* destNode);Node* Select();void SetDestPt(Node* pDestNode){m_pDestNode = pDestNode;}void DisplayRoute() const;private:Queue m_queue;Node* m_pDestNode;};#endif // PROGECT_1_SEARCHTree:#ifndef PROGECT_1_TREE#define PROGECT_1_TREE#endif // PROGECT_1_TREE五、实验过程原始记录( 测试数据、图表、计算等)六、实验结果、分析和结论(误差分析与数据处理、成果总结等。

相关文档
最新文档