双向搜索法 ------推箱子算法简要分析

    本文适合各个层次的人工智能编程爱好者阅读。分析得可能有误,看下面本人写的补充评论。

    结合本人的理论学习、编程实践、网络搜索,简要总结我的推箱子算法如下:

    1,先逐个推箱子,此时认为布局中只有一个箱子。得到一个搬运工位置和一个箱子位置的所有组合状态,当然是个网状数据结构。这个网状数据结构不会很大,普通个人电脑可以容纳。用广度搜索,记录每个节点的正向层数,也就是正向距离。对于不同的初始箱子及搬运工组合状态会有不同的距离数。

    2,以单个箱子被推到终点(目标点)的数据状态为中心节点(会有很多,最多也就是箱子数*4个),进行逆向广度搜索,得到并记录各层节点到各个中心节点的距离,就是逆向层数。每个节点到不同中心节点的层数(距离)是不同的。这个距离就是推箱子算法的重要参考依据。这个数据量普通个人电脑应该可以承受。

    3,以上都是由单个的箱子情况得到的数据,现在开始要把这些箱子数据组合在一起。

    1)  由实际箱子组合起始状态向最终目标点组合状态出发,用广度搜索法,正向搜索,算法是:正向距离最小的方向。数据量应该减少很多。问题是把哪个箱子推到哪个目标点上?排列组合!都试试吧!推的过程中有可能重复,那就为减少数据量做贡献了。

    2)  由终点状态向起始状态出发,用广度搜索法,正向搜索,算法是:逆向距离最小的方向。数据量应该减少很多。终点状态的箱子排列肯定一样,只是不知道哪个箱子原来在哪?问题多了一个,搬运工应该在哪?应该不难吧,逆推应该简单多了,从单个箱子的结果里一个一个选吧。又一个排列组合.....那就再都试试吧! 推的过程中这些排列组合也有可能重复,那就又为减少数据量做贡献了。

    3)  这两个对向搜索步骤交替进行,直到这两个步骤产生的最外层状态数据集出现了交集,搜索过程完成,层数和就是最终步数。数据量应该减少很多。

    4)   预估总步数就是初始状态的总距离的2倍,因为一个搬运工是要走返程的。综合考虑让路的步数和合并的步数,就差不多了。双向搜索到初始状态的总距离后开始分析最外圈的交集,保守点的话,提前到3/4。当然这个数越接近实际距离越好。这需要对游戏布局进行分析和经验总结。这个问题以后有空再详细研究吧。

    4,总体分析:把相互交替影响的复杂过程拆解成各自独立的过程。根据数据本身逻辑取各自独立过程数据的交集,使剪枝增多,总数据量减少,这个策略可能适合推箱子这种问题的解决。

    1)   从平面几何上来说,是两个圆相交问题,分析结果就是:两个小圆的面积<一个大圆的面积

公式:2πr2   <  4πr2

    2)  从立体几何上来说是:两个小球的体积<一个大球的体积 

公式:2* (4/3)πr^3  <  8* (4/3)πr^3

    3)  推箱子问题数据量的增长比这个快很多。所以效率增加也就多。

 

    不过,真理还是要实践来检验的。第一版代码已经完成,是正向广度搜索的,在我的资源上,虽然也加了很多算法,效率果然还是不高,超过六个箱子的很慢了......。逆向搜索代码编写ing……

    还是JAVA 的.....

    但愿java的 Set 集合的搜索效率能够帮忙。否则.....

    业余程序员没有“否则”......

    那就先这样吧......!

     那些C代码......不写详细说明书,今年可能看不明白了......

                                                                                                   2013.02.17

                                                                                                   外星人2012 


这么多年了,总算有了一点进展,把图贴出来,晒一下吧。

导入关卡文件:

 

逐步分析

结果:


步骤结果(LURD)1: dLLruululuurruulDllldddRdRRurDDDrdLLLrruuuluLuuurrdLDDldRurDDDrdLLuLrruulllluRRurDldRurDDrdL

LruuluuuulDDDldRRllluuuRRurDDDrDDrdLuuulldRurDDDrdL








步骤结果(LURD)1: drrururrddlUrrdrruLLLuLrddlUlldlluRRRURldRdrruLdlUrrruuUlulLrrdrdddlllllluuUruRRlldldddrrrrrruuuluL

rdrdddlllUdrrruuululLrrdrdddlllllluuuruRRlldldddrrrrUdrruuuluLLLullDDDDuuuurrdrrrdrdddllllldlluRRRur

rddlUrrruuuluurDDDDuululllLdldddrrrrrdrruLLLrruuululllldldddrrRdrrruuuulullllulDrrrrrrddddlLrruuululllll

DDDuururrrrrddddlluLrddlUlldlluRRRRdrU

´问题描述: 码头仓库是划分为n×m个格子的矩形阵列。有公共边的格子是相邻格子。当前仓库中 有的格子是空闲的;有的格子则已经堆放了沉重的货物。由于堆放的货物很重,单凭仓库管 理员的力量是无移动的。仓库管理员有一项任务,要将一个小箱子推到指定的格子上去。 管理员可以在仓库中移动,但不能跨过已经堆放了货物的格子。管理员站在与箱子相对的空 闲格子上时,可以做一次推动,把箱子推到另一相邻的空闲格子。推箱时只能向管理员的对 面方向推。由于要推动的箱子很重,仓库管理员想尽量减少推箱子的次数。 ´编程任务: 对于给定的仓库布局,以及仓库管理员在仓库中的位置和箱子的开始位置和目标位置, 设计一个解推箱子问题的分支限界, 计算出仓库管理员将箱子从开始位置推到目标位置所 需的最少推动次数。 ´数据输入: 由文件input.txt提供输入数据。输入文件第 1 行有 2个正整数 n和 m(1<=n,m<=100) , 表示仓库是n×m个格子的矩形阵列。接下来有 n行,每行有 m个字符,表示格子的状态。 S 表示格子上放了不可移动的沉重货物; w 表示格子空闲; M 表示仓库管理员的初始位置; P 表示箱子的初始位置; K 表示箱子的目标位置。 ´结果输出: 将计算出的最少推动次数输出到文件 output.txt。如果仓库管理员无将箱子从开始位 置推到目标位置则输出“No solution!” 。 输入文件示例 输出文件示例 input.txt output.txt
评论 60
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

外星人2012

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值