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

合集下载

A星算法求八数码问题实验报告

A星算法求八数码问题实验报告

A星算法求八数码问题实验报告人工智能实验报告实验名称:八数码问题姓名:xx学号:2012210xxxx计算机学院2014年1月14日一.实验目的掌握A*的思想,启发式搜索,来求解在代价最小的情况下将九宫格从一个状态转为另状态的路径。

二.实验内容给定九宫格的初始状态,要求在有限步的操作内,使其转化为目标状态,且所得到的解是代价最小解(2 8 31 6 47 0 52 8 31 6 47 0 5三、A*算法思想:1、思想:A*算法是一种静态路网中求解最短路最有效的直接搜索方法。

估价值与实际值越接近,估价函数取得就越好2、原理:估价函数公式表示为: f(n)=g(n)+h(n),其中 f(n) 是从初始点经由节点n到目标点的估价函数,g(n) 是在状态空间中从初始节点到n节点的实际代价,h(n) 是从n到目标节点最佳路径的估计代价。

保证找到最短路径(最优解的)条件,关键在于估价函数h(n)的选取:估价值h(n)<= n到目标节点的距离实际值,这种情况下,搜索的点数多,搜索范围大,效率低。

但能得到最优解。

并且如果h(n)=d(n),即距离估计h(n)等于最短距离,那么搜索将严格沿着最短路径进行此时的搜索效率是最高的。

如果估价值>实际值,搜索的点数少,搜索范围小,效率高,但不能保证得到最优解。

四、算法流程:Heuristic_Search(启发式搜索)While是从未拓展表中删N为目是,输出路径否,生成n的所有子状态Case:此子状Case:此子状Case:此子状计算该子状记录比已有记录比已有返回五、关键技术:1、使用了CreateChild()函数,求得了任意未拓展九宫格的扩展结点,便于拓展子空间,搜索所有情况。

关键代码:bool CreateChild(NOExtend ns[],NOExtend ne){int i,j,k=0;for(i=0;i<3;i++){for(j=0;j<3;j++){if(ne.cur_sudoku.num[i][j]==0){ //寻找九宫格空缺所在的坐标if(i-1>=0){ //将空格向上移动CopySudoku(ns[k].cur_sudoku,ne.cur_sudo ku);//先把未改变的九宫格复制给九宫格数组的某一元素ns[k].cur_sudoku.num[i][j]=ne.cur_sudoku.num[i-1][j];//然后仅改变此二维九宫格的两项值即可ns[k].cur_sudoku.num[i-1][j]=0;ns[k].dx=1;k++;}if(j+1<=2){ //将空格向右移动CopySudoku(ns[k].cur_sudoku,ne.cur_sudo ku);ns[k].cur_sudoku.num[i][j]=ns[k].cur_su doku.num[i][j+1];ns[k].cur_sudoku.num[i][j+1]=0;ns[k].dx=1;k++;}if(i+1<=2){ //将空格向下移动CopySudoku(ns[k].cur_sudoku,ne.cur_sudo ku);ns[k].cur_sudoku.num[i][j]=ns[k].cur_su doku.num[i+1][j];ns[k].cur_sudoku.num[i+1][j]=0;ns[k].dx=1;k++;}if(j-1>=0){ //将空格向左移动CopySudoku(ns[k].cur_sudoku,ne.cur_sudo ku);ns[k].cur_sudoku.num[i][j]=ns[k].cur_su doku.num[i][j-1];ns[k].cur_sudoku.num[i][j-1]=0;ns[k].dx=1;k++;}return 1;}}}return 0;2、用启发式搜索函数寻找求解路径,运用了A*算法的思想,能够更快的求解出最优解。

八数码问题求解实验报告

八数码问题求解实验报告

八数码问题求解(一)实验软件TC2.0或VC6.0编程语言或其它编程语言(二)实验目的1.熟悉人工智能系统中的问题求解过程;2.熟悉状态空间的盲目搜索和启发式搜索算法的应用;3.熟悉对八数码问题的建模,求解及编程语言的应用。

(三)实验内容八数码问题:在3×3的方格棋盘上,摆放着1到8这八个数码,有一个方格是空的,要求对空格执行空格左移,空格右移,空格上移,空格下移这四个操作使得棋盘从初始状态到目标状态。

输入初始状态和目标状态,输出从初始状态到目标状态的路径。

(四)实验代码#include"stdafx.h"#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;typedef struct_Node{int digit[ROW][COL];int dist; // distance between one state and the destination int dep; // the depth of node// So the comment function = dist + dep.int index; // point to the location of parent} Node;Node src, dest;vector<Node> node_v; // store the nodesbool isEmptyOfOPEN() {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.digit[i][j] << ' ';os << endl;}return os;}void PrintSteps(int index, vector<Node>& rstep_v) { rstep_v.push_back(node_v[index]);index = node_v[index].index;while (index != 0) {rstep_v.push_back(node_v[index]);index = node_v[index].index;}for (int i = rstep_v.size() - 1; i >= 0; i--)cout << "Step " << rstep_v.size() - i<< endl << rstep_v[i] << endl;}void Swap(int& a, int& b) {int t;t = a;a = b;b = t;}void Assign(Node& node, int index) {for (int i = 0; i < ROW; i++)for (int j = 0; j < COL; j++)node.digit[i][j] = node_v[index].digit[i][j];}int GetMinNode() {int dist = MAXNUM;int loc; // the location of minimize nodefor (int i = 0; i < node_v.size(); i++) {if (node_v[i].dist == MAXNUM)continue;else if ((node_v[i].dist + node_v[i].dep) < dist) {loc = i;dist = node_v[i].dist + node_v[i].dep;}}return loc;}bool isExpandable(Node& node) {for (int i = 0; i < node_v.size(); i++) {if (isEqual(i, node.digit))return false;}return true;}//扩展int Distance(Node& node, int digit[][COL]) {int distance = 0;bool flag = false;for (int i = 0; i < ROW; i++)for (int j = 0; j < COL; j++)for (int k = 0; k < ROW; k++) {for (int l = 0; l < COL; l++) {if (node.digit[i][j] == digit[k][l]) {distance += abs(i - k) + abs(j - l);//abs()求得是正数的绝对值。

人工智能实验总结

人工智能实验总结
对于同一个问题 由于搜索规模增大,宽度优先搜索和深度 优先搜索都未能得出解,宽度只显示有解, 但未能搜索出结果,深度达到了指定搜索 深度也未能找到目标,而且启发式搜索仍 然可以求出解来。
总结
宽度优先搜索法
在有解的情形总能保证搜索到最短路经,也 就是移动最少步数的路径。但宽度优先搜索法的 最大问题在于搜索的结点数量太多,因为在宽度 优先搜索法中,每一个可能扩展出的结点都是搜 索的对象。随着结点在搜索树上的深度增大,搜 索的结点数会很快增长,并以指数形式扩张,从 而所需的存储空间和搜索花费的时间也会成倍增 长。
1 2
0 1 0 1
0 0 1 1
0 1 1 0
神经网络设计
用两层神经网络来实现,其中隐层为随机 感知器层(net1),神经网络元数目设计为 3,其权值和阈值是随机的,它的输出作为 输出层(分类层)的输入;输出层为感知 器层(net2),其神经元数为1,这里仅对 该层进行训练。
程序运行结果
随机感知器层的权值向量 iw1 = 0.4267 -0.6556 -0.5439 0.9376 -0.1007 -0.2886 随机感知器层的阈值向量 b1 = 0.4074 0.0441 0.8658
运行结果分析
上面实验结果可以看出,城市数目为30的 时候,当迭代次数为100,算法收敛慢,在 迭代次数内最优解没有达到稳定,没有搜 索到最好的解。 迭代次数为200和250的时候,算法基本达 到收敛,最优解在100代以后趋于稳定,表 明搜索到问题的最优解。
运行结果
当城市数目改变的时候: CityNum=50;最大代数gnmax=100;
程序运行结果
第二层感知器层的权值向量和阈值向量 iw2 = -3 -2 2 b2 = 2

人工智能实验报告

人工智能实验报告

人工智能九宫格重移——搜索成员:赵春杰 2009210665羊森 2009210653黄鑫 2009210周成兵 2009210664王素娟 20092106441.问题描述:八数码问题也称为九宫问题。

在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同。

棋盘上还有一个空格,与空格相邻的棋子可以移到空格中。

要求解决的问题是:给出一个初始状态和一个目标状态,找出一种从初始转变成目标状态的移动棋子步数最少的移动步骤。

所谓问题的一个状态就是棋子在棋盘上的一种摆法。

棋子移动后,状态就会发生改变。

解八数码问题实际上就是找出从初始状态到达目标状态所经过的一系列中间过渡状态。

2.九宫重移有无答案检查(逆序数)我们把每个9宫格横向展开,如第一个123456789,我们把左边数大于右边数的组数称为这个九宫格的逆序数,显然123456789的逆序数为0;考虑横向平移,那么逆序数的增量为2或0或-2;纵向平移,逆序数的增量为4或0或-4;但147258369的逆序数为奇数。

所以147258369是无解的情况。

由此也可以类推当将9宫格展开后,如果数据序列的逆序数为奇数,则此数据序列对应的九宫格是无解的。

3.BFS算法队列: Queue open = new Queue();存放待扩展的节点List: List<Bfstr> closed = new List<Bfstr>();存放已被扩展过的节点ArrayList map = new ArrayList();//存放答案HashTale: Hashtable table = new Hashtable();构造哈希表以方便查找3.1.BFS算法介绍广度优先搜索算法BFS基本思想:从图中某顶点v出发,逐层对节点进行拓展,并考察是否为目标节点,在第n层节点没有全部扩展并考察前,不对第n+1层节点进行扩展。

八数码问题

八数码问题
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*算法作为搜索策略。

八数码 人工智能实验报告

八数码 人工智能实验报告

八数码人工智能实验报告八数码人工智能实验报告引言:八数码是一种经典的数学问题,也是人工智能领域中常用的实验题目之一。

本次实验旨在通过使用搜索算法解决八数码问题,探讨人工智能在解决复杂问题上的应用。

一、问题描述:八数码问题是一种数字排列游戏,使用一个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*搜索算法在解决八数码问题上表现更优秀,具有更高的效率和准确性。

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

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

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

八数码问题实验报告

八数码问题实验报告

八数码问题实验报告八数码问题实验报告引言:八数码问题,也被称为九宫格问题,是一种经典的数学谜题。

在一个3x3的方格中,摆放有1至8的数字,其中一个位置为空。

目标是通过交换数字的位置,将数字按照从小到大的顺序排列,最终使得空格位于最后一个位置。

本实验旨在通过编程实现八数码问题的求解,并探讨不同算法在解决该问题上的效果和优劣。

实验步骤:1. 算法选择在本次实验中,我们选择了广度优先搜索算法和A*算法作为求解八数码问题的两种不同方法。

广度优先搜索算法是一种盲目搜索算法,它通过逐层扩展搜索树,直到找到目标状态。

而A*算法则是一种启发式搜索算法,它结合了广度优先搜索和启发式函数,通过评估每个状态的代价来指导搜索过程,以找到最优解。

2. 算法实现我们使用Python语言实现了以上两种算法。

首先,我们定义了一个表示状态的类,并实现了状态的初始化、移动、判断是否达到目标状态等基本操作。

然后,我们分别编写了广度优先搜索算法和A*算法的求解函数。

在广度优先搜索算法中,我们使用队列数据结构来保存待扩展的状态,以实现逐层扩展的效果;在A*算法中,我们使用优先队列来保存待扩展的状态,并根据启发式函数的值进行优先级排序。

3. 实验结果我们使用了多个测试样例来验证两种算法的求解效果。

实验结果表明,广度优先搜索算法能够找到解,但是在面对状态空间较大的情况下,搜索时间会呈指数级增长。

而A*算法则能够更快地找到最优解,其效率相对较高。

然而,A*算法需要选择合适的启发式函数,并且对于某些特殊情况,可能会陷入局部最优解而无法找到最优解。

4. 结果分析通过对比两种算法的求解结果,我们可以发现广度优先搜索算法和A*算法在时间效率和解的质量上存在一定的差异。

广度优先搜索算法适用于状态空间较小的情况,但是在状态空间较大时效率较低;而A*算法则能够在较短的时间内找到最优解,但需要对问题进行合理的建模和启发式函数的选择。

因此,在实际应用中,我们需要根据问题的规模和特点来选择合适的算法。

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

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

实验一 启发式搜索算法姓名:徐维坚 学号:2220103484 日期:2012/6/29一、实验目的:熟练掌握启发式搜索A *算法及其可采纳性。

二、实验内容:使用启发式搜索算法求解8数码问题。

1) 编制程序实现求解8数码问题A *算法,采用估价函数()()()()w n f n d n p n ⎧⎪=+⎨⎪⎩, 其中:()d n 是搜索树中结点n 的深度;()w n 为结点n 的数据库中错放的棋子个数;()p n 为结点n 的数据库中每个棋子与其目标位置之间的距离总和。

2) 分析上述⑴中两种估价函数求解8数码问题的效率差别,给出一个是()p n 的上界 的()h n 的定义,并测试使用该估价函数是否使算法失去可采纳性。

三、实验原理:1. 问题描述:八数码问题也称为九宫问题。

在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同。

棋盘上还有一个空格(以数字0来表示),与空格相邻的棋子可以移到空格中。

要求解决的问题是:给出一个初始状态和一个目标状态,找出一种从初始转变成目标状态的移动棋子步数最少的移动步骤。

所谓问题的一个状态就是棋子在棋盘上的一种摆法。

解八数码问题实际上就是找出从初始状态到达目标状态所经过的一系列中间过渡状态。

2. 原理描述:2.1 有序搜索算法:(1)原理:在搜索过程中,OPEN 表中节点按照其估价函数值以递增顺序排列,选择OPEN 表中具有最小估价函数值的节点作为下一个待扩展的节点,这种搜索方法称为有序搜索。

在本例中,估价函数中的)(n g 取节点深度)(n d ,)(n h 为节点n 的状态与目标状态之间错放的个数,即函数)(n ω。

(2)算法描述:① 把起始节点S 放到OPEN 表中,并计算节点S 的)(S f ;② 如果OPEN 是空表,则失败退出,无解;③ 从OPEN 表中选择一个f 值最小的节点i 。

如果有几个节点值相同,当其中有一个 为目标节点时,则选择此目标节点;否则就选择其中任一个节点作为节点i ;④ 把节点i 从 OPEN 表中移出,并把它放入 CLOSED 的已扩展节点表中;⑤ 如果i 是个目标节点,则成功退出,求得一个解;⑥ 扩展节点i ,生成其全部后继节点。

八数码问题报告

八数码问题报告

⼋数码问题报告⼋数码问题分析班级:计算机1041学号:01姓名:李守先2013年9⽉26⽇摘要⼋数码问题(Eight-puzzle Problem )是⼈⼯智能中⼀个很典型的智⼒问题。

本⽂以状态空间搜索的观点讨论了⼋数码问题,给出了⼋数码问题的Java 算法与实现的思想, 分析了A*算法的可采纳性等及系统的特点。

关键词九宫重排, 状态空间, 启发式搜索, A*算法1 引⾔九宫重排问题(即⼋数码问题)是⼈⼯智能当中有名的难题之⼀。

问题是在3×3⽅格盘上,放有⼋个数码,剩下⼀个位置为空,每⼀空格其上下左右的数码可移⾄空格。

问题给定初始位置和⽬标位置,要求通过⼀系列的数码移动,将初始状态转化为⽬标状态。

状态转换的规则:空格周围的数移向空格,我们可以看作是空格移动,它最多可以有4个⽅向的移动,即上、下、左、右。

九宫重排问题的求解⽅法,就是从给定的初始状态出发,不断地空格上下左右的数码移⾄空格,将⼀个状态转化成其它状态,直到产⽣⽬标状态。

图1许多学者对该问题进⾏了有益的探索[1,2,4,6]。

给定初始状态,9个数在3×3中的放法共有9!=362880种,其状态空间是相当⼤的。

因此, 有必要考虑与问题相关的启发性信息来指导搜索,以提⾼搜索的效率。

当然,还有个很重要的问题:每个初始状态都存在解路径吗?⽂献给出了九宫重排问题是否有解的判别⽅法:九宫重排问题存在⽆解的情况,当遍历完所有可扩展的状态也没有搜索到⽬标状态就判断为⽆解。

可以根据状态的逆序数来先验的判断是否有解,当初始状态的逆序数和⽬标状态的逆序数的奇偶性相同时,问题有解;否则问题⽆解。

状态的逆序数是定义把三⾏数展开排成⼀⾏,并且丢弃数字 0 不计⼊其中,ηi 是第 i 个数之前⽐该数⼩的数字的个数,则η=Σηi 是该状态的逆序数,图2说明了逆序数计算的过程。

本⽂介绍⽤JAVA 编写九宫重排问题游戏。

游戏规则是,可随机产⽣或由⽤户设置初始状态,由初始状态出发,不断地在空格上下左右的数码移⾄空格,若能排出⽬标状态,则成功。

人工智能实验报告 八数码

人工智能实验报告 八数码

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

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

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

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

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

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

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

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

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

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

实验结果表明,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,6 3,2,1,8,0,4,7,6,5 1,0,4,2,7,3,8,5,6 1,0,3,8,2,4,7,6,5static int arrayStep41[6]={5,4,3,6,7,8};//第四步和第六步共用的数组,所以设为全局量static int arrayStep71[4]={3,6,7,4};static int local;//空格的位置int i,j;//所用到的变量int number=0;//记录移动步数void print();void step1();void step2();void step3();void step4();void step5();void step6();void step7();void step8();void step9();void exchange(int x,int y);void judge();void judge()//判断空格位置{number = 0;for(i=0;i<9;i++){if(style[i]==0){local=i;return;}}}void exchange(int x,int y)//交换两个数{int temp;print();temp=style[x];style[x]=style[y];style[y]=temp;local=y;number++;}void step1(){int arrayStep11[5]={3,0,1,2,5};int arrayStep12[6]={6,7,8,5,2,1};if((style[2]!=0)&&style[2]!=1)return;else{if(local==2){if(style[1]==1)exchange(2,5);elseexchange(2,1);return;}else{if(local==4){exchange(4,1);i=2;while(local!=5){exchange(arrayStep11[i],arrayStep11[i+1]);i++;}return;}for(i=0;i<3;i++){if(arrayStep11[i]==local){while(local!=5){exchange(arrayStep11[i],arrayStep11[i+1]);i++;}return;}}for(i=0;i<4;i++){if(arrayStep12[i]==local){while(local!=1){exchange(arrayStep12[i],arrayStep12[i+1]);i++;}return;}}}}return;}void step2(){int arrayStep21[8]={0,3,6,7,8,5,4,1};for(i=0;i<8;i++){if(arrayStep21[i]==local){while(style[0]!=1){exchange(arrayStep21[i%8],arrayStep21[(i+1)%8]);i++;}break;}}}void step3(){int arrayStep31[8]={2,1,4,3,6,7,8,5};for(i=0;i<8;i++){if(arrayStep31[i]==local){while(style[1]!=2){exchange(arrayStep31[i%8],arrayStep31[(i+1)%8]);i++;}break;}}}void step4(){for(i=0;i<6;i++){if(arrayStep41[i]==local){while((style[4]!=3)){exchange(arrayStep41[i%6],arrayStep41[(i+1)%6]);i=(i+1)%6;}while(local!=3){exchange(arrayStep41[i%6],arrayStep41[(i+5)%6]);i=(i+5)%6;}break;}}}void step5(){int arrayStep51[9]={3,0,1,4,5,2,1,0,3};i=0;do{exchange(arrayStep51[i],arrayStep51[i+1]);i++;}while(local!=3);}void step6(){for(i=0;i<6;i++){if(arrayStep41[i]==local){while(style[5]!=4){exchange(arrayStep41[i%6],arrayStep41[(i+1)%6]);i++;}if(local==8)exchange(8,7);break;}}return;}void step7(){for(i=0;i<4;i++){if(arrayStep71[i]==local){while(style[4]!=5){exchange(arrayStep71[i%4],arrayStep71[(i+1)%4]);i=(i+1)%4;}while(local!=3){exchange(arrayStep71[i%4],arrayStep71[(i+3)%4]);i=(i+3)%4;}break;}}}void step8(){int arrayStep81[13]={3,0,1,2,5,4,7,8,5,2,1,0,3};i=0;do{exchange(arrayStep81[i],arrayStep81[i+1]);i++;}}void step9(){for(i=0;i<4;i++){if(arrayStep71[i]==local){while(style[7]!=6){exchange(arrayStep71[i%4],arrayStep71[(i+1)%4]);i=(i+1)%4;}while(local!=4){exchange(arrayStep71[i%4],arrayStep71[(i+3)%4]);i=(i+3)%4;}break;}}}void print(){for(j=0;j<9;j++){if(style[j]==0)printf(" \t");elseprintf("%d\t",style[j]);if((j+1)%3==0)printf("\n");}printf("************ %d ***********\n",number);}void loop(){printf("请输入数码:\n");for(i=0;i<9;i++)scanf("%d",&style[i]);judge();step1();step2();step3();{step4();step5();}step6();if(style[8]!=5){step7();step8();}step9();print();if(!((style[3]==8)&&(style[6]==7)))printf("用书上所给算法来看此数码错误!\n"); }void main(){while(1)loop();}2.深度优先实现/***************说明***********************用宽度优先搜索算法实现八数码问题******************************************/#include<iostream>#include<stdio.h>#include<fstream>#include<stdlib.h>#include "string.h"#include "assert.h"#include "windows.h"using namespace std;int wholeStyle[9] = {2,8,3,1,6,4,7,0,5};int standard1[9] = {1,2,3,8,0,4,7,6,5};int local,i,j;int startKey = 0,endKey = 0,equalKey = 1,tempSpace;struct node *openHead,*open; //open表struct node *closedHead,*closed; //closed表struct node *tempNode; //临时节点struct node *answer; //找到的路径int num = 0;struct node{int style[9];struct node *next;struct node *father;};void updateData() //更新要判断数据{int i;printf("请输入八数码原始状态:\n");for(i = 0;i < 9;i++)scanf("%d",&wholeStyle[i]);printf("请输入八数码最终状态:\n");for(i = 0;i < 9;i++)scanf("%d",&standard1[i]);}void judge1(struct node *head)//判断空格位置{for(i = 0;i < 9;i++){if(head->style[i] == 0){local = i;return;}}}int judge2(struct node *head) //判断是否与标准八数码相等,不相等返回值为0 {for(i = 0;i < 9;i++){if(head->style[i] != standard1[i]){if((i == 3)&&(head->style[3] == standard1[6]));else if((i == 6)&&(head->style[6] == standard1[3]));elsereturn 0;}}return 1;}void judge3() //判断新生成的八数码是否就是最终状态或者在open、closed表中出现{if(judge2(tempNode))endKey = 1;else{while(openHead->next->next->style[0] != 9){for(i = 0;i < 9;i++){if(openHead->next->next->style[i] != tempNode->style[i]){equalKey = 1;break;}elseequalKey = 0;}if(equalKey)//不相等openHead = openHead->next;elsebreak;}openHead = open->next;if(equalKey)//不相等{while(closedHead->next->style[0] != 9){for(i = 0;i < 9;i++){if(closedHead->next->style[i] != tempNode->style[i]){equalKey = 1;break;}elseequalKey = 0;}if(!equalKey)//相等break;elseclosedHead = closedHead->next;}closedHead = closed->next;}if(equalKey)//不相等{open->next = tempNode;tempNode->next = openHead;tempNode->father = openHead->next;open = open->next;}}}void print(struct node *temp) //输出八数码表{for(j = 0;j < 9;j++){if(temp->style[j] == 0)printf(" \t");elseprintf("%d\t",temp->style[j]);if((j + 1) % 3 == 0)printf("\n");}}void write2txt(){ofstream out("F:\\out_details.txt",ios::app);if( out.fail() ){cerr<<"未找到文件"<<endl;}out<<" 第"<<++num<<"步\n";out<<"open table:\n";while(openHead->next->style[0] != 9){for(i = 0;i < 9;i ++){out<<openHead->next->style[i]<<"\t";if((i+1) % 3 == 0)out<<"\n";}out<<"\n";openHead = openHead->next;}openHead = openHead->next;out<<"*********************\n";out<<"closed table:\n";while(closedHead->next->style[0] != 9){for(i = 0;i < 9;i ++){out<<closedHead->next->style[i]<<"\t";if((i + 1) % 3 ==0)out<<"\n";}out<<"\n";closedHead = closedHead->next;}closedHead = closedHead->next;out<<"-----------------------------------\n";out.close();}void main(){//updateData();//输入八数码数据for(i = 0;i < 9;i++) //判断初始状态是否已经为最终状态{if(wholeStyle[i] == standard1[i]);else{if((i == 3)&&(wholeStyle[i] == standard1[6]));else if((i == 6)&&(wholeStyle[i] == standard1[3]));else{startKey = 1;break;}}}if(!startKey){printf("不用判断!\n");return;}printf("要判断!\n");openHead = new node();open = new node();openHead->style[0] = 9;openHead->next = open;for(i = 0;i < 9;i++)open->style[i] = wholeStyle[i];open->next = openHead;open->father = openHead;closedHead = new node();closed = new node();closedHead->style[0] = 9;closedHead->next = closedHead;closed = closedHead;while(open->style[0] != 9)//当open表不为空时一直循环{judge1(openHead->next);if(local % 3 > 0)//右移{equalKey = 1;tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = openHead->next->style[i];tempSpace = tempNode->style[local - 1];tempNode->style[local - 1] = tempNode->style[local];tempNode->style[local] = tempSpace;judge3();}if(endKey)break;if(local > 2)//下移{equalKey = 1;tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = openHead->next->style[i];tempSpace = tempNode->style[local - 3];tempNode->style[local - 3] = tempNode->style[local];tempNode->style[local] = tempSpace;judge3();}if(endKey)break;if(local % 3 < 2)//左移{equalKey = 1;tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = openHead->next->style[i];tempSpace = tempNode->style[local + 1];tempNode->style[local + 1] = tempNode->style[local];tempNode->style[local] = tempSpace;judge3();}if(endKey)break;if(local < 6)//上移{equalKey = 1;tempNode = new node();//tempNode = malloc(sizeof(struct node));for(i = 0;i < 9;i++)tempNode->style[i] = openHead->next->style[i];tempSpace = tempNode->style[local + 3];tempNode->style[local + 3] = tempNode->style[local];tempNode->style[local] = tempSpace;judge3();}if(endKey)break;closed->next = openHead->next; //把open的标头添加到closed表中openHead->next = openHead->next->next;closed = closed->next;closed->next = closedHead;write2txt();}open->next = tempNode;//把找到的新节点添加到open表中tempNode->next = openHead;tempNode->father = openHead->next;open = open->next;closed->next = openHead->next; //把open的标头添加到closed表中openHead->next = openHead->next->next;closed = closed->next;closed->next = closedHead;write2txt();answer = new node();tempNode = new node();tempNode = open;while(tempNode->style[0] != 9)//将结果路径存于answer{answer = tempNode;tempNode = tempNode->father;tempNode->next = answer;}num = 0;while(answer->next->style[0] != 9)//输出answer{printf("***********第%d步***********\n",num++);print(answer);answer = answer->next;printf("\n");}printf("***********第%d步***********\n",num++);print(answer);if(answer->style[3] != standard1[3])printf("\n!!输入的八数码不合法,不能从初始状态到最终状态\n\n\n\n");return;}3.宽度优先:/***************说明***********************用宽度优先搜索算法实现八数码问题******************************************/#include<iostream>#include<stdio.h>#include<fstream>#include<stdlib.h>#include "string.h"#include "assert.h"#include "windows.h"using namespace std;int wholeStyle[9] = {2,8,3,1,6,4,7,0,5};int standard1[9] = {1,2,3,8,0,4,7,6,5};int local,i,j;int startKey = 0,endKey = 0,equalKey = 1,tempSpace; struct node *openHead,*open; //open表struct node *closedHead,*closed; //closed表struct node *tempNode; //临时节点struct node *answer; //找到的路径int num = 0;struct node{int style[9];struct node *next;struct node *father;};void updateData() //更新要判断数据{int i;printf("请输入八数码原始状态:\n");for(i = 0;i < 9;i++)scanf("%d",&wholeStyle[i]);printf("请输入八数码最终状态:\n");for(i = 0;i < 9;i++)scanf("%d",&standard1[i]);}void judge1(struct node *head)//判断空格位置{for(i = 0;i < 9;i++){if(head->style[i] == 0){local = i;return;}}}int judge2(struct node *head) //判断是否与标准八数码相等,不相等返回值为0{for(i = 0;i < 9;i++){if(head->style[i] != standard1[i]){if((i == 3)&&(head->style[3] == standard1[6]));else if((i == 6)&&(head->style[6] == standard1[3]));elsereturn 0;}}return 1;}void judge3() //判断新生成的八数码是否就是最终状态或者在open、closed表中出现{if(judge2(tempNode))endKey = 1;else{while(openHead->next->next->style[0] != 9){for(i = 0;i < 9;i++){if(openHead->next->next->style[i] != tempNode->style[i]){equalKey = 1;break;}elseequalKey = 0;}if(equalKey)//不相等openHead = openHead->next;elsebreak;}openHead = open->next;if(equalKey)//不相等{while(closedHead->next->style[0] != 9){for(i = 0;i < 9;i++){if(closedHead->next->style[i] != tempNode->style[i]){equalKey = 1;break;}elseequalKey = 0;}if(!equalKey)//相等break;elseclosedHead = closedHead->next;}closedHead = closed->next;}if(equalKey)//不相等{open->next = tempNode;tempNode->next = openHead;tempNode->father = openHead->next;open = open->next;}}}void print(struct node *temp) //输出八数码表{for(j = 0;j < 9;j++){if(temp->style[j] == 0)printf(" \t");elseprintf("%d\t",temp->style[j]);if((j + 1) % 3 == 0)printf("\n");}}void write2txt(){ofstream out("F:\\out_details.txt",ios::app);if( out.fail() ){cerr<<"未找到文件"<<endl;}out<<" 第"<<++num<<"步\n";out<<"open table:\n";while(openHead->next->style[0] != 9){for(i = 0;i < 9;i ++){out<<openHead->next->style[i]<<"\t";if((i+1) % 3 == 0)out<<"\n";}out<<"\n";openHead = openHead->next;}openHead = openHead->next;out<<"*********************\n";out<<"closed table:\n";while(closedHead->next->style[0] != 9){for(i = 0;i < 9;i ++){out<<closedHead->next->style[i]<<"\t";if((i + 1) % 3 ==0)out<<"\n";}out<<"\n";closedHead = closedHead->next;}closedHead = closedHead->next;out<<"-----------------------------------\n";out.close();}void main(){//updateData();//输入八数码数据for(i = 0;i < 9;i++) //判断初始状态是否已经为最终状态{if(wholeStyle[i] == standard1[i]);else{if((i == 3)&&(wholeStyle[i] == standard1[6]));else if((i == 6)&&(wholeStyle[i] == standard1[3]));else{startKey = 1;break;}}}if(!startKey){printf("不用判断!\n");return;}printf("要判断!\n");openHead = new node();open = new node();openHead->style[0] = 9;openHead->next = open;for(i = 0;i < 9;i++)open->style[i] = wholeStyle[i];open->next = openHead;open->father = openHead;closedHead = new node();closed = new node();closedHead->style[0] = 9;closedHead->next = closedHead;closed = closedHead;while(open->style[0] != 9)//当open表不为空时一直循环{judge1(openHead->next);if(local % 3 > 0)//右移{equalKey = 1;tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = openHead->next->style[i];tempSpace = tempNode->style[local - 1];tempNode->style[local - 1] = tempNode->style[local];tempNode->style[local] = tempSpace;judge3();}if(endKey)break;if(local > 2)//下移{equalKey = 1;tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = openHead->next->style[i];tempSpace = tempNode->style[local - 3];tempNode->style[local - 3] = tempNode->style[local];tempNode->style[local] = tempSpace;judge3();}if(endKey)break;if(local % 3 < 2)//左移{equalKey = 1;tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = openHead->next->style[i];tempSpace = tempNode->style[local + 1];tempNode->style[local + 1] = tempNode->style[local];tempNode->style[local] = tempSpace;judge3();}if(endKey)break;if(local < 6)//上移{equalKey = 1;tempNode = new node();//tempNode = malloc(sizeof(struct node));for(i = 0;i < 9;i++)tempNode->style[i] = openHead->next->style[i];tempSpace = tempNode->style[local + 3];tempNode->style[local + 3] = tempNode->style[local];tempNode->style[local] = tempSpace;judge3();}if(endKey)break;closed->next = openHead->next; //把open的标头添加到closed表中openHead->next = openHead->next->next;closed = closed->next;closed->next = closedHead;write2txt();}open->next = tempNode;//把找到的新节点添加到open表中tempNode->next = openHead;tempNode->father = openHead->next;open = open->next;closed->next = openHead->next; //把open的标头添加到closed表中openHead->next = openHead->next->next;closed = closed->next;closed->next = closedHead;write2txt();answer = new node();tempNode = new node();tempNode = open;while(tempNode->style[0] != 9)//将结果路径存于answer{answer = tempNode;tempNode = tempNode->father;tempNode->next = answer;}num = 0;while(answer->next->style[0] != 9)//输出answer{printf("***********第%d步***********\n",num++);print(answer);answer = answer->next;printf("\n");}printf("***********第%d步***********\n",num++);print(answer);if(answer->style[3] != standard1[3])printf("\n!!输入的八数码不合法,不能从初始状态到最终状态\n\n\n\n");return;}4.A算法/***************说明************************* A算法实现八数码问题********************************************/#include<iostream>#include<fstream>#include<iomanip>using namespace std;void print(struct node *temp);int wholeStyle[9] = {2,8,3,1,6,4,7,0,5};int standard1[9] = {1,2,3,8,0,4,7,6,5};int local,i,j;int tempSpace;struct node *openHead,*open; //open表struct node *closedHead,*closed; //closed表struct node *tempNode; //临时节点struct node *answer; //找到的路径int num = 0;bool endKey;struct node{int depth;int judgement_based;int style[9];struct node *next;struct node *father;};void updateData() //更新要判断数据{int i;cout<<"请输入八数码原始状态:"<<endl;for(i = 0;i < 9;i++)cin>>wholeStyle[i];cout<<"请输入八数码最终状态:"<<endl;for(i = 0;i < 9;i++)cin>>standard1[i];}int judge1(struct node *head)//判断空格位置{for(i = 0;i < 9;i++){if(head->style[i] == 0)return i;}}int evaluation_function(struct node *head) //计算不在正确位置的点的个数{int not_correct_position = 0;for(i = 0;i < 9;i++)if((head->style[i] != 0)&&(head->style[i] != standard1[i]))not_correct_position++;return not_correct_position;}void print(struct node *temp) //输出八数码表{for(j = 0;j < 9;j++){if(temp->style[j] == 0)cout<<" \t";elsecout<<temp->style[j]<<"\t";if((j + 1) % 3 == 0)cout<<endl;}}void write2txt() //将过程记录到文本文档中{ofstream out("F:\\out_details4.txt",ios::app);if( out.fail() ){cerr<<"未找到文件"<<endl;}out<<" 第"<<++num<<"步\n";out<<"open table:\n";while(openHead->next->style[0] != 9){for(i = 0;i < 9;i ++){out<<openHead->next->style[i]<<"\t";if((i+1) % 3 == 0)out<<"\n";}out<<"估值:";out<<openHead->next->judgement_based<<"\n";openHead = openHead->next;}openHead = openHead->next;out<<"*********************\n";out<<"closed table:\n";while(closedHead->next->style[0] != 9){for(i = 0;i < 9;i ++){out<<closedHead->next->style[i]<<"\t";if((i + 1) % 3 ==0)out<<"\n";}out<<"深度:"<<closedHead->next->depth<<" 估值:"<<closedHead->next->judgement_based<<"\n";closedHead = closedHead->next;}closedHead = closedHead->next;out<<"-----------------------------------\n";out.close();}void basic_exchange_oper() //每一次基本的交换都要进行的动作{if(judge1(tempNode) != judge1(closed->father))//当新生成节点的空格位置与closed父亲节点的空格位置不相等{tempNode->father = closed; //新生成节点的指向它的父亲节点tempNode->depth = closed->depth + 1;//深度加1tempNode->judgement_based = evaluation_function(tempNode) + tempNode->depth;//计算估值while(openHead->next->style[0] != 9){if(tempNode->judgement_based > openHead->next->judgement_based){openHead = openHead->next;}else{tempNode->next = openHead->next;openHead->next = tempNode;openHead = open->next;return;}}//插入的值比最后一个还大进行下面的操作openHead = open->next;//先恢复表头否则Head指向为最后一个open->next = tempNode;tempNode->next = openHead;open = open->next;return;}}void main(){//updateData();//输入八数码数据openHead = new node(); //初始化open表open = new node();openHead->style[0] = 9;openHead->next = open;for(i = 0;i < 9;i++)open->style[i] = wholeStyle[i];open->next = openHead;open->father = openHead;open->depth = 0;open->judgement_based = evaluation_function(open) + open->depth;//这行可以不写closedHead = new node(); //初始化closed表closed = new node();closedHead->style[0] = 9;closedHead->next = closedHead;closed = closedHead;int min_judgement1 = open->judgement_based;while(open->style[0] != 9)//当open表不为空时一直循环{//updateData();//输入八数码数据write2txt();closed->next = openHead->next; //把open表中第一组八数码移到closed表中openHead->next = openHead->next->next;closed = closed->next;closed->next = closedHead;if(openHead->next->style[0] == 9)//如果是第一次则open暂时指向openHead open = openHead;if(closed->judgement_based == closed->depth)//判断新移进closed表中的八数码的f 值是否等于它的层数{cout<<"succeed!"<<endl;write2txt();answer = new node();while(closed->style[0] != 9) //将结果存于answer表中{answer = closed;closed = closed->father;closed->next = answer;}num = 0;while(answer->style[0] != 9) //控制台显示步骤{cout<<"******第"<<num++<<"步***********\n";print(answer);cout<<endl;answer = answer->next;}return;}else //如果closed表末的八数码是最终状态则拓展新的八数码{local = judge1(closed);if(local % 3 > 0)//右移{tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = closed->style[i];tempSpace = tempNode->style[local - 1];tempNode->style[local - 1] = tempNode->style[local];tempNode->style[local] = tempSpace;basic_exchange_oper();}if(local < 6)//上移{tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = closed->style[i];tempSpace = tempNode->style[local + 3];tempNode->style[local + 3] = tempNode->style[local];tempNode->style[local] = tempSpace;basic_exchange_oper();}if(local > 2)//下移{tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = closed->style[i];tempSpace = tempNode->style[local - 3];tempNode->style[local - 3] = tempNode->style[local];tempNode->style[local] = tempSpace;basic_exchange_oper();}if(local % 3 < 2)//左移{tempNode = new node();for(i = 0;i < 9;i++)tempNode->style[i] = closed->style[i];tempSpace = tempNode->style[local + 1];tempNode->style[local + 1] = tempNode->style[local];tempNode->style[local] = tempSpace;basic_exchange_oper();}}}cout<<"false!"<<endl;}神经网络实验群神经网络实验一、实验目的:理解反向传播网络的结构和原理,掌握反向传播算法对神经元的训练过程,了解反向传播公式。

人工智能八数码游戏

人工智能八数码游戏

实验一:八数码游戏问题一、八数码游戏问题简介九宫排字问题(又称八数码问题)是人工智能当中有名的难题之一。

问题是在3X3方格盘上,放有八个数码,剩下第九个为空,每一空格其上下左右的数码可移至空格。

问题给定初始位置和目标位置,要求通过一系列的数码移动,将初始位置转化为目标位置。

(a)初始状态小)目标状态图八数码游戏二、实验目的1.熟悉人工智能系统中的问题求解过程;2.熟悉状态空间的盲目搜索和启发式搜索算法的应用;3.熟悉对八数码问题的建模、求解及编程语言的应用。

三、实验的思路八数码问题:在3X3的方格棋盘上,摆放着1到8这八个数码,有1个方格是空的,其初始状态如图1所示,要求对空格执行空格左移、空格右移、空格上移和空格下移这四个操作使得棋盘从初始状态到目标状态。

例如:(a)初始状态图1八数码问题示意图1 .启发函数设定由八数码问题的部分状态图可以看出,从初始节点开始,在通向目标节点的 路径上,各节点的数码格局同目标节点相比较,其数码不同的位置个数在逐渐减 少,最后为零,因此可以把数码不同的位置个数作为标志一个节点到目标节点距 离远近的一个启发性信息,利用这个信息来扩展节点的选择,减少搜索范围,提 高搜索速度。

2 .搜索过程:(搜索采用广度搜索方式,利用待处理队列辅助,逐层搜索(跳过 劣质节点))a 、把初始数码组压入队列;b 、从队列中取出一个数码组节点;c 、扩展子节点,即从上下左右四个方向移动空格,生成相应子节点:d 、对子节点数码组作评估,是否为优越节点,即其评估值是否小于等于其 父节点加一,是则将其压入队,否则抛弃。

e 、判断压入队的子节点数码组(优越点)的评估值,为零则表示搜索完成, 退出搜索;f 、跳到步骤2;四、数据结构的设计//八数码结构体 //数码组 //评估值,差距//所屏蔽方向,防止往回推到上一状态,1上2下3左4//父节点数码结构体typedef struct node(int form[N][N];int evalue;int udirec; 右 struct node *parent;}Graph;Graph *Qu[MAX];//队列Graph *St[MAX];//堆栈起始成功是否有后继节点为目标节点?... 是否open 表为空表? ..否 否 是是—工失败扩展节点n ,把其后裔放入open 表的前头把open 表中的第一个节点n移入close 表把s 放入open 表五、实验过程及代码#include <stdio.h> } 〃设计了搜索深度范围,防止队列内存越界#include <stdlib.h> #include <time.h>#define N 3 〃数码组大小#define Max_Step 50 //最大搜索深度#define MAX 50typedef struct node//八数码结构体( int form[N][N];//数码组int evalue;//评估值int udirect;〃所屏蔽方向,防止往回推到上已状态,1上2下3左4右struct node "parentJ/父节点}Graph;Graph *Qu[MAX]; 〃队列Graph *St[MAX]; 〃堆栈/////////打印数码组void Print(Graph *The_graph) ( int i,j; if(The_graph==NULL) printf("图为空\n"); else ( printf(" -------------------------- \n");for(i=0;i<N;i++) ( printf("|\t"); for(j=0;j<N;j++)( printf("%d\t",The_graph->form[i][j]);/遍历打印} printf("\t|\n");} printf("|\t\t\t 差距:%d\t|\n",The_graph->evalue);//差距显示printf(" ----------------- \n");〃〃〃〃/评价函数int Evaluate(Graph *The_graph,Graph *End_graph)(int 丫21a©=0;//差距数int i,j;for(i=0;i<N;i++)(for(j=0;j<N;j++)(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) (Graph *New_graph;int HasGetBlank=0;//是否获取空格位置int Ab1eMove=1;//是否可移动int i,j,t_i,t_j,x,y;for(i=0;i<N;i++)//获取空格坐标i,j(for(j=0;j<N;j++)(if(The_graph->form[i][j]==0)(HasGetBlank=1;break;))if(HasGetBlank==1)break;)//printf("空格位置:%d,%d\n”,i,j);t_i=i;t_j=j;〃移动空格switch(Direct) (case 1:〃上t_i--;if(t_i<0)AbleMove=0;break;case 2:〃下t_i++;if(t_i>=N)AbleMove=0;break;case 3:〃左t_j--;if(t_j<0)AbleMove=0;break;case 4:〃右t_j++; if(t_j>=N)AbleMove=0; break;)if(AbleMove==0)//不能移动则返回原节点(return The_graph;)if(CreatNew_graph==1)(New_graph=(Graph *)malloc(sizeof(Graph));//生成节点for(x=0;x<N;x++) ( for(y=0;y<N;y++)(New_graph->form[x][y]=The_graph->form[x][y];/复制数码组)) else(New_graph=The_graph;)〃移动后New_graph->form[i][j]=New_graph->form[t_i][t_j];New_graph->form[t_i][t_j]=0;//printfC移动产生的新图:\n");//Print(New_graph);return New_graph;)/////////搜索函数Graph *Search(Graph *Begin,Graph *End) (Graph *g1,*g2,*g;int Step=0;//^^int Direct=0;//方向int i;int front,rear;front=rear=-1;//队列初始化g=NULL;rear++;//A^Qu[rear]=Begin;while(rear!=front)//队列不空(front++;//出队g1=Qu[front];//printf("开始第%d 个图:\n",front);//Print(g1);代班=1;1<=4计+)//分别从四个方向推导出新子节点(Direct=i;if(Direct==g1->udirect)//跳过屏蔽方向continue;g2=Move(g1, Direct, 1);//移动数码组if(g2!=g1)//数码组是否可以移动(〃可以移动Evaluate(g2, End);//评价新的节点//printfC开始产生的第%d个图:\n",i);//Print(g2);if(g2->evalue<=g1->evalue+1) (〃是优越节点g2->parent=g1;〃移动空格switch①irect)//设置屏蔽方向,防止往回推(case 1://上g2->udirect=2;break;case 2://下g2->udirect=1;break;case 3://左g2->udirect=4;break;case 4://右g2->udirect=3; break;)rear++;Qu[rear]=g2;//存储节点到待处理队列if(g2->evalue==0)〃为0 则搜索完成(g=g2;//i=5;break;))else(free(g2);//抛弃劣质节点g2=NULL;)))if(g!=NULL)〃为0则搜索完成(if(g->evalue==0)(break;Step++;//统计深度if(Step>Max_Step) (break;))return g;) int main (int argc, const char * argv[])(// insert code here...Graph Begin_graph={{{2,8,3},{1,6,4},{7,0,5}},0,0,NULL);/*Graph Begin_graph={{{2,8,3},{1,0,4},{7,6,5}},0,0,NULL };Graph Begin_graph={{{2,0,1},{4,6,5},{3,7,8}},0,0,NULL};*///目标数码组Graph End_graph={{{1,2,3},{8,0,4},{7,6,5}},0,0,NULL };Evaluate(&Begin_graph, &End_graph);//对初始的数码组评价printf("初始数码组:\n");Print(&Begin_graph);printf("目标数码组:\n");Print(&End_graph);Graph *G,*P;int top=-1;〃图搜索G=Search(&Begin_graph, &End_graph);〃打印if(G)(〃把路径倒序P=G;〃压栈while(P!=NULL)(top++;St[top]=P;P=P->parent;}printf("vvvvvvvvvvvvvvv 搜索结果〃弹栈打印while(top>-l)(P=St[top];top-;Print(P);}printf("««««««««<^^»»»»»»»»»\n"); } else(printf("搜索不到结果,深度为%d\n",Max_Step);〃设计搜索深度范围主要是防止队列内存越界return 0;六、实验结果。

八数码问题,实验报告

八数码问题,实验报告

八数码问题,实验报告八数码实验报告利用人工智能技术解决八数码游戏问题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 数码问题的求解过程。

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

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

基于人工智能的状态空间搜索策略研究
——八数码问题求解
(一)实验软件
TC2.0 或VC6.0编程语言或其它编程语言
(二)实验目的
1. 熟悉人工智能系统中的问题求解过程;
2. 熟悉状态空间的盲目搜索和启发式搜索算法的应用;
3. 熟悉对八数码问题的建模、求解及编程语言的应用。

(三)需要的预备知识
1. 熟悉TC
2.0或VC6.0 编程语言或者其它编程语言;
2. 熟悉状态空间的宽度优先搜索、深度优先搜索和启发式搜索算法;
3. 熟悉计算机语言对常用数据结构如链表、队列等的描述应用;
4. 熟悉计算机常用人机接口设计。

(四)实验数据及步骤
1. 实验内容
八数码问题:在3×3的方格棋盘上,摆放着1到8这八个数码,有1个方格是空的,其初始状态如图1所示,要求对空格执行空格左移、空格右移、空格上移和空格下移这四个操作使得棋盘从初始状态到目标状态。

图1 八数码问题示意图
请任选一种盲目搜索算法(深度优先搜索或宽度优先搜索)或任选一种启发式搜索方法(A 算法或A* 算法)编程求解八数码问题(初始状态任选),并对实验结果进行分析,得出合理的结论。

2. 实验步骤
(1)分析算法基本原理和基本流程;
程序采用宽度优先搜索算法,基本流程如下:
(2)确定对问题描述的基本数据结构,如Open表和Closed表等;
(3)编写算符运算、目标比较等函数;
(4)编写输入、输出接口;
(5)全部模块联调;
(6)撰写实验报告。

(五)实验报告要求
所撰写的实验报告必须包含以下内容:
1. 算法基本原理和流程框图;
2. 基本数据结构分析和实现;
3. 编写程序的各个子模块,按模块编写文档,含每个模块的建立时间、功能、输入输出参数意义和与其它模块联系等;
4. 程序运行结果,含使用的搜索算法及搜索路径等;
5. 实验结果分析;
6. 结论;
7. 提供全部源程序及软件的可执行程序。

附:实验报告格式
一、实验问题
二、实验目的
三、实验原理
四、程序框图
五、实验结果及分析
六、结论。

相关文档
最新文档