人工智能导论实验一 基于图搜索技术的八数码问题求解

合集下载

【精编范文】八数码实验报告-推荐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表中(如果该起始节点为一目标节点,则求得一个解答)。

八数码难题的搜索求解演示-推荐下载

八数码难题的搜索求解演示-推荐下载
算法分析:
九宫问题的求解方法就是交换空格(0)位置,直至到达目标 位置为止。如图所示:
对全部高中资料试卷电气设备,在安装过程中以及安装结束后进行高中资料试卷调整试验;通电检查所有设备高中资料电试力卷保相护互装作置用调与试相技互术通关,1系电过,力管根保线据护敷生高设产中技工资术艺料0不高试仅中卷可资配以料置解试技决卷术吊要是顶求指层,机配对组置电在不气进规设行范备继高进电中行保资空护料载高试与中卷带资问负料题荷试2下卷2,高总而中体且资配可料置保试时障卷,各调需类控要管试在路验最习;大题对限到设度位备内。进来在行确管调保路整机敷使组设其高过在中程正资1常料中工试,况卷要下安加与全强过,看度并22工且22作尽22下可22都能22可地护以缩1关正小于常故管工障路作高高;中中对资资于料料继试试电卷卷保破连护坏接进范管行围口整,处核或理对者高定对中值某资,些料审异试核常卷与高弯校中扁对资度图料固纸试定,卷盒编工位写况置复进.杂行保设自护备动层与处防装理腐置,跨高尤接中其地资要线料避弯试免曲卷错半调误径试高标方中高案资等,料,编试要5写、卷求重电保技要气护术设设装交备备置底4高调、动。中试电作管资高气,线料中课并敷3试资件且、设卷料中拒管技试试调绝路术验卷试动敷中方技作设包案术,技含以来术线及避槽系免、统不管启必架动要等方高多案中项;资方对料式整试,套卷为启突解动然决过停高程机中中。语高因文中此电资,气料电课试力件卷高中电中管气资壁设料薄备试、进卷接行保口调护不试装严工置等作调问并试题且技,进术合行,理过要利关求用运电管行力线高保敷中护设资装技料置术试做。卷到线技准缆术确敷指灵设导活原。。则对对:于于在调差分试动线过保盒程护处中装,高置当中高不资中同料资电试料压卷试回技卷路术调交问试叉题技时,术,作是应为指采调发用试电金人机属员一隔,变板需压进要器行在组隔事在开前发处掌生理握内;图部同纸故一资障线料时槽、,内设需,备要强制进电造行回厂外路家部须出电同具源时高高切中中断资资习料料题试试电卷卷源试切,验除线报从缆告而敷与采设相用完关高毕技中,术资要资料进料试行,卷检并主查且要和了保检解护测现装处场置理设。备高中资料试卷布置情况与有关高中资料试卷电气系统接线等情况,然后根据规范与规程规定,制定设备调试高中资料试卷方案。

人工智能_八数码实验报告【范本模板】

人工智能_八数码实验报告【范本模板】

西安郵電大学人工智能实验报告书(三)学院:自动化学院专业:智能科学与技术班级:智能1403姓名:刘忠强时间:2016—3—29一、实验目的1. 熟悉人工智能系统中的问题求解过程;2。

熟悉状态空间的盲目搜索策略;3.掌握盲目收索算法,重点是宽度优先收索和深度优先收索.二、实验算法广度优先收索是一种先生成的节点先扩展的策略。

它的过程是:从初始节点开始逐层向下扩展,再第n层节点还没有完全搜索之前,不进如第n+1层节点.Open表中的节点总是按进入的先后排序,先进入的节点排在前面,够进入的排在后面。

三、程序框图四、实验结果及分析初始状态:目标状态:2 83 2 1 61 6 4 4 0 87 0 5 7 5 3五、源程序及注释#include <iostream〉#include <ctime>#include 〈vector〉using namespace std;const int ROW = 3;const int COL = 3;const int MAXDISTANCE = 10000;const int MAXNUM = 10000;int abs(int a){if (a>0) return a;else return —a;}typedef struct _Node{int digit[ROW][COL];int dist; // 距离int dep; // 深度int index; // 索引值} Node;Node src, dest;vector〈Node〉 node_v; // 储存节点bool isEmptyOfOPEN(){ //判断Open表是否空for (int i = 0; i 〈 node_v.size(); i++){if (node_v[i]。

dist != MAXNUM)return false;}return true;}bool isEqual(int index, int digit[][COL]) { //判断节点是否与索引值指向的节点相同for (int i = 0; i 〈 ROW; i++)for (int j = 0; j 〈 COL; j++){if (node_v[index].digit[i][j] != digit[i][j])return false;}return true;}ostream& operator<<(ostream& os, Node& node){for (int i = 0; i < ROW; i++) {for (int j = 0; j 〈 COL; j++)os <〈 node。

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

八数码实验报告人工智能课设报告

八数码实验报告人工智能课设报告

学生实验报告实验课名称:人工智能实验名称: 八数码专业名称:计算机科学与技术班级:学号:学生姓名:教师姓名:2010 年10 月20日一.实验内容用OPEN表和CLOSED表解决搜索问题。

二.实验题目采用启发式算法(如A*算法)求解八数码问题。

三.实验要求1.必须使用OPEN表和CLOSED表。

2.明确给出问题描述。

系统初始状态。

目标状态和启发式函数。

3.除了初始状态以外,至少搜索四层。

4.给出解路径(解图)。

四.实验过程①问题:初始状态到目标状态是否可解如何判断?答:实验过程自己给出的初始状态使用A*算法求解,并不是所有的初始状态都可解到达目标状态。

因为八数码问题其实是0~9的一个排列,而排列有奇排列和偶排列,从奇排列不能转化为偶排列或者相反。

例如:函数f(s)表示s前比s 小的数字的数目(s则当f(a8)+f(a7)+……+f(a1)为偶数时才能重排成,所以嘛,上面那个有解的.②问题描述:在3X3的九宫格棋盘上,摆有8个将牌,每一个将牌都刻有1~8数码中的某一个数码。

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

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

下面给出初始状态和目标状态:初始状态:目标状态:评价函数f(n)形式为:f(n)=g(n)+h(n),其中g(n)是节点所处的深度,h(n)是启发式函数,这里启发式函数h(n)表示“不在位”的将牌个数,这时f(n)可估计出通向目标结点的希望的程度。

注意:移动规则为左-→上→右→下。

③搜索过程:如下图-1为八数码问题的搜索树:因此可得解路径:S(4)→B(4)→D(5)→E(5)→I(5)→K(5)→L(5).④得到OPEN表和CLOSED表结论:由以上分析,可以从CLOSED表中可知从初始状态到结束状态的搜索路径为:S0→S2→S5→S9→S11→S12.五、实验体会通过本次实验又将课本内容熟悉了一遍,而且通过互联网了解了更多的关于八数码问题,如读过网上用VC++编写八数码问题的源代码,虽然理解不是很深,但基本思想也是有所体会;同时也对广度优先搜索算法,深度优先算法,双向广度优先算法及A*算法有更深的掌握。

a算法求解八数码问题 实验报告

a算法求解八数码问题 实验报告

题目: a算法求解八数码问题实验报告目录1. 实验目的2. 实验设计3. 实验过程4. 实验结果5. 实验分析6. 实验总结1. 实验目的本实验旨在通过实验验证a算法在求解八数码问题时的效果,并对其进行分析和总结。

2. 实验设计a算法是一种启发式搜索算法,主要用于在图形搜索和有向图中找到最短路径。

在本实验中,我们将使用a算法来解决八数码问题,即在3x3的九宫格中,给定一个初始状态和一个目标状态,通过移动数字的方式将初始状态转变为目标状态。

具体的实验设计如下:1) 实验工具:我们将使用编程语言来实现a算法,并结合九宫格的数据结构来解决八数码问题。

2) 实验流程:我们将设计一个初始状态和一个目标状态,然后通过a 算法来求解初始状态到目标状态的最短路径。

在求解的过程中,我们将记录下每一步的状态变化和移动路径。

3. 实验过程我们在编程语言中实现了a算法,并用于求解八数码问题。

具体的实验过程如下:1) 初始状态和目标状态的设计:我们设计了一个初始状态和一个目标状态,分别为:初始状态:1 2 34 5 67 8 0目标状态:1 2 38 0 42) a算法求解:我们通过a算法来求解初始状态到目标状态的最短路径,并记录下每一步的状态变化和移动路径。

3) 实验结果在实验中,我们成功求解出了初始状态到目标状态的最短路径,并记录下了每一步的状态变化和移动路径。

具体的实验结果如下:初始状态:1 2 34 5 67 8 0目标状态:1 2 38 0 47 6 5求解路径:1. 上移1 2 37 8 62. 左移1 2 3 4 0 5 7 8 63. 下移1 2 3 4 8 5 7 0 64. 右移1 2 3 4 8 5 0 7 65. 上移1 2 3 0 8 5 4 7 61 2 38 0 54 7 67. 下移1 2 38 7 54 0 68. 右移1 2 38 7 54 6 0共计8步,成功从初始状态到目标状态的最短路径。

人工智能概论-搜索算法编程及实验报告

人工智能概论-搜索算法编程及实验报告

人工智能概论大作业学院:电子工程学院专业:智能科学与技术题目一:搜索算法编程及实验报告一.算法题目八数码难题的求解。

二.实验目的从盲目搜索和启发式搜索方法中分别选择一种解决八数码难题,给出搜索树和从起始节点到目标节点的路径。

三.实验设备及软件环境Win7的笔记本电脑,VS2013(使用c语言编程)。

四.实验方法1.盲目搜索——宽度优先搜索。

(1).算法描述如果搜索是以接近其实节点的程度来依次扩展节点,那么这中搜索就叫宽度优先搜索。

这种搜索是逐层进行的,在对下一层的任一节点进行搜索之前,必须搜索完本层的所有节点。

(1)把起始节点放到OPEN表中(如果该起始节点为一目标节点,则求得一个解答)。

(2)如果OPEN是个空表,则没有解,失败退出;否则继续。

(3)把第一个节点(节点 n)从OPEN表移出,并把它放入CLOSED扩展节点表中。

(4)扩展节点n。

如果没有后继节点,则转向上述第(2)步。

(5)把n 的所有后继节点放到OPEN表的末端,并提供从这些后继节点回到n的指针。

(6)如果n 的任一个后继节点是个目标节点,则找到一个解答,成功退出;否则转向第(2)步。

(2).算法流程图(3).程序代码#include "stdio.h"#include "conio.h"#include "string.h" struct pic{char data[10];char imoperate;int father;char extend; };char end[10] = "1238 4765";int result[100];int n;int m;pic base[100];char *w;int find(int x){for (int i = 0; i < 10; i++)if (base[x].data[i] != end[i])return 0;return 1;}void showline(int x){int i = 0;while (base[x].father != -1){result[i] = x;x = base[x].father;i++;}result[i] = 0;result[i + 1] = '\0';m = i;printf("\n搜索路径");for (i = m; i >= 0; i--){printf("\n\n\n");printf("%c\t%c\t%c\n", base[result[i]].data[0], base[result[i]].data[1], base[result[i]].data[2]);printf("%c\t%c\t%c\n", base[result[i]].data[3], base[result[i]].data[4], base[result[i]].data[5]);printf("%c\t%c\t%c", base[result[i]].data[6], base[result[i]].data[7], base[result[i]].data[8]);}}int left(int x){int i;for (i = 0; i < 10; i++)if (base[x].data[i] == ' ')break;if (i == 0 || i == 3 || i == 6)return 0;for (int j = 0; j < 10; j++)base[n].data[j] = base[x].data[j];base[n].data[i] = base[x].data[i - 1];base[n].father = x;base[n].imoperate = 'R';base[n].extend = 'Y';base[x].extend = 'N';w = base[n].data;n++;if (find(n - 1) == 1)return 1;}int right(int x){int i;for (i = 0; i < 10; i++)if (base[x].data[i] == ' ')break;if (i == 2 || i == 5 || i == 8)return 0;for (int j = 0; j < 10; j++)base[n].data[j] = base[x].data[j];base[n].data[i + 1] = base[x].data[i];base[n].father = x;base[n].imoperate = 'L';base[n].extend = 'Y';base[x].extend = 'N';w = base[n].data;n++;if (find(n - 1) == 1)return 1;}int up(int x){int i;for (i = 0; i < 10; i++)if (base[x].data[i] == ' ')break;if (i == 0 || i == 1 || i == 2)return 0;for (int j = 0; j < 10; j++)base[n].data[j] = base[x].data[j];base[n].data[i - 3] = base[x].data[i];base[n].data[i] = base[x].data[i - 3];base[n].father = x;base[n].imoperate = 'D';base[n].extend = 'Y';base[x].extend = 'N';w = base[n].data;n++;if (find(n - 1) == 1)return 1;}int down(int x){int i;for (i = 0; i < 10; i++)if (base[x].data[i] ==' ')break;if (i == 6 || i == 7 || i == 8)return 0;for (int j = 0; j < 10; j++)base[n].data[j] = base[x].data[j];base[n].data[i + 3] = base[x].data[i];base[n].data[i] = base[x].data[i + 3];base[n].father = x;base[n].imoperate = 'U';base[n].extend = 'Y';base[x].extend = 'N';w = base[n].data;n++;if (find(n - 1) == 1)return 1;}void main(){void showtree(int x);n = 1;int i;strcpy_s(base[0].data, "2831 4765");base[0].imoperate = 'N';base[0].father = -1;base[0].extend = 'Y';for ( i = 0; i < 100; i++){if (base[i].extend == 'Y'){if (base[i].imoperate == 'L'){if (right(i) == 1)break;if (up(i) == 1)break;if (down(i) == 1)break;continue;}if (base[i].imoperate == 'R') {if (left(i) == 1)break;if (up(i) == 1)break;if (down(i) == 1)break;continue;}if (base[i].imoperate == 'U') {if (left(i) == 1)break;if (right(i) == 1)break;if (down(i) == 1)break;continue;}if (base[i].imoperate == 'D') {if (right(i) == 1)break;if (up(i) == 1)break;if (left(i) == 1)break;continue;}if (base[i].imoperate == 'N') {if (left(i) == 1)break;if (right(i) == 1)break;if (up(i) == 1)break;if (down(i) == 1)break;continue;}}}printf("搜索结束\n");showline(n - 1);showtree(n - 1);getchar();}void showtree(int x){printf("\n\n\n搜索树\n\n\n");int i;for (i = 0; i <= x; i++){if (i == 0){printf("\t\t\t %c%c%c\n", base[i].data[0], base[i].data[1], base[i].data[2]);printf("\t\t\t %c%c%c\n", base[i].data[3], base[i].data[4], base[i].data[5]);base[i].data[7], base[i].data[8]);printf("\t\t\t |\n");printf(" ");for (int j = 0; j < 49; j++)printf("-");printf("\n");printf(" |");printf(" |");printf(" |");printf(" |\n");continue;}if (i>0 && i <= 4){printf(" %c%c%c", base[i].data[0],base[i].data[1], base[i].data[2]);printf("\t %c%c%c", base[i+1].data[0], base[i+1].data[1], base[i+1].data[2]);printf("\t %c%c%c", base[i+2].data[0], base[i+2].data[1], base[i+2].data[2]);printf("\t %c%c%c\n", base[i+3].data[0], base[i+3].data[1], base[i+3].data[2]);printf(" %c%c%c", base[i].data[3],base[i].data[4], base[i].data[5]);base[i+1].data[4], base[i+1].data[5]);printf("\t %c%c%c", base[i+2].data[3], base[i+2].data[4], base[i+2].data[5]);printf("\t %c%c%c\n", base[i+3].data[3], base[i+3].data[4], base[i+3].data[5]);printf(" %c%c%c", base[i].data[6],base[i].data[7], base[i].data[8]);printf("\t %c%c%c", base[i+1].data[6], base[i+1].data[7], base[i+1].data[8]);printf("\t %c%c%c", base[i+2].data[6], base[i+2].data[7], base[i+2].data[8]);printf("\t %c%c%c\n", base[i+3].data[6], base[i+3].data[7], base[i+3].data[8]);printf(" |");printf(" |");printf(" |");printf(" |\n");printf(" ---------");printf(" ---------");printf(" ---------");printf(" ---------\n");printf(" | |");printf(" | |");printf(" | |");printf(" | |\n");i = 4;continue;}if (i > 4 && i <= 12){printf(" %c%c%c", base[i].data[0], base[i].data[1], base[i].data[2]);for (int j = 1; j < 8; j++)printf(" %c%c%c", base[i+j].data[0],base[i+j].data[1], base[i+j].data[2]);printf("\n %c%c%c", base[i].data[3],base[i].data[4], base[i].data[5]);for (int j = 1; j < 8; j++)printf(" %c%c%c", base[i + j].data[3], base[i + j].data[4], base[i + j].data[5]);printf("\n %c%c%c", base[i].data[6],base[i].data[7], base[i].data[8]);for (int j = 1; j < 8; j++)printf(" %c%c%c", base[i + j].data[6], base[i + j].data[7], base[i + j].data[8]);printf("\n | |");printf(" | |");printf(" | |");printf(" | |\n");i = 12;continue;}if (i > 12 && i <= 20){printf(" %c%c%c", base[i].data[0], base[i].data[1], base[i].data[2]);for (int j = 1; j < 8; j++)printf(" %c%c%c", base[i + j].data[0], base[i + j].data[1], base[i + j].data[2]);printf("\n %c%c%c", base[i].data[3],base[i].data[4], base[i].data[5]);for (int j = 1; j < 8; j++)printf(" %c%c%c", base[i + j].data[3], base[i + j].data[4], base[i + j].data[5]);printf("\n %c%c%c", base[i].data[6],base[i].data[7], base[i].data[8]);for (int j = 1; j < 8; j++)printf(" %c%c%c", base[i + j].data[6], base[i + j].data[7], base[i + j].data[8]);printf("\n | |");printf(" | |");printf(" | |");printf(" | |\n");printf(" -----");for (int j = 0; j < 7;j++)printf(" -----");printf("\n | |");for (int j = 0; j < 7; j++)printf(" | |");i = 20;continue;}if (i>20 && i <= 36){printf("\n%c%c%c", base[i].data[0], base[i].data[1], base[i].data[2]);for (int j = 1; j < 11; j++)printf(" %c%c%c", base[i + j].data[0], base[i + j].data[1], base[i + j].data[2]);printf("\n%c%c%c", base[i].data[3], base[i].data[4], base[i].data[5]);for (int j = 1; j < 11; j++)printf(" %c%c%c", base[i + j].data[3], base[i + j].data[4], base[i + j].data[5]);printf("\n%c%c%c", base[i].data[6], base[i].data[7], base[i].data[8]);for (int j = 1; j < 11; j++)printf(" %c%c%c", base[i + j].data[6], base[i + j].data[7], base[i + j].data[8]);i = 36;continue;}}}2.启发式搜索——有序搜索(1)算法描述有序搜索又称最好优先搜索,他总是选择最有希望的节点作为下一个要扩展的节点。

人工智能实验报告-图搜索策略

人工智能实验报告-图搜索策略

人工智能第一次实验报告图搜索策略班级:姓名:学号:一、实验目的1. 加深对各种图搜索策略概念的理解;2. 进一步了解启发式搜索、α-β剪枝等概念;3. 比较并分析图搜索策略的实质,通过实验理解启发式搜索的意义。

二、实验要求以九宫问题/八数码问题为例,以某种搜索策略编程演示其搜索过程,最好能采用全局择优搜索,其中的启发式函数自己设计;三、实验算法1.有解和无解如何判定?答:计算两种状态的逆序值,若两者奇偶性相同则可达,不然两个状态不可达。

下面是判断的调用函数:int panduan(struct point x,struct point y)//判断是否有解{int i,j,no=0,a[9],b[9],temp1,temp2,num1=0,num2=0;for(i=0;i<3;i++)for(j=0;j<3;j++){a[no]=x.path[i][j];b[no]=y.path[i][j];no++;}for(i=0;i<9;i++){temp1=0;temp2=0;for(j=i+1;j<9;j++){if(a[j]<a[i]) temp1++;if(b[j]<a[i]) temp2++;}num1+=temp1;num2+=temp2;}if(num1%2==num1%2)return 1;else return 0;}2.启发式函数如何设定?答:比较当前状态和目标状态不同位的个数,数值越小的越接近,因此优先扩展,当为0是表示打到目标:int decide(struct point *x) //h函数&判断函数{int i,j;int no=0; //no是数字不同的个数for(i=0;i<3;i++)for(j=0;j<3;j++) //循环比较if(x->path[i][j]!=end.path[i][j])no++;return no;}3.open表和close表如何实现?答:以结构体存储open表和close表,struct point{int step;//step用于存储相异的元素int path[3][3];struct point *next;}start,end;struct point *open[362880];struct point *closed[362880];4.关键的函数有哪些?①.该函数实现空格的上移:struct point up(struct point *b,int x,int y){point newone=*b;char a;if(x>=0&&x<=2&&y>=0&&y<=2){a=newone.path[x][y];newone.path[x][y]=newone.path[x-1][y];newone.path[x-1][y]=a;}return newone;}②.该函数用于将open表中数据排序:void paixu(){int i,a=optail;struct point *x;for(i=optail;i<ophead;i++)if(open[optail]->step<open[i]->step)a=i;for(i=optail;i<a;i++){x=open[i+1];open[i+1]=open[i];open[i]=x;}}③.Main函数中部分代码,用于实现九宫格的移动:if(num!=0){for(i=0;i<3;i++) //找空格for(j=0;j<3;j++){if(closed[cl]->path[i][j]==0){x=i;y=j;}}point *up=(point *)malloc(sizeof(struct point));//向上 *up=*closed[cl];if(x>0){up->path[x][y]=up->path[x-1][y];up->path[x-1][y]=0;}if(testhash(up)){up->step=decide(up);up->next=closed[cl];open[optail]=up;paixu();optail--;}else free(up);point *down=(point *)malloc(sizeof(struct point));//向下 *down=*closed[cl];if(x<2){down->path[x][y]=down->path[x+1][y];down->path[x+1][y]=0;}if(testhash(down)){down->step=decide(down);down->next=closed[cl];open[optail]=down;paixu();optail--;}else free(down);point *left=(point *)malloc(sizeof(struct point));//向左 *left=*closed[cl];if(y>0){left->path[x][y]=left->path[x][y-1];left->path[x][y-1]=0;}if(testhash(left)){left->step=decide(left);left->next=closed[cl];open[optail]=left;paixu();optail--;}else free(left);point *right=(point *)malloc(sizeof(struct point));//向右 *right=*closed[cl];if(y<2){right->path[x][y]=right->path[x][y+1];right->path[x][y+1]=0;}if(testhash(right)){right->step=decide(right);right->next=closed[cl];open[optail]=right;paixu();optail--;}else free(right);}cl++;}四、实验结果1. 要求有实验运行结果截图,以及必要的说明;输入数据:运行结果:2. 对所采用的策略进行性能分析。

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

广州大学学生实验报告开课学院及实验室:计算机科学与工程实验室 2020年10月14日(***报告只能为文字和图片,老师评语将添加到此处,学生请勿作答***)一、实验内容1. 分别用广度优先搜索策略、深度优先搜索策略和启发式搜索算法(至少两种)求解八数码问题;分析估价函数对启发式搜索算法的影响;探究讨论各个搜索算法的特点。

二、实验设备1. 实验设备:计算机;2. 平台:Windows操作系统,Visual C++ 6.0 / Python Anaconda三、实验步骤1. 随机生成一个八数码问题分布,设计一个可解的目标状态(要求棋盘9个位置都不同)2. 分别用广度优先搜索策略、深度优先搜索策略和至少两种启发式搜索算法求解八数码问题3. 分析估价函数对启发式搜索算法的影响4. 探究讨论各个搜索算法的特点四、分析说明(包括核心代码及解释)广度优先搜索:首先创建一个结构体node,来记录节点移动方向和扩展的节点。

struct node{int ab[3][3];//节点int direction;//方向};struct node sh[102], end;int count = 1;然后创建一个init函数来初始化棋盘起始状态和目标状态,使用for语句填写棋盘数字用loction函数确定0节点的位置,通过for语句和if语句判断sh[num].ab[i / 3][i % 3] == 0,即可得到0节点的位置Sign函数用来获取棋盘状态,将当前棋盘数字顺序生成一个数,即可得知棋盘状态。

Mobile函数用来移动0节点,先用loction函数获取0节点的位置,再通过if语句来判断0节点位置和所能移动方向,然后进行移动。

Display函数使用for语句来打印当前棋盘。

Search函数使用display函数来打印从初始状态移动到目标状态的中间状态棋盘,在while(1)语句下利用mobile函数移动0节点,直到目标状态找到或者超过寻找次数。

#include<stdio.h>#include<iostream>struct node{int ab[3][3];//节点int direction;//方向};struct node sh[102], end;int count = 1;void init(){printf("输入起始棋盘的状态:\n");int i, j;for (i = 0; i < 3; i++)for (j = 0; j < 3; j++)scanf("%d", &sh[0].ab[i][j]);sh[0].direction = -1;printf("输入目标棋盘的状态:\n");for (i = 0; i < 3; i++)for (j = 0; j < 3; j++)scanf("%d", &sh[101].ab[i][j]);sh[101].direction = -1;printf("中间状态:\n");}//找出0的位置int loction(int num){int i;for (i = 0; i < 9; i++)if (sh[num].ab[i / 3][i % 3] == 0) return i;}//获取棋盘状态long long sign(int num){long long sum;sum = sh[num].ab[0][0] * 100000000 + sh[num].ab[0][1] * 10000000 + sh[num].ab[0][2] * 1000000 + sh[num].ab[1][0] * 100000 + sh[num].ab[1][1] * 10000 + sh[num].ab[1][2] * 1000 + sh[num].ab[2][0] * 100 + sh[num].ab[2][1] * 10 + sh[num].ab[2][2];return sum;}//移动0节点void mobile(int num){int temp;int loc;int up = 1, down = 1, left = 1, right = 1;loc = loction(num);int stand = sh[num].direction;//direction的0 1 2 3分别代表左上右下if (loc / 3 != 0 && stand != 1){sh[count] = sh[num];temp = sh[count].ab[loc / 3][loc % 3];sh[count].ab[loc / 3][loc % 3] = sh[count].ab[loc / 3 - 1][loc % 3];sh[count].ab[loc / 3 - 1][loc % 3] = temp;sh[count].direction = 3;count++;};if (loc / 3 != 2 && stand != 3){sh[count] = sh[num];temp = sh[count].ab[loc / 3][loc % 3];sh[count].ab[loc / 3][loc % 3] = sh[count].ab[loc / 3 + 1][loc % 3];sh[count].ab[loc / 3 + 1][loc % 3] = temp;sh[count].direction = 1;count++;}if (loc % 3 != 0 && stand != 0){sh[count] = sh[num];temp = sh[count].ab[loc / 3][loc % 3];sh[count].ab[loc / 3][loc % 3] = sh[count].ab[loc / 3][loc % 3 - 1];sh[count].ab[loc / 3][loc % 3 - 1] = temp;sh[count].direction = 2;count++;}if (loc % 3 != 2 && stand != 2){sh[count] = sh[num];temp = sh[count].ab[loc / 3][loc % 3];sh[count].ab[loc / 3][loc % 3] = sh[count].ab[loc / 3][loc % 3 + 1];sh[count].ab[loc / 3][loc % 3 + 1] = temp;sh[count].direction = 0;count++;}}//打印当前棋盘void display(int num){int i, j;for (i = 0; i < 3; i++){for (j = 0; j < 3; j++)printf("%d ", sh[num].ab[i][j]);printf("\n");}}//寻找目标状态int search(){int i = 0;while (1){printf("\n");display(i);printf("\n");if (i == 100){printf("超出了上限次数\n");return 0;}if (sign(i) == sign(101)){printf("在第%d次找到了\n", i);display(i);return i;}mobile(i);i++;}}int main(){init();search();system("pause");}宽度优先搜索:创建一个结构体Octal,其中的arr[4][4]用来存储八数码To_number函数将八数码棋盘中的数据转为数字存储。

Up函数用来移动0节点,同时判断0节点是否能向上移动Down函数用来判断0节点是否能向下移动Left函数用来判断0节点是否能向左移动Right函数用来判断0节点是否能向右移动主函数中用while(!open.empty())语句来循环搜索目标状态,用if语句判断当前状态若为目标状态则break 跳出循环,然后打印寻找目标状态过程的中间状态#include<iostream>#include<vector>using namespace std;struct Octal{int arr[4][4]; // 存储八数码int parent; // 父亲的值int current; // 当前的值int depth; // 当前深度};int to_number(int[4][4]);bool up(int[4][4]);bool down(int[4][4]);bool left(int[4][4]);bool right(int[4][4]);int main(){int arr[4][4] = { 0 }; // 存储当前八数码vector<Octal> open; // open表vector<Octal> closed; // closed表int depth; // 深度Octal octal; // 八数码cout <<"请输入起始棋盘状态:"<< endl;for (int i = 1; i <= 3; i++){for (int j = 1; j <= 3; j++){cin >> arr[i][j];octal.arr[i][j] = arr[i][j];}}cout <<"请输入深度:"<< endl;cin >> depth;cout <<"中间状态:"<< endl;octal.parent = 0;octal.current = to_number(arr);octal.depth = 0;open.push_back(octal);int goal = 123804765; // 最终的八数码值bool flag = false; // 成功解决为true,失败为falseOctal temp;int count = 1;while (!open.empty()){temp.current = open[open.size() - 1].current;temp.parent = open[open.size() - 1].parent;temp.depth = open[open.size() - 1].depth;for (int i = 1; i <= 3; i++)for (int j = 1; j <= 3; j++)temp.arr[i][j] = open[open.size() - 1].arr[i][j];open.pop_back();closed.push_back(temp);if (temp.current == goal){flag = true;break;}if (temp.depth >= depth){continue;}Octal produce[4]; // 四个可能生成的八数码数组for (int i = 0; i < 4; i++){produce[i].parent = temp.current;for (int j = 1; j <= 3; j++)for (int k = 1; k <= 3; k++)produce[i].arr[j][k] = temp.arr[j][k];produce[i].depth = temp.depth + 1;}bool flagProduce[4][2]; // 四个八数码对应的标志,0为open中是否含有,1位closed中是否含有for (int i = 0; i < 4; i++)for (int j = 0; j < 2; j++)flagProduce[i][j] = true;if (up(produce[0].arr)){produce[0].current = to_number(produce[0].arr);for (int i = 0; i < open.size(); i++)if (open[i].current == produce[0].current){flagProduce[0][0] = false;break;}if (flagProduce[0][0]){for (int i = 0; i < closed.size(); i++)if (closed[i].current == produce[0].current){flagProduce[0][1] = false;break;}if (flagProduce[0][1])open.push_back(produce[0]);}}if (down(produce[1].arr)){produce[1].current = to_number(produce[1].arr);for (int i = 0; i < open.size(); i++)if (open[i].current == produce[1].current){flagProduce[1][0] = false;break;}if (flagProduce[1][0]){for (int i = 0; i < closed.size(); i++)if (closed[i].current == produce[1].current){flagProduce[1][1] = false;break;}if (flagProduce[1][1])open.push_back(produce[1]);}}if (left(produce[2].arr)){produce[2].current = to_number(produce[2].arr);for (int i = 0; i < open.size(); i++)if (open[i].current == produce[2].current){flagProduce[2][0] = false;break;}if (flagProduce[2][0]){for (int i = 0; i < closed.size(); i++)if (closed[i].current == produce[2].current){flagProduce[2][1] = false;break;}if (flagProduce[2][1])open.push_back(produce[2]);}}if (right(produce[3].arr)){produce[3].current = to_number(produce[3].arr);for (int i = 0; i < open.size(); i++)if (open[i].current == produce[3].current){flagProduce[3][0] = false;break;}if (flagProduce[3][0]){for (int i = 0; i < closed.size(); i++)if (closed[i].current == produce[3].current){flagProduce[3][1] = false;break;}if (flagProduce[3][1])open.push_back(produce[3]);}}}if (flag){vector<Octal> answer;answer.push_back(temp);int parent = temp.parent;while (parent != 0){for (int j = 0; j < closed.size(); j++){if (closed[j].current == parent){temp.current = closed[j].current;temp.depth = closed[j].depth;temp.parent = closed[j].parent;for (int k = 1; k <= 3; k++){for (int m = 1; m <= 3; m++){temp.arr[k][m] = closed[j].arr[k][m];}}answer.push_back(temp);parent = closed[j].parent;break;}}}for (int i = answer.size() - 1; i >= 0; i--){if(i<=0){cout <<"第"<< answer.size() - i - 1 <<"次找到了"<< endl; }for (int j = 1; j <= 3; j++){for (int k = 1; k <= 3; k++){cout << answer[i].arr[j][k] <<" ";}cout << endl;}cout << endl;}}else{cout <<"在深度限制内的所有结果搜索完毕,没有答案!"<< endl;}system("pause");}int to_number(int arr[4][4]){// 将八数码矩阵中的数据转换为数字,方便存储和比较// 从左到右,从上至下,按照从1到9递增,1为亿位,……,9为个位int index = 100000000;long long result = 0;for (int i = 1; i <= 3; i++){for (int j = 1; j <= 3; j++){result += arr[i][j] * index;index /= 10;}}return result;}bool up(int arr[4][4]){// 空格向上int i, j; // 空格的位置为(i, j)bool flag = false;for (i = 1; i <= 3; i++){for (j = 1; j <= 3; j++)if (arr[i][j] == 0){flag = true;break;}if (flag)break;}if (i == 1)return false; // 此时无法向上else{arr[i][j] = arr[i - 1][j];arr[i - 1][j] = 0;}return true;}bool down(int arr[4][4]){// 空格向下int i, j; // 空格的位置为(i, j)bool flag = false;for (i = 1; i <= 3; i++){for (j = 1; j <= 3; j++)if (arr[i][j] == 0){flag = true;break;}if (flag)break;}if (i == 3)return false; // 此时无法向下else{arr[i][j] = arr[i + 1][j];arr[i + 1][j] = 0;}return true;}bool left(int arr[4][4]){// 空格向左int i, j; // 空格的位置为(i, j)bool flag = false;for (i = 1; i <= 3; i++){for (j = 1; j <= 3; j++)if (arr[i][j] == 0){flag = true;break;}if (flag)break;}if (j == 1)return false; // 此时无法向左else{arr[i][j] = arr[i][j - 1];arr[i][j - 1] = 0;}return true;}bool right(int arr[4][4]){// 空格向右int i, j; // 空格的位置为(i, j)bool flag = false;for (i = 1; i <= 3; i++){for (j = 1; j <= 3; j++)if (arr[i][j] == 0){flag = true;break;}if (flag)break;}if (j == 3)return false; // 此时无法向右else{arr[i][j] = arr[i][j + 1];arr[i][j + 1] = 0;}return true;}启发式搜索:首先创建一个结构体Node。

相关文档
最新文档