有界深度优先搜索算法解决八数码问题
《人工智能导论》(第四版)
课后题5.3 C++实现
题目:
运行结果:
C++代码:
思想:Octal结构体表示一个状态,其中parent和current为父状态和当前状态的值,这个值可以理解为ID,唯一标识一个状态,生成的规则在to_number(int [4][4])函数中。变换空格位置,按顺序分别为:上、下、左、右。伪代码为书中P116的伪代码。
#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 << "请输入八数码数据,按照从左到右,从上至下的顺序,空格用0代替:" << 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 (flagProduce[0][0] && flagProduce[0][1]){cout << "up " << count++ << " " << produce[0].depth << endl;for (int i = 1; i <= 3; i++){for (int j = 1; j <= 3; j++){cout << produce[0].arr[i][j] << " ";}cout << endl;}cout << produce[0].current << endl;cout << "============" << endl;}*/}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 (flagProduce[1][0] && flagProduce[1][1]){cout << "down " << count++ << " " << produce[1].depth << endl;for (int i = 1; i <= 3; i++){for (int j = 1; j <= 3; j++){cout << produce[1].arr[i][j] << " ";}cout << endl;}cout << produce[1].current << endl;cout << "============" << endl;}*/}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 (flagProduce[2][0] && flagProduce[2][1]){cout << "left " << count++ << " " << produce[2].depth << endl;for (int i = 1; i <= 3; i++){for (int j = 1; j <= 3; j++){cout << produce[2].arr[i][j] << " ";}cout << endl;}cout << produce[2].current << endl;cout << "============" << endl;}*/}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 (flagProduce[3][0] && flagProduce[3][1]){cout << "right " << count++ << " " << produce[3].depth << endl;for (int i = 1; i <= 3; i++){for (int j = 1; j <= 3; j++){cout << produce[3].arr[i][j] << " ";}cout << endl;}cout << produce[3].current << endl;cout << "============" << endl;}*/}}if (flag){vector<Octal> answer;cout << "找到一个解!" << endl;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--){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;}}}else{cout << "在深度限制内的所有结果搜索完毕,没有答案!" << endl;}return 0;
}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;
}
有界深度优先搜索算法解决八数码问题相关推荐
- 宽度优先搜索算法解决八数码问题
宽度优先搜索算法解决八数码问题 原理 1.宽度优先搜索是指在一个搜索树中,搜索以同层邻近节点依次扩展节点.这种搜索是逐层进行的,在对下一层的任一节点进行搜索之前,必须搜索完本层的所有节点. 宽度优先搜 ...
- 深度优先搜索解决八数码难题
八数码问题 以前用java写的通过深度优先瘦素解决八数码难题. 对于八数码难题来说,可以把9宫格看成一个[3][3]的二维数组,将空格位置看成0,将0可以移动的方向看成树的枝丫,分为上下左右4个方向. ...
- python---A*搜索算法解决八数码问题
A*解决八数码问题 问题内容 算法流程 相关设置 具体程序 运行结果 遇到的问题 完结 问题内容 [八数码问题] 在一个3×3的九宫中有1-8这8个数字以及一个空格随机摆放在其中的格子里.将该九宫格调 ...
- 深度优先搜索解决八数码问题
//程序描述:基于盲目搜索策略的宽度优先搜索方法#include <iostream> #include <string> #include <cstring> # ...
- 题目2:隐式图的搜索问题(A*算法解决八数码)
数据结构课程实践系列 题目1:学生成绩档案管理系统(实验准备) 题目2:隐式图的搜索问题(A*算法解决八数码) 题目3:文本文件单词的检索与计数(实验准备) 文章目录 数据结构课程实践系列 题目1:学 ...
- A*算法解决八数码问题 Java语言实现
A*算法解决八数码问题 Java语言实现 参考文章: (1)A*算法解决八数码问题 Java语言实现 (2)https://www.cnblogs.com/beilin/p/5981483.html ...
- 求素数mdp c语言问题,C语言使用深度优先搜索算法解决迷宫问题(堆栈)
本文实例讲述了C语言使用深度优先搜索算法解决迷宫问题.分享给大家供大家参考,具体如下: 深度优先搜索 伪代码 (Pseudocode)如下: 将起点标记为已走过并压栈; while (栈非空) { 从 ...
- Nilsson's sequence score算法解决八数码问题解释
解决了最近一个人工智能关于解决八数码难题的作业. 图可能看不清,除了黑块外其他位置是英文字母ABCDEFGH A*:f(n)=g(n)+h(n) 其中f为总花费,g为已知花费(深度),h为估计花费 关 ...
- Python利用A*算法解决八数码问题
资源下载地址:https://download.csdn.net/download/sheziqiong/86790565 资源下载地址:https://download.csdn.net/downl ...
最新文章
- Django 1.11 bootstrap样式文件无法加载问题解决
- php显示错误内容为空,检查文件夹是否为空输出错误(PHP)
- 使用原生 Java 玩转验证码【含 DATA-URIS 介绍】
- 深入浅出之函数的参数传递方式
- leetcode-16-最接近的三数之和
- 用python打开视频_Python读取视频的两种方法(imageio和cv2)
- IOS开发基础之绘制饼图、柱状图、自定义进度条
- 影响PoE交换机不稳定的因素
- 解决EF使用context.Database.SqlQuery时NotMapped属性列为空null的问题(转载)
- 【Elasticsearch】elasticsearch 磁盘相关常用配置 磁盘优化
- Hadoop版本比较
- 操作系统文件的物理结构(文件分配方式)
- 状态输出导航栏html,网页导航条代码
- 如何在PDF页面中插入图片?
- ESP8266-NodeMCU项目(四):将上一项目的空调控制接入小爱同学(Blinker_APP同步控制+DHT11温湿度模块数据接入)
- 网页简单整合Skype
- 精华【分布式微服务云架构dubbo+zookeeper+springmvc+mybatis+shiro+redis】分布式大型互联网企业架构!
- burpsuite安装注册
- 验证银行卡卡号是否符合规则
- 记swagger离线文档乱码解决