华容道问题求解_详细设计(四)之查找算法2_BFS

news2025/6/21 4:13:22

(续上篇)
利用BFS查找,会找到最短路径(没有权重的图),这个道理比较简单,这是由于寻找路径的方法都是从起点或者接近起点的位置开始的。查找过程如果画出图来,类似于一圈圈的放大,你可以想想是一个类似圆的渐开线的扫描过程。
前文已经谈到,这个BFS和DFS的主要不同就是对当前参数的保存方法不同,即BFS采用队列保存,DFS采用堆栈保存。因此,将DFS的保存当前参数的方法改成队列就可以实现BFS了。

BFS 核心代码

       internal bool SearchPathBFS(int endHashCode)
       {
           
           if (statesObjQueue.Count == 0) return false;
           //##############################################################
           //## BFS 代码的改变如下                                        ##
           //##############################################################
           var lastState = DequeueState(); 
           //var lastHashCode=   layoutHashCodeStk.Pop();

           // map it to the current  state 
           MapToCurState(lastState);
           var curBestSteps = lastState.bestSteps+1;
           while (gameState.openPieces.Count > 0 && gameState.curOpenIdx < gameState.openPieces.Count)// There are open pieces not moved , move them one by one.
           {
               var selOpenPcs = gameState.openPieces[gameState.curOpenIdx];
               var selPcs = selOpenPcs.piece;
               var toPcs = selOpenPcs.MoveToPcs;
              var dirFrom = MoveToPcs(selPcs, toPcs);
               gameState.selPcs = selPcs;
               var redundant = RedundantState(gameState);
               StateShot stateShot = new StateShot(gameState, 0);
               // record the current best steps 
               stateShot.bestSteps = curBestSteps;
               //Create the graph data structure 
               AddEdgeToGraph(lastState, stateShot);
          if (gameState.curOpenIdx < lastState.openPcsArr.Length)
               {
                  gameState.curOpenIdx++;
                   lastState.lastOpenIdx = gameState.curOpenIdx;
                }
               if (!redundant.Item1)
               {
                   SearchOpenPieces();
                   stateShot = new StateShot(gameState, 0);
                   stateShot.bestSteps = curBestSteps;
           //##############################################################
           //## BFS 代码的改变如下                                       ##
           //##############################################################         
                   EnqueueState(lastState, stateShot, selPcs, toPcs);//add edge to the grapph and enqueue the current state
               }
               // 2024-01-30 Found the least steps with BFS and it runs very fast.
               // Judge if it succeeds that caocao is at the exit of the board.
               if (endHashCode==0 && selPcs.type == 4)
               {
                   if (selPcs.hrdPos.X == 2 && selPcs.hrdPos.Y == 4)
                   {
                       RefreshLayout();
                       Application.DoEvents();
                       var verTex = GetMyHashCodeV1(gameState);
                       // the layout might not the same that needs to record all of them 
                       if (!endVtxLst.Contains(verTex)) endVtxLst.Add(verTex);
                       //MessageBox.Show(string.Format("Success! The best steps is {0},the hash code is {1}", hCodeAndShotShortPathDict[verTex].Item2, verTex));
                       //return false;//debug
                  }
               }else if (redundant.Item2 == endHashCode)
               {
                   RefreshLayout();
                   Application.DoEvents();
                   var verTex = GetMyHashCodeV1(gameState);
                   // the layout might not the same that needs to record all of them 
                   if (!endVtxLst.Contains(verTex)) endVtxLst.Add(verTex);
                   }
               MapToCurState(lastState); // back the last state and try to moev next open pieces
            
           }
          return true;
       }

和DFS的代码对比一下就会发现,除了堆栈改成队列之外,代码几乎没有做什么改变。

下面给出 两个主要变化的函数代码
入队代码:

       private void EnqueueState(StateShot source, StateShot dest, Piece selPcs, Piece dstPcs)
       {
           statesObjQueue.Enqueue(dest);
           var toHashCode = GetMyHashCode(dest);

           stateHashCodeLst.Add(toHashCode);

           int[,] layoutArr = new int[6, 7];

           Array.Copy(dest.layoutOfIdx, layoutArr, layoutArr.Length);
           hCodeAndShotDict.Add(toHashCode, (dest.basePcs, selPcs.idx, dstPcs.idx));
           var frmHashCode = GetMyHashCode(source);
           AddEdge(frmHashCode, toHashCode, 1);
       }

出队代码

       private StateShot DequeueState()
       {
           var stshot = statesObjQueue.Dequeue();
          
           //stateHashCodeStack.Pop();
           return stshot;
       }

其中 statesObjQueue 的定义为;

//used to store the game state and the shortest path from last state For BFS search 
       private Queue<StateShot> statesObjQueue= new Queue<StateShot>();

运行之后,就很快找到了最少步数,虽然在过程当中也构建了一个图,但是并没有使用这个图。

结果也比较理想,是一个对称的结果,符合预期。这个原因,我想是因为在BFS 的求解过程当中的每一次探索的步数的基数都是一样的,而路径是不同的,因此也就必然会出现这么一种结果。
运行结果获得30种符合要求的布局,根据对称性,应该是15 中不同的解法。
截图如下:
说明:左面列表数值是该布局对应的Hash值
在这里插入图片描述
在这里插入图片描述
对比上面的布局,发现这是个对称的布局。这些解法中,最少的是81步,最多的是 115步。
其余结果请参考下列视频。另外 “不同解法 ”的含义就是最终的布局不同。

横刀立马最佳结果集


基本功能的探索到此告一段落,后面将对显示和布局设计进行一些尝试。

marasun BJFWDQ
204-03-09

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

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

相关文章

C++初阶:类与对象(中篇)

目录 2. 类的六个默认成员函数2.1 构造函数2.1.1 构造函数的定义方式 2.2 析构函数2.2.1 析构函数定义方式 2.3拷贝构造函数2.3.1 拷贝构造函数的定义方式2.3.2 深拷贝与浅拷贝 2.4 赋值运算符的重载2.4.1 运算符重载2.4.2 运算符的重载的定义方式2.4.3 默认成员函数&#xff1…

Redis 常见数据类型(对象类型)和应用案列

前言: 每次你在游戏中看到玩家排行榜&#xff0c;或者在音乐应用中浏览热门歌单&#xff0c;有没有想过这个排行榜是如何做到实时更新的&#xff1f;当然&#xff0c;依靠 Redis 即可做到。 在技术领域&#xff0c;我们经常听到「键值存储」 这个词。但在 Redis 的世界里&…

VBA技术资料MF128:批量创建文件夹及子文件夹

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套&#xff0c;分为初级、中级、高级三大部分&#xff0c;教程是对VBA的系统讲解&#…

低密度奇偶校验码LDPC(十)——LDPC码的密度进化

一、密度进化的概念 二、规则LDPC码的密度进化算法(SPA算法) 算法变量表 VN更新的密度进化 CN更新的密度进化 算法总结 程序仿真 参考文献 [1] 白宝明 孙韶辉 王加庆. 5G 移动通信中的信道编码[M]. 北京: 电子工业出版社, 2018. [2] William E. Ryan, Shu Lin. Channel Co…

【C语言】linux内核ip_local_out函数

一、讲解 这个函数 __ip_local_out 是 Linux 内核网络子系统中的函数&#xff0c;部分与本地出口的 IPv4 数据包发送相关。下面讲解这段代码的每一部分&#xff1a; 1. 函数声明 int __ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb)&#xff1a; -…

AcWing 1262. 鱼塘钓鱼(每日一题)

目录 暴力枚举法&#xff1a; 贪心&#xff1a; 原题链接&#xff1a;1262. 鱼塘钓鱼 - AcWing题库 有 N个鱼塘排成一排&#xff0c;每个鱼塘中有一定数量的鱼&#xff0c;例如&#xff1a;N5 时&#xff0c;如下表&#xff1a; 鱼塘编号12345第1分钟能钓到的鱼的数量&…

k8s-生产级的k8s高可用(2) 25

部署containerd k8s2、k8s3、k8s4在配置前需要重置节点&#xff08;reset&#xff09;在上一章已完成 禁用所有节点docker和cri-docker服务 所有节点清除iptables规则 重置后全部节点重启 由于之前部署过docker&#xff0c;因此containerd默认已安装 修改配置 启动containe…

专业140+总分430+西南交通大学924信号与系统考研经验电子信息与通信工程,真题,大纲,参考书

今年报考西南交通大学&#xff0c;考研分数专业课924信号与系统140&#xff0c;总分430&#xff0c;各门分数都还是比较均衡&#xff0c;经过一年的复习&#xff0c;有得有失&#xff0c;总结一下自己的复习经历&#xff0c;希望给大家有点帮助&#xff0c;在复习中做的更好&am…

十七、IO流——综合练习

综合练习 目录 一、制造假数据1.1自己写代码1.2 利用糊涂包生成假数据 二、随机点名器2.1随机点名器12.2 随机点名器22.3 随机点名器32.4 随机点名器42.5 随机点名器5 三、登录注册3.1 登录注册13.2 登录注册23.3 登录注册3 一、制造假数据 需求&#xff1a;制造假数据也是开发…

BadUsb制作

BadUsb制作 一个树莓派pico kali监听 需要的文件 https://pan.baidu.com/s/1_kyzXIqk9JWHGHstTgq7sQ?pwd6666 1.将pico插入电脑 2.将Bad USB固件中的文件复制到pico中&#xff0c;pico会重启 3.将Bad USB目录文件复制进去&#xff08;打开Bad USB目录文件复制&#xff09; …

MySQL--explain执行计划详解

什么是执行计划&#xff1f; SQL的执行计划&#xff0c;通俗来说就是SQL的执行情况&#xff0c;一条SQL语句扫描哪些表&#xff0c;那个子查询先执行&#xff0c;是否用到了索引等等&#xff0c;只有当我们知道了这些情况之后才知道&#xff0c;才可以更好的去优化SQL&#xf…

如何将MathType嵌入到word中 word打开MathType显示错误

当我们编辑好mathtype公式以后&#xff0c;有时候需要将这个公式导入到word中&#xff0c;但是有不少用户们不清楚mathtype如何嵌入到word中。今天小编就给大家说明一下mathtype公式导入word的两种不同方法&#xff0c;有需要的用户们赶紧来看一下吧。 一、mathtype如何嵌入到…

(产品之美系列三)小红书投票组建,利用用户好奇心,增大互动

小红书发布笔记或者视频&#xff0c;可以带一个投票功能。此投票功能与其他的有什么不同呢&#xff1f; 发布一个话题:你觉得王维和李白哪个更帅&#xff1f; 如果你自己不投票&#xff0c;就是看不到结果。当你投票之后: 可以知道选择王维的有百分之八十二。 启发:小红书投…

Git分布式管理-头歌实验远程版本库

Git的一大特点就是&#xff0c;能为不同系统下的开发者提供了一个协作开发的平台。而团队如果要基于Git进行协同开发&#xff0c;就必须依赖远程版本库。远程版本库允许&#xff0c;我们将本地版本库保存在远端服务器&#xff0c;而且&#xff0c;不同的开发者也是基于远程版本…

OJ:循环队列

622. 设计循环队列 - 力扣&#xff08;LeetCode&#xff09; 思路 思路&#xff1a;首先循环队列的意思是&#xff1a;空间固定&#xff0c;就是提前开辟好&#xff0c;满了就不能插入了&#xff0c;但是删除数据后仍有空间&#xff0c;删除循环队列里面的数据后&#xff0c;保…

Python学习日记之学习turtle库(上 篇)

一、初步认识turtle库 turtle 库是 Python 语言中一个很流行的绘制图像的函数库&#xff0c;想象一个小乌龟&#xff0c;在一个横 轴为 x、纵轴为 y 的坐标系原点&#xff0c;(0,0)位置开始&#xff0c;它根据一组函数指令的控制&#xff0c;在这个平面 坐标系中移动&#xff0…

如果编程语言是一种武器……

对程序员来说&#xff0c;编程语言就是武器&#xff0c;但有的武器好用&#xff0c;有的武器不好用&#xff0c;有的武器甚至会杀了自己 C语言是M1式加兰德步枪&#xff0c;很老但可靠。 C是双截棍&#xff0c;挥舞起来很强悍&#xff0c;很吸引人&#xff0c;但需要你多年的磨…

Ubuntu平铺左、右、上、下、1/2、1/4窗口(脚本)

前言 之前因为一直在用Ubuntu 18或者Ubuntu 20然后发现装了GNOME插件后&#xff0c;电脑在使用过程中&#xff0c;会时不时的卡死&#xff08;鼠标没问题&#xff0c;键盘输入会有10-20秒的延迟&#xff09;频率基本是一小时一次&#xff0c;因为这种卡顿会很容易打断思路&…

攻防世界-MISC-EASY_EVM

题目链接&#xff1a;攻防世界 (xctf.org.cn) 下载附件得到info.txt&#xff1a; pragma solidity ^0.5.0; ABI: [ { "inputs": [], "payable": true, "stateMutability": "payable", "type": "constructor" }, {…

基于单片机的RFID门禁系统设计

目 录 摘 要 I Abstract II 引 言 1 1 控制系统设计 3 1.1 主控制器选择 3 1.2 项目总体设计 3 2 项目硬件设计 5 2.1 单片机控制模块 5 2.2 射频识别模块 8 2.3 矩阵键盘模块 9 2.4 液晶显示模块 10 2.5 报警模块 11 2.6 AT24C02存储模块 12 2.7 继电器驱动模块 13 2.8 总电路…