八数码问题是一个经典的搜索问题,本文将介绍如何使用启发式搜索—— AStar 算法来求解八数码问题。

问题描述

八数码问题的A星搜索算法实现

要求:设计估价函数,并采用c或python编程实现,以八数码为例演示A星算法的搜索过程,争取做到直观、清晰地演示算法,代码要适当加注释。

八数码难题:在3×3方格棋盘上,分别放置了标有数字1,2,3,4,5,6,7,8的八张牌,初始状态S0可自己随机设定,使用的操作有:空格上移,空格左移,空格右移,空格下移。试采用A*算法编一程序实现这一搜索过程。

算法描述

预估值的设计

A* 算法的花费为 f(n) = g(n) + h(n),其中 g(n) 为搜索深度,定义为状态单元 state 的成员变量,在每次生成子节点时将其加一。h(n) 为不对位的将牌数,将该部分的计算重载于 state 的小于运算符中,并将 f(n) = g(n) + h(n) 的值作为状态单元的比较值。

数据结构设计

  • 每个状态用一个结构体表示,其中 depth 为状态深度,str 为该状态字符串,并重载小于运算符用于计算最优。
  • open 表使用优先队列 priority_queue,实现在 O(logn) 的时间复杂度内获取最优值。
  • close 表使用哈希集合 unordered_set,实现在 O(1) 时间复杂度内判断某状态是否已位于 close 表中。
  • 而为了得到最优搜索路径,还需要将每个状态的前驱加以保存,前驱表 pre 我使用了哈希表 unordered_map,模板类型为 pair<string, string>,表示 key 的前驱为 value。

代码

#include<iostream>
#include<string>
#include<vector>
#include<queue>
#include<unordered_map>
#include<unordered_set>
#include<stack>
using namespace std;class Solution {private:static string targetStr;const vector<vector<int>> dirs = { {-1,0},{1,0},{0,-1},{0,1} }; // 四个移动方向struct state{string str;int depth;state(string s, int d) : str(s), depth(d) {}bool operator < (const state& s) const {int cnt1 = 0, cnt2 = 0;for (int i = 0; i < 9; ++i) {if (s.str[i] != targetStr[i])++cnt1;if (this->str[i] != targetStr[i])++cnt2;}return cnt1 + this->depth < cnt2 + s.depth; // f(n) = g(n) + h(n)            }};inline void swapChr(string& child, int iniInd, int childInd) { // 交换字符,完成移动child[iniInd] = child[childInd];child[childInd] = '0';}void printPath(unordered_map<string, string>& pre, string path) { // 输出路径stack<string> st;while (path != "None") {st.emplace(path);path = pre[path];}int cnt = 0;while (++cnt && !st.empty()) {string str = st.top();st.pop();cout << "step" << cnt << ":  " << str.substr(0, 3) << endl<< "        " << str.substr(3, 3) << endl << "        " <<str.substr(6, 3) << endl << string(15, '-') << endl;}}
public:void eightDigitalQues(const string& ini, const string& target) {targetStr = target;priority_queue<state> open;unordered_set<string> close;unordered_map<string, string> pre;open.emplace(ini, 0);pre[ini] = "None";while (!open.empty()) {string n = open.top().str;int d = open.top().depth;open.pop();close.emplace(n);if (n == target) {break;}int iniInd = n.find('0');int x = iniInd / 3, y = iniInd % 3;for (const auto& dir : dirs) { // 尝试选择四个方向int nx = x + dir[0], ny = y + dir[1];if (nx >= 0 && nx <= 2 && ny >= 0 && ny <= 2) { // 满足移动后下标满足条件int childInd = nx * 3 + ny;state childState(n, d + 1);swapChr(childState.str, iniInd, childInd);if (close.count(childState.str)) // 如该状态已加入close表,则跳过continue;open.emplace(childState); // 加入满足条件的子状态pre[childState.str] = n; // 更新前驱}}}printPath(pre, target); // 输出流程return;}
};
string Solution::targetStr;
int main() {Solution S;string ini, target;cin >> ini >> target;S.eightDigitalQues(ini, target);cin.get();
}

运行结果

输入

原状态:283164705, 目标状态:123804765

输出

使用AStar算法解决八数码问题相关推荐

  1. Astar、A星算法解决八数码问题--python实现

    一.问题描述 数码问题又称9宫问题,与游戏"华容道"类似.意在给定的3*3棋格的8个格子内分别放一个符号,符号之间互不相同,余下的一格为空格.并且通常把8个符号在棋格上的排列顺序称 ...

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

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

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

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

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

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

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

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

  6. 全局择优搜索、A*算法、宽度优先算法解决八数码问题

    1问题描述 使用盲目搜索中的宽度优先搜索算法或者使用启发式搜索中的全局择优搜索或A算法,对任意的八数码问题给出求解结果.例如:对于如下具体的八数码问题: 通过设计启发函数,编程实现求解过程,如果问题有 ...

  7. A*算法解决八数码问题 人工智能原理实验报告 启发式搜索 python

    目录 一.实验主要步骤 ①.设计界面输入规则 ②.判断是否有解 ③.求解 二.实验结果展示 三.附录 完整实验程序代码: 一.实验主要步骤 ①.设计界面输入规则 有且仅有9位数字代表数码和空格,从左到 ...

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

    从起点 开始,把它加入到一个由方格组成的open list(开放列表) 中,这个open list像是一个购物清单.Open list里的格子是可能会是沿途经过的,也有可能不经过.因此可以将其看成一个 ...

  9. 人工智能实现a*算法解决八数码_小白带你学回溯算法

    微信公众号:小白算法 关注可了解更多算法,并能领取免费资料.问题或建议,请公众号留言;小白算法,简单白话算法,每个人都能看懂的算法 上一期算法回顾--贪婪法:https://mp.weixin.qq. ...

  10. C++ 使用A*算法解决八数码问题

    主要过程: 通过一个当前最好状态即best矩阵,移动0或者空白的位置,上下左右生成4个方向的子结点(如果0没有越界),把子结点加入到open表中,当前的best加入到closed表.然后在open表中 ...

最新文章

  1. 数据蒋堂 | 大清单报表应当怎么做?
  2. Tensorflow-gpu安装
  3. android 创建虚拟内存,在 Android 的 /data 目录下添加虚拟内存
  4. 比select2 更好用的chosen插件 for angular
  5. java lang保_java.lang.Object的受保护方法如何保护子类?
  6. 51 NOD 1238 最小公倍数之和 V3
  7. matlab subplot同时显示多幅图像
  8. 天文学中常用的坐标系
  9. p图软件pⅰc_惊爆软件:王者荣耀P图大神,助力少年国服梦
  10. php parse url ctf,【SSRF】如何绕过filter_var(), preg_match() 和 parse_url()
  11. MinIO Client完全指南 ​​​​​​​
  12. XSLT的处理模型(1)
  13. 2015.12.21 内存管理(memory management)
  14. RedisRepository封装—Redis发布订阅以及StackExchange.Redis中的使用
  15. 2017onsite比赛游记帖
  16. Python语言程序设计前言
  17. 青龙扩展--九章头条
  18. cjz格式文件打开方式_鹏业四川CJZ整体解决方案
  19. 岩土工程、颗粒流计算软件PFC6.0疫情传播案例——生化危机、病毒传播感染、古尔丹大战霜狼氏族
  20. Openmeetings开源视频部署

热门文章

  1. 20181225面试
  2. docker阿里云镜像加速器
  3. 谷歌翻译突然用不了了
  4. 思科命令大全_【汇总】思科网络设备产品型号大全!超全解释~
  5. QT creator安装教程
  6. MAX DotNet 透明界面效果代码实例 转自CG++原帖
  7. java简历项目经验大全,不吃透都对不起自己
  8. Thor HTTP 抓包嗅探分析接口调试网络协议
  9. app抓包工具_【旧版IPA抓包教程2】超便捷苹果旧版本APP抓包/轻松抓取你想要的版本,旧版app任意下载...
  10. 企业全面运营管理沙盘模拟心得_企业运营沙盘模拟心得体会