好文档就是一把金锄头!
欢迎来到金锄头文库![会员中心]
电子文档交易市场
安卓APP | ios版本
电子文档交易市场
安卓APP | ios版本

八数码问题C语言A星算法详细实验报告含代码[共11页].docx

11页
  • 卖家[上传人]:哈****
  • 文档编号:195695493
  • 上传时间:2021-09-11
  • 文档格式:DOCX
  • 文档大小:256.69KB
  • / 11 举报 版权申诉 马上下载
  • 文本预览
  • 下载提示
  • 常见问题
    • 一、实验内容和要求八数码问题:在33的方格棋盘上,摆放着1到8这八个数码,有1个方格是空的,其初始状态如图1所示,要求对空格执行空格左移、空格右移、空格上移和空格下移这四个操作使得棋盘从初始状态到目标状态例如:28312316484705765(a) 初始状态 (b) 目标状态图1 八数码问题示意图请任选一种盲目搜索算法(广度优先搜索或深度优先搜索)或任选一种启发式搜索方法(全局择优搜索,加权状态图搜索,A 算法或 A* 算法)编程求解八数码问题(初始状态任选)选择一个初始状态,画出搜索树,填写相应的OPEN表和CLOSED表,给出解路径,对实验结果进行分析总结,得出结论二、实验目的1. 熟悉人工智能系统中的问题求解过程;2. 熟悉状态空间的盲目搜索和启发式搜索算法的应用;3. 熟悉对八数码问题的建模、求解及编程语言的应用三、实验算法A*算法是一种常用的启发式搜索算法在A*算法中,一个结点位置的好坏用估价函数来对它进行评估A*算法的估价函数可表示为: f(n) = g(n) + h(n) 这里,f(n)是估价函数,g(n)是起点到终点的最短路径值(也称为最小耗费或最小代价),h(n)是n到目标的最短路经的启发值。

      由于这个f(n)其实是无法预先知道的,所以实际上使用的是下面的估价函数:f(n) = g(n) + h(n) 其中g(n)是从初始结点到节点n的实际代价,h(n)是从结点n到目标结点的最佳路径的估计代价在这里主要是h(n)体现了搜索的启发信息,因为g(n)是已知的用f(n)作为f(n)的近似,也就是用g(n)代替g(n),h(n)代替h(n)这样必须满足两个条件:(1)g(n)>=g(n)(大多数情况下都是满足的,可以不用考虑),且f必须保持单调递增2)h必须小于等于实际的从当前节点到达目标节点的最小耗费h(n)<=h(n)第二点特别的重要可以证明应用这样的估价函数是可以找到最短路径的3.A*算法的步骤A*算法基本上与广度优先算法相同,但是在扩展出一个结点后,要计算它的估价函数,并根据估价函数对待扩展的结点排序,从而保证每次扩展的结点都是估价函数最小的结点A*算法的步骤如下:1)建立一个队列,计算初始结点的估价函数f,并将初始结点入队,设置队列头和尾指针2)取出队列头(队列头指针所指)的结点,如果该结点是目标结点,则输出路径,程序结束否则对结点进行扩展 3)检查扩展出的新结点是否与队列中的结点重复,若与不能再扩展的结点重复(位于队列头指针之前),则将它抛弃;若新结点与待扩展的结点重复(位于队列头指针之后),则比较两个结点的估价函数中g的大小,保留较小g值的结点。

      跳至第五步4)如果扩展出的新结点与队列中的结点不重复,则按照它的估价函数f大小将它插入队列中的头结点后待扩展结点的适当位置,使它们按从小到大的顺序排列,最后更新队列尾指针5)如果队列头的结点还可以扩展,直接返回第二步否则将队列头指针指向下一结点,再返回第二步四、程序框图五、实验结果及分析输入初始状态:2 8 3 目标状态: 1 2 3 1 6 4 8 0 4 7 0 5 7 6 5 运行结果屏幕打印OPEN表与CLOSE表:OPENCLOSE1 2 3 4 02 3 4 5 60 12 3 4 6 70 1 52 3 4 6 8 90 1 5 72 3 4 8 9 100 1 5 7 62 3 4 8 11 12 13 0 1 5 7 6 92 3 4 8 12 13 14 150 1 5 7 6 9 113 4 8 12 13 14 15 16 170 1 5 7 6 9 11 24 8 12 13 14 15 16 17 18 190 1 5 7 6 9 11 2 34 8 12 13 14 15 16 17 19 200 1 5 7 6 9 11 2 3 188 12 13 14 15 16 17 19 21 220 1 5 7 6 9 11 2 3 18 412 13 14 15 16 17 19 21 22 230 1 5 7 6 9 11 2 3 18 4 812 13 14 15 16 17 19 21 22 24 250 1 5 7 6 9 11 2 3 18 4 8 2312 13 14 15 16 17 19 21 22 24 260 1 5 7 6 9 11 2 3 18 4 8 23 24发现26为目标节点0…72 8 31 0 47 6 5搜索树:2..112 8 31 6 47 0 51…72 0 31 8 47 6 54..112 8 31 4 07 6 53..112 8 30 1 47 6 522.142 8 31 4 57 6 019.122 8 37 1 40 6 521.122 8 31 4 37 6 518.100 8 32 1 47 6 511.142 8 31 6 47 5 010.142 8 31 6 47 0 56…92 3 01 8 47 6 55…80 2 31 8 47 6 57…91 2 30 8 47 6 510.112 3 41 8 07 6 520.118 0 32 1 47 6 5注释:每个方格中最上面两个数字分别为编号与启发值,下面九个数字为八数码。

      较粗的箭头为解路径8..121 2 37 8 40 6 59..101 2 38 0 47 6 511..91 0 38 2 47 6 523..91 2 37 8 46 0 513.131 2 38 4 07 6 512.131 2 38 6 47 0 524..81 2 37 0 46 8 525.121 2 37 8 46 5 014.120 1 38 2 47 6 515.143 1 08 2 47 6 5 目标节点 六、结论对于八数码问题,BFS算法最慢,A*算法较快八数码问题的一个状态实际上是0~9的一个排列,对于任意给定的初始状态和目标,不一定有解,也就是说从初始状态不一定能到达目标状态因为排列有奇排列和偶排列两类,从奇排列不能转化成偶排列如果一个数字0~8的随机排列871526340,用F(X)表示数字X前面比它小的数的个数,全部数字的F(X)之和为Y=∑(F(X)),如果Y为奇数则称原数字的排列是奇排列,如果Y为偶数则称原数字的排列是偶排列因此,可以在运行程序前检查初始状态和目标状态的排序的奇偶行是否相同,相同则问题可解,应当能搜索到路径。

      否则无解七、源程序及注释#include #include #include 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_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.digit[i][j] << ; os << endl;}return os;}void PrintSteps(int index, vector& 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。

      点击阅读更多内容
      关于金锄头网 - 版权申诉 - 免责声明 - 诚邀英才 - 联系我们
      手机版 | 川公网安备 51140202000112号 | 经营许可证(蜀ICP备13022795号)
      ©2008-2016 by Sichuan Goldhoe Inc. All Rights Reserved.