BFS:八数码问题求解

八数码原题

剖析一下BFS

        BFS算法是一种图遍历算法,它从起点开始,逐层扩展搜索范围,直到找到目标节点为止。        

        BFS算法一般选择队列作为节点存储的数据结构,我们将搜索目标节点的问题抽象为寻找目标状态,那么队列存储的对象就是每一种状态。

        对于状态的含义与变化过程,BFS算法如下要求(为了讲解得更加透彻,举走迷宫问题为例):

  1. 初始以及其拓展出开的状态都要存储在队列中。在走迷宫问题中,队列q存储已走过的点 ,点代表位置状态,基于一个点可以拓展出它四周的点;
  2. 问题的求解必须有初始状态最终状态。在走迷宫问题中,起点(0,0)便是初始状态,而终点(n,n)是最终状态;
  3. 问题的状态次数是有限的已出现的状态一般需要被记录下来。在走迷宫问题中,dis[i][j]表示从起点到达点(i,j)的距离。当dis的所有元素被初始化为0时,如果dis[i][j]非零时,就说明点(i,j)已被记录过;
  4. 当前状态preState可以拓展出其他状态State,如果State已经出现过或者不符合要求,那么该状态无法加入队列中.

八数码问题的求解 

问题描述

        八数码,在3×3的方格棋盘上,摆放着1到8这八个数码,有1个方格放置字符x,其初始状态如图所示,要求对字符x执行x左移、x右移、x上移和x下移这四个操作使得棋盘从初始状态到目标状态。

        147ac6bb7d3b4fd7ab401c398919f979.png

        基于上述状态能够拓展出如下四种状态:

 

7af3caa860a84e0dbf6fdf8ee5809ba5.png

         八数码问题要求是,对字符x进行若干次唯一操作,得到目标状态并且求算操作次数: 

9ea05a3f65d745cfa077648e36522153.png

 求解思路

  1. 每一个矩阵的里面的元素能够用一个字符串来存储,例如存储最终状态string s = "12345678x";
  2. 本问题借助state结构体存储每一种状态,state的分量为:s,pos,step.其中,s代表该状态对应的字符串,pos代表x在s字符串中的位置,step代表本状态由初始转台经过了step次操作得来;
  3. 定义一个map<string,bool>st映射,记录该字符串(即新拓展出来的状态)曾经是否出现过,即已出现的状态需要被记录下来;
  4. 当前状态preState包含三个分量{s,pos,step},根据pos与s值,拓展出其他至多四种状态,具体实现将代码的genOtherState函数.

        好啦,大功告成~~👌👌👌其他细节部分见代码后,也许会有更加深刻的体会(代码有详细注释,所谓优秀的代码本身就是学习文档!!!)

代码实现

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
#include<map>
#include<queue>
using namespace std;//	come from Acwing//	记录状态
struct state {string s;int pos;	//	x的位置int step;	//	step次交换
};string str;
map<string, bool>st;	//	记录某个状态是否曾出现
queue<state>q;	//	状态队列//	产生其他状态
void genOtherState(const state& sta) {string s;state t;//	判断是否能够交换x与它上面字符的位置if (sta.pos - 3 >= 0) {//	交换两个字符的位置s = sta.s;swap(s[sta.pos], s[sta.pos - 3]);if (!st[s]) {q.push(state{ s,sta.pos - 3,sta.step + 1 });st[s] = true;}}//	判断是否能够交换x与它下面字符的位置if (sta.pos + 3 <= 8) {s = sta.s;swap(s[sta.pos], s[sta.pos + 3]);if (!st[s]) {q.push(state{ s,sta.pos + 3,sta.step + 1 });st[s] = true;}}// 判断是否能够交换x与它右边字符的位置if (sta.pos % 3<=1) {s = sta.s;swap(s[sta.pos], s[sta.pos + 1]);if (!st[s]) {q.push(state{ s,sta.pos + 1,sta.step + 1 });st[s] = true;}}// 判断是否能够交换x与它左边字符的位置if (sta.pos % 3 >= 1) {s = sta.s;swap(s[sta.pos], s[sta.pos - 1]);if (!st[s]) {q.push(state{ s,sta.pos - 1,sta.step + 1 });st[s] = true;}}
}int bfs(int pos) {string target = "12345678x";	//	目标状态// 初始化state init = state{ str,pos,0 };q.push(init);st[str] = true;while (q.size()) {auto t = q.front();	//	取出队头状态进行拓展q.pop();if (t.s == target) {return t.step;}//	当前状态拓展出其余状态genOtherState(t);}return -1;
}int main() {int cnt = 9;int pos = 0;//	输入for (int i = 0;i <= 8;i++) {char a;cin >> a;if (a == 'x') {pos = i;}str += a;}int res = bfs(pos);cout << res << endl;return 0;
}

 总结

        本博客先解释了BFS的存储队列节点的抽象含义,将每一个节点看作一种状态,并从状态存储、状态记录、状态拓展等角度解答了BFS算法如何解决遍历问题。

        紧接着,我们借助BFS算法的状态处理方法给出了八数码问题的求解思路。我们以字符串存储了八数码的每一种状态,每一种状态记录{s,pos,step}三个分量,借助st映射记录新拓展出的状态,并于代码中给出状态拓展的方法。

        实际上,八数码问题只是抽象BFS问题的一种实例化,当我们判断一个问题是否属于BFS问题时,需要判断问题是否存在初始状态与最终状态?每一种状态如何存储,有哪些分量?如何记录每一种状态?每一种状态拓展出其他状态的方式是否是规律的且有限的?掌握了如上的思考方式,相信你能够在下一次遇到或判断一个问题是否属于BFS问题时,你能够更加游刃有余!!!

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/228639.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue3 reative回显问题

1. reactive 在做项目的时候通常会遇到这种情况&#xff0c;比如我们有一个 Table 显示数据&#xff0c;添加 Table 数据的时候使用 dialog 弹出&#xff0c;在里面填写字段然后添加。 在 vue3 中&#xff0c;对于对象的响应式定义推荐使用 reactive &#xff0c;那么可以写入…

运筹学经典问题(二):最短路问题

问题描述 给定一个图&#xff08;有向图或无向图&#xff09; G ( V , E ) G (V, E) G(V,E)&#xff0c; V V V是图中点的集合&#xff0c; E E E是图中边的集合&#xff0c;图中每条边 ( i , j ) ∈ E (i, j) \in E (i,j)∈E都对应一个权重 c i j c_{ij} cij​&#xff08;…

Android取消深色适配

从Android10&#xff08;API 29&#xff09;开始&#xff0c;在原有的主题适配的基础上&#xff0c;Google开始提供了Force Dark机制&#xff0c;在系统底层直接对颜色和图片进行转换处理&#xff0c;原生支持深色模式。当系统设置深色主题背景或者进入省电模式情况下会进入深色…

2023年烟花爆竹经营单位主要负责人证模拟考试题库及烟花爆竹经营单位主要负责人理论考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年烟花爆竹经营单位主要负责人证模拟考试题库及烟花爆竹经营单位主要负责人理论考试试题是由安全生产模拟考试一点通提供&#xff0c;烟花爆竹经营单位主要负责人证模拟考试题库是根据烟花爆竹经营单位主要负责人…

RGB颜色表示法(RGBA解释) 以及常见的色调

RGB&#xff1a;代表red&#xff0c;green&#xff0c;blue。即用这三个色调表示所有颜色。 表示方式如&#xff1a;&#xff08;255,255,255&#xff09;白色、&#xff08;0,0,0&#xff09;黑色 改变三个不同的数值可以得到不同的颜色&#xff0c;数值取值范围为0-255&#…

设计模式——模板方法模式

引言 模板方法模式是一种行为设计模式&#xff0c; 它在超类中定义了一个算法的框架&#xff0c; 允许子类在不修改结构的情况下重写算法的特定步骤。 问题 假如你正在开发一款分析公司文档的数据挖掘程序。 用户需要向程序输入各种格式 &#xff08;PDF、 DOC 或 CSV&#…

Ubuntu 常用命令之 cp 命令用法介绍

cp命令在Ubuntu系统中用于复制文件或目录。它的基本格式是cp [选项] 源文件或目录 目标文件或目录。 以下是一些常用的cp命令选项 -i&#xff1a;在覆盖目标文件之前将给出提示。-r或-R&#xff1a;递归复制&#xff0c;用于目录的复制操作。-v&#xff1a;详细模式&#xff…

2023-12-12 AIGC-AI工具的基本工作原理

摘要: 2023-12-12 AIGC-AI工具的基本工作原理 AI工具的基本工作原理 AI工具的基本工作原理涉及到一系列复杂的技术和算法。这些原理可以根据不同类型的AI工具进行概括&#xff0c;包括机器学习、自然语言处理、图像识别等。以下是一些关键的AI工具及其工作原理的概述&#xff…

对于实例控制,枚举类型优先于readResolve

实例控制是指控制类实例的创建和使用过程&#xff0c;而 readResolve 方法是 Serializable 接口中的一个特殊方法&#xff0c;用于在反序列化时控制对象的实例。在一些情况下&#xff0c;使用枚举类型可以更优雅地实现实例控制&#xff0c;而不需要依赖 readResolve 方法。 下…

网络基础(十二):ACL与NAT

目录 一、ACL 1、ACL的概述 2、ACL的分类 3、ACL的应用 4、ACL的组成和基本原理 ​编辑 5、ACL的配置 5.1配置基本ACL 5.2配置高级ACL 二、NAT 1、NAT的概述 2、NAT的分类 3、NAT的工作原理 4、静态NAT的配置 5、动态NAT的配置 6、NAPT&#xff08;端口映射&am…

查询某个类是在哪个JAR的什么版本开始出现的方法

背景 我们在依赖第三方JAR时&#xff0c;同时也会间接的依赖第三方JAR引用的依赖&#xff0c;而当我们项目中某个依赖的版本与第三方JAR依赖的版本不一致时&#xff0c;可能会导致第三方JAR的在运行时无法找到某些方法或类&#xff0c;从而无法正常使用。 如我正在开发的一个…

流程引擎相关资料

最近调研流程引擎相关知识&#xff0c;BPMN规范和流程引擎相关知识无法避开&#xff0c;以及市面上比较多的流程引擎产品。 BPMN2.0 基本形状 流对象&#xff08;Flow Objects&#xff09;&#xff0c;流对象是定义业务流程的主要图形元素。它进一步细分为三个类别&#xff0…

[SUCTF 2018]MultiSQL MYSQL 预处理写

首先这道题需要预处理写马 之前在ctfshow中学习过预处理 我们来看看 CTFSHOW -SQL 注入-CSDN博客 首先我们开始判断是否存在注入 2^(if(10,1,0))2^(if(ascii(mid(user(),1,1))>0,0,1))判断出存在sql注入 然后我们开始fuzz 发现 select &#xff0c;union 都没了 但是…

Mistral MOE架构全面解析

从代码角度理解Mistral架构 Mistral架构全面解析前言Mistral 架构分析分词网络主干MixtralDecoderLayerAttentionMOEMLP 下游任务因果推理文本分类 Mistral架构全面解析 前言 Mixtral-8x7B 大型语言模型 (LLM) 是一种预训练的生成式稀疏专家混合模型。在大多数基准测试中&…

探索顺序表:数据结构中的秩序之美(c语言实现常见功能接口)

在我们的数据结构探索中&#xff0c;我们已经探讨时间复杂度、空间复杂度。大家可以移步到我的上篇文章&#xff1a; 打开数据结构大门&#xff1a;深入理解时间与空间复杂度 今天&#xff0c;我们将深入研究另一个重要的主题——顺序表 全部的源代码大家可以去我github主页…

web服务器之——www服务器的基本配置

目录 一、www简介 1、什么是www 2、www所用的协议 3、WEB服务器 4、主要数据 5、浏览器 二、 网址及HTTP简介 1、HTTP协议请求的工作流程 三、www服务器的类型(静态网站&#xff08;HTML&#xff09;&#xff0c; 动态网站(jsp python,php,perl)) 1、 仅提供…

Windows设备管理

1、前言 熟悉Windows系统的都应该使用过设备管理器。设备管理器将操作系统中所有已安装的设备分类展现出来。同时提供了安装、卸载、启用和禁用的功能。 那么&#xff0c;我们应该如何通过C编程的方式实现这种功能呢&#xff1f;答案很简单&#xff0c;那就是使用SetupDi函数族…

Lumerical 选项------superimpose structure

Lumerical 选项------superimpose structure 简介正文 简介 这里给大家介绍一下 Modal analysis 计算中的 superimpose structure 选项的作用。 正文 当我们勾选上 superimpose structure 选项时&#xff0c; 当我们取消勾选时 通过对比我们得到&#xff0c;勾选 superimp…

Windows11环境下配置深度学习环境(Pytorch)

目录 1. 下载安装Miniconda2. 新建Python3.9虚拟环境3. 下载英伟达驱动4. 安装CUDA版Pytorch5. CPU版本pytorch安装 1. 下载安装Miniconda 下载安装包&#xff1a;镜像文件地址 将Miniconda相关路径添加至系统变量的路径中。 打开Anaconda Powershell Prompt&#xff0c;输入…

计算机组成原理-指令系统CISC和RISC

文章目录 总览CISC和RISC 总览 CISC和RISC 存储程序就是用一个电路再加上存储部件构成 可访存指令不同 RISC更自由&#xff0c;因为很多函数没有固定&#xff0c;是自己写的 由于CISC各个指令执行时间不一样&#xff0c;要实现指令流水线比较困难 由于CISC可访存指令没有限制…