//程序描述:基于盲目搜索策略的宽度优先搜索方法#include <iostream>
#include <string>
#include <cstring>
#include <cmath>
#include <vector>
// #include <queue>
#include <stack>
#include <set>
using namespace std;#define N 9       //九宫格总数字//数组定义:0~9阶乘定义
const int jc[N + 1] = { 1,1,2,6,24,120,720,5040,40320,362880 };    //0-9的阶乘//数组定义,移动规则(分别对应空格右移、下移、上移、左移)
const int zero_move[4][2] = { {0,1}, {1,0},{0,-1},{-1,0} };//结构体定义:状态结构体
typedef struct Status
{int array[N];   //状态数组int hash;       //存储某一状态的哈希索引int pos;        //0(空格)当前位置int step;       //记录移动步数
}Node;//函数功能:康托展开
//函数参数:某一状态序列
//函数返回:康托展开值
int cantor(int arr[N])
{int i, j;int sum = 0;for (i = 0; i < N; i++){int nmin = 0;for (j = i + 1; j < N; j++){if (arr[i] > arr[j])nmin++;}sum += (nmin * jc[N - i - 1]);}return sum;
}//函数功能:交换数组
void swap(int* array, int i, int j)
{int t = array[i];array[i] = array[j];array[j] = t;
}//函数功能:以矩阵形式打印状态数组
void printArray(int* array)
{for (int i = 0; i < N; i++){if (i % 3 == 0)cout << "\n";cout << array[i] << " ";}cout << endl;
}//函数功能:复制数组
void copyArray(int source[N], int target[N])
{for (int i = 0; i < N; i++){target[i] = source[i];}}//vector<Node> vec_node;
//函数功能:深度优先搜索
//函数参数:初始状态数组,源状态哈希索引,目标状态哈希索引
//函数返回:搜索步数(空格移动次数)
int dfs(int array_source[N], int source_Hash, int target_Hash)
{if (source_Hash == target_Hash)  //消除同一状态return 0;set<int> setHash;stack<vector<Node>> stack_Open;  //Open表vector<Node> vec_Node;Node now_Status;   //当前状态Node next_Status;  //下一状态copyArray(array_source, now_Status.array);//确定状态中空格(0)的位置int pos = 0;for (int i = 0; i < N; i++){if (array_source[i] == 0)break;pos++;}//初始化当前状态结构体now_Status.hash = source_Hash;now_Status.pos = pos;now_Status.step = 0;next_Status.step = 0;//把当前结点放入Open表中vec_Node.push_back(now_Status);stack_Open.push(vec_Node);setHash.insert(now_Status.hash);//Open表不为空则继续搜索while (!stack_Open.empty()){//从Open表中删除第一个状态printf("%s\n","进入while循环" );vec_Node = stack_Open.top();stack_Open.pop();cout<<vec_Node.size()<<endl;now_Status = vec_Node[vec_Node.size()-1];printf("%s\n", "printArray(now_Status.array);");printArray(now_Status.array);// printf("%s\n","vec_Node[i]");//  for(int i = 0; i < vec_Node.size(); i++)//     {//         printArray(vec_Node[i].array);//     }       //对Open表中的每一个状态判断空格右、下、上、左移动for (int i = 0; i < 4; i++){int offsetX = 0, offsetY = 0;//固定某一坐标,移动另一坐标offsetX = (now_Status.pos % 3 + zero_move[i][0]);offsetY = (now_Status.pos / 3 + zero_move[i][1]);//边界判断通过后空格进行移动if (offsetX >= 0 && offsetX < 3 && offsetY < 3 && offsetY >= 0){copyArray(now_Status.array, next_Status.array);//空格移动复制next_Status.step = now_Status.step;next_Status.step++;swap(next_Status.array, now_Status.pos, offsetY * 3 + offsetX);//移动后的状态哈希索引及空格位置next_Status.hash = cantor(next_Status.array);next_Status.pos = (offsetY * 3 + offsetX);int begin = setHash.size();setHash.insert(next_Status.hash);int end = setHash.size();vec_Node.push_back(next_Status);if (next_Status.hash == target_Hash){       for(int i = 0; i < vec_Node.size(); i++){printArray(vec_Node[i].array);}        printf("%ld\n",  vec_Node.size());return next_Status.step;}if (end > begin and next_Status.step <50){stack_Open.push(vec_Node);}vec_Node.pop_back();}}}return -1;
}//函数功能:求逆序数
//函数参数:表示状态的数字序列
int inversion(int array[N])
{int sum = 0;for (int i = 0; i < N; ++i){for (int j = i + 1; j < N; ++j){if (array[j] < array[i] && array[j] != 0)  //不与0比较{sum++;}}}return sum;}//主程序入口
int main()
{string str_source;   //源状态字符串string str_target;   //目标状态字符串// cout << "请输入初始状态序列:";// cin >> str_source;// cout << endl;// cout << "请输入目标状态序列:";// cin >> str_target;// cout << endl;str_source = "132405678";str_target = "123804765";//源int数组和目标int数组int array_source[N];int array_target[N];for (int i = 0; i < 9; i++){if (str_source.at(i) >= '0' && str_source.at(i) <= '8'){array_source[i] = str_source.at(i) - '0';}else{array_source[i] = 0;}if (str_target.at(i) >= '0' && str_target.at(i) <= '8'){array_target[i] = str_target.at(i) - '0';}else{array_target[i] = 0;}}//源状态哈希和目标状态哈希int sHash, tHash;sHash = cantor(array_source);tHash = cantor(array_target);// printf(" %d,%d\n",sHash,tHash);// printArray(array_source);// printArray(array_source);//求初始状态和目标状态的逆序数int inver_source = inversion(array_source);int inver_target = inversion(array_target);//具有同奇或同偶排列的八数码才能移动可达,否则不可达if ((inver_source + inver_target) % 2 == 0){int step = dfs(array_source, sHash, tHash);cout << "从初始状态到目标状态空格0的最小移动步数为:"<<step << endl; //输出步数     }else{cout << "无法从初始状态到达目标状态!" << endl;}return 0;
}

深度优先搜索解决八数码问题相关推荐

  1. 深度优先搜索解决八数码难题

    八数码问题 以前用java写的通过深度优先瘦素解决八数码难题. 对于八数码难题来说,可以把9宫格看成一个[3][3]的二维数组,将空格位置看成0,将0可以移动的方向看成树的枝丫,分为上下左右4个方向. ...

  2. 机器学习之基于A*搜索解决八数码问题15数码问题

    针对hdu1043,来说一下A* 搜索.这道题不一定用A* 算法,还可以用双向bfs.但是A*搜索更快,在人工智能方面应用也很广泛. A* 搜索不是像深度优先搜索算法和广度优先搜索算法一样的傻瓜式的埋 ...

  3. 有界深度优先搜索算法解决八数码问题

    <人工智能导论>(第四版) 课后题5.3 C++实现 题目: 运行结果: C++代码: 思想:Octal结构体表示一个状态,其中parent和current为父状态和当前状态的值,这个值可 ...

  4. 题目2:隐式图的搜索问题(A*算法解决八数码)

    数据结构课程实践系列 题目1:学生成绩档案管理系统(实验准备) 题目2:隐式图的搜索问题(A*算法解决八数码) 题目3:文本文件单词的检索与计数(实验准备) 文章目录 数据结构课程实践系列 题目1:学 ...

  5. 宽度优先搜索算法解决八数码问题

    宽度优先搜索算法解决八数码问题 原理 1.宽度优先搜索是指在一个搜索树中,搜索以同层邻近节点依次扩展节点.这种搜索是逐层进行的,在对下一层的任一节点进行搜索之前,必须搜索完本层的所有节点. 宽度优先搜 ...

  6. Python利用A*算法解决八数码问题

    资源下载地址:https://download.csdn.net/download/sheziqiong/86790565 资源下载地址:https://download.csdn.net/downl ...

  7. A*算法解决八数码问题 Java语言实现

    A*算法解决八数码问题 Java语言实现 参考文章: (1)A*算法解决八数码问题 Java语言实现 (2)https://www.cnblogs.com/beilin/p/5981483.html ...

  8. python---A*搜索算法解决八数码问题

    A*解决八数码问题 问题内容 算法流程 相关设置 具体程序 运行结果 遇到的问题 完结 问题内容 [八数码问题] 在一个3×3的九宫中有1-8这8个数字以及一个空格随机摆放在其中的格子里.将该九宫格调 ...

  9. Nilsson's sequence score算法解决八数码问题解释

    解决了最近一个人工智能关于解决八数码难题的作业. 图可能看不清,除了黑块外其他位置是英文字母ABCDEFGH A*:f(n)=g(n)+h(n) 其中f为总花费,g为已知花费(深度),h为估计花费 关 ...

最新文章

  1. 【设计模式】中介者模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )
  2. 关于mysql 优化的日常记录
  3. 使用 vue-qrcode 生成二维码
  4. recv函数阻塞_socket缓冲区以及阻塞模式详解
  5. 邢波老师致广大学员的一封信(2010-10-26)
  6. ningx访问日志切割
  7. 【U+】通用财务,附加数据库后,软件看不到账套。
  8. SqlServer NBU备份出现错误代码2
  9. 15软件班安卓课程实训总结
  10. pacman 查询_pacman (简体中文)
  11. windows安装exe为系统服务
  12. 口袋的天空(洛谷 P1195)
  13. 基于JavaEE的健身房管理系统的设计
  14. lol祖安服务器维护,触目惊心 被演员与代练所“支配”的英雄联盟
  15. “二选一”突袭,暗战“山姆”?
  16. java实现OCR图文识别Tess4j,高准确率高效率
  17. 关于条件编译和预编译的一点学习心得
  18. 使用Docker搭建自己的在线密码管理器软件-Bitwarden
  19. Hive--窗口函数
  20. 可信认证之九阴真经二

热门文章

  1. 学习在不断进行中……
  2. 基于Spring 4.0 的 Web Socket 聊天室/游戏服务端简单架构
  3. Neusoft——智能网联无线通信技术
  4. 更改西门子PLC的IP地址
  5. 仿头条新闻资讯dz模板 Discuz新闻资讯商业版GBK模板源码
  6. C#上位机 串口上位机Modbus协议
  7. Asp.net 处理程序(第五篇)
  8. Latex之图片排版
  9. K_A07_005 基于 STM32等单片机驱动 DRV8833 模块按键控制步进电机正反转
  10. cesium 实战记录(六)地图通用工具方法的封装