使用VB求解华容道问题

问题

1、问题的提出
1.1“华容道”简介
“华容道”是一种中国古代的智力游戏玩具,在一个宽为4,长为5的矩形框中,有10个棋子,包括一个曹操,五虎上将,四个小卒,要求在各个棋子不重叠的情况下进行移动,最有将曹操从棋盘上方移动到下边中央为成功。由于五员大将可以横放也可以竖放,有许多种排列方法,因而可以形成非常复杂的棋局,人们还给常用的棋局起了很多好听的名字,例如下图就是“横刀立马”的布局图。

图1.1 “横刀立马”的布局

关于此问题的求解方法,现在已经有许多文章详细描述,本文不再一一描述,专门针对“广度优先算法”方式解题进行讨论。
1.2广度优先算法的讨论
我们知道,对于类似于“华容道”的问题,例如迷宫问题等,都可以归结为图论中图的遍历和最短路径问题。也就是说,从某一个具体状态开始作为图的起点,每走出任意一步以后得到的状态作为这个节点的延伸,只要保证每次走出的状态不和原来已经走过的状态相重复,那么就可以遍历所有由此原始状态可能到达的所有状态,从而形成一张完整的倒立放置的树图,如下图所示意。

图1.2 状态转化示意图

针对“华容道”问题,其实质在于如何快速构建这样一张状态树图,在数据量未知的情况下,保证快速找到最终的结果。要做到这一点,有许多算法,广度优先是其中比较流行的一种算法。其具体思路是:
由起点出发,先构建第一层的节点,然后依次构建第二层,第三层节点,在构建的过程中,为了保证数据不重复出现,需要对每一个新节点都和原来已经生成的所有节点进行比较,保证其不重复出现在图中。
问题则由此而产生,由于在每次增加新节点时,都需要和原来所有的节点进行比较以保证此节点不重复出现,随着节点数量的增加,每次需要进行的比较也不断增加,这样就需要进行大量的时间用于比较状态是否重复,从而形成算法效率的一个瓶颈。这也是有人认为广度优先算法效率低下的一个重要原因。
下面将讨论如何优化广度优先算法以提高效率。
2、广度优先算法的优化
我们现在假设已经找到了一条从起始点状态到最终结果状态的一条最短路径,那么我们显然可以得到如下的推论:
从起始点到此最短路径上的每一个具体状态,所走的路径都是针对此节点状态的最短路径。
也就是说,我们要找到从起点到终点的最短路径,只能够通过行走每个节点的最短路径来得到。
我们现在给图中的每一个节点,都标示上其对应的最短路径步数,形成如同下图的一张带有路径步数的节点状态树图。

图2.1 带有最短路径步数的状态树图

结合上图,我们可以很容易得到如下的结论:

在最短路径树图中,与任何级别为n的节点相连的节点,其级别必然在[n-1,n+1]之间。(结论1)

那么,从一个级别为n的节点出发,得到的所有节点,其级别也只能在(n-1,n+1)之间。因此,得到如下的结论:

要判断从一个原始级别为n的节点产生的节点是否在图中已经存在,仅需要判断图中[n-1,n+1]级别的节点集合中是否有此节点即可,如果没有,那么此节点就是新节点。(结论2)

请注意上面所描述的结论2,根据结论2,在对于新产生节点是否重复的判断问题上,仅需要由本级节点上溯到上二极即可,而不需要一直上溯到最开始的节点。

这样,通过缩小对于新产生节点是否存在的判断范围,我们达到了对于广度优先算法的优化目的。

3、结论

在广度优先算法的搜索过程中,如果按照最短路径的规则进行搜索,那么对于每次搜索产生的新节点状态,只需要在其上两层进行回溯判断,就可以判断新节点状态是否重复,从而达到快速搜索的目的。这种对于广度优先算法的优化同样可以用于其它类似问题的求解,例如“八皇后问题”,迷宫行走问题,最短交通路线问题等等。

时间: 2024-09-19 09:47:48

使用VB求解华容道问题的相关文章

利用VB解决华容道问题的源代码

解决|问题|源代码 全局变量定义 Type HRDState '华容道的棋局表示state(1 To 12) As Long '棋盘上的12个棋子的当前位置Superid As Long '上一步棋盘的位置编号,0代表无上一步Level As Long '这一不棋局的级别,0代表是开始状态End TypePublic G_Next As CHRDNextPublic G_Save As CHRDSavePublic G_State As HRDState 应用程序启动 Sub Main()frm

循环-vb.net操作word最后一步求解

问题描述 vb.net操作word最后一步求解 If e.KeyCode = Keys.Enter Then Dim q As Integer = InputBox("请输入搜索页码的次数") If q > 0 Then Static Dim p(q) As String Dim j As Integer For j = 0 To q - 1 p(j) = InputBox("请输入关键字") Next Dim temp If p(j) = p(q) Then

vb.net怎样实现一元一次方程(线性方程)求解

问题描述 vb.net怎样实现一元一次方程(线性方程)求解,给点提示格式如-2x+7=9要编成个窗体应用程序,-2x+7为一个文本框,9为另一个,点击求解按钮在一个文本框得出答案 解决方案 解决方案二:可以用正则表达式将x前面和后面的数值提取出来,后面怎么处理就好办了解决方案三:首先你要进行表达式解析通常是用堆栈方式,得到操作数栈{-2,x,7}注:右侧为栈顶操作符栈{*,+}然后把栈转化为二叉树(+,True){注:True/False表示是否含有x(7,False){}(*,True){(x

vb进制转换-VBHEX转BIN时的一些问题,求解。

问题描述 VBHEX转BIN时的一些问题,求解. 书中有一些代码我不能理解,也许跟HEX转BIN的理论知识有关 While left(B,1)="0" B=Right(B,Len(b)-1) Wend HEX_TO_BIN=B 它的意思是当B的第一个字符为0时,返回长度减1的B.但为什么要写这些?是不是如果在HEX转BIN时,第一个位为0,就必须减去最后一位?代码我能理解,就是不理解为什么要写这些.

vb.net生成的setup文件,在win7上必须要兼容模式打开.求解.

问题描述 本人在练习做了一个c/s应用程序,在制作了setup文件后,在xp上安装都运行正常,可是在win7下32和64位下都出现程序无法打开,必须用兼容模式打开才可以运行,是不是我在制作setup文件的时候需要特殊要求呢?希望有做个的朋友帮帮忙.谢谢了! 解决方案 解决方案二:求帮忙,谢谢了...解决方案三:顶顶,有做过的朋友帮帮忙.谢谢了!解决方案四:111

控件-大神求解! 表情显示怎么实现啊!

问题描述 大神求解! 表情显示怎么实现啊! 大神求解! 表情显示怎么实现啊!需要什么控件???求方法!谢谢了 解决方案 什么语言也没说.如果是C# VB,用richtextbox,如果是web,用各种编辑器,比如fkcedit等. 解决方案二: 类似http://blog.csdn.net/xianfajushi/article/details/4763800 解决方案三: http://blog.csdn.net/baidu_33396702/article/details/50349861

矩阵-vb.net进行线性代数运算

问题描述 vb.net进行线性代数运算 我编的程序需要进行一次线性方程组求解,AX=B.程序已经算出A和B了.都是vb.net本身的数组表示的,大小随用户输入的参数有变化.之前下了ILNumerics,但是不会用.貌似需要AB都是它的格式的矩阵才能计算.可是教程看不懂(http://ilnumerics.net/index.html , 官网链接点进去,选support-documention,就是教程了), 全英文,而且教程里的矩阵都是手动输入的.有没有谁会在vb.net里解线性方程组的,教一

vb.net(basler相机SDK抓取图像数据流后,将图片显示在picturebox中)

问题描述 vb.net(basler相机SDK抓取图像数据流后,将图片显示在picturebox中) vs2012,vb.net编程,basler相机的sdk取像得到数据流后basler有自己的方法显示图片,但我不要中他的方法,我要显示在自己的picturebox控件中,自己写了一段程序,如图,102行一直提示说参数无效,求解! 解决方案 图太小了,看不见.你可以先保存为bmp 用picturebox1.Image = Image.FromFile(文件)

vb6-VB中long型转Bytes型代码求解

问题描述 VB中long型转Bytes型代码求解 请问下面这段代码怎么分析啊?看了半天没看懂!Bytes = (Number And &H7F000000) &H1000000 Or (((Number And &H80000000) <> 0) And &H80) 解决方案 vb中long是32位,如果2进制表示就是4个字节(1111 1111),H7F000000二进制是01111111 00000000 00000000 00000000 ,为了防止溢出,