推箱子避免重复推的算法

Haven 2011-05-30 04:52:40
近来无聊,写了个小程序解推箱子的方法。思路很直接,就是从小人儿开始上下左右分别试,如果推得动,则叠代继续,直到成功,打印路径。现在写了七八百行,解决了简单的推法。但我试了一下比较复杂的情况,发现很久没出来,Debug一看,仅一个不是正规的路就试了几万次叠代。为什么呢?我仔细想了想,发现了一个核心的问题。

我用打标志的方法,记录轨迹,确保了小人儿在不推箱子的情况下,不会走回头路。但更大的问题是,把箱子推过来,推过去,怎么识别或避免。一个箱子的情况好办,相邻两次方向相反且人可归位就是重复,但如果是多个箱子的时候,就太难识别了。举个例子,推一下A,再推一下B,回头把A推回原来的位置,再去推一下C,再把B推到原来C的地方,再把C推B原来的位置。如果此刻人可以回到原位置,那就等于没推。当然还有更为复杂的状态重复。

空格越多,箱子越多,越容易出现重复,程序在这时候就跳不出来。我想到最为直接的方法,设定一个数组,每条记录记载一个没有重复过的状态,并同时要记录一个人可能到达的区域(应该也是一个数组)。后面的过程,只要与前面状态重复就认为无意义,不去尝试,或记为死路都行。但这样做,一想就知道需要很多资源。我用的是9*9的数组记录状态,那就意味着一个状态需要横坐标、纵坐标、状态三个数字,再乘以81个格子,即243个字符,再加上人能到达的区域,就是五六百字符记录一个状态。如果有一千个状态,就是几百兆的资源。另外,每一次比对也是很费事的。

暂还没有想出更好的办法,请各位帮忙想想,有什么好算法。
...全文
134 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
Haven 2011-05-31
  • 打赏
  • 举报
回复
“如,8个箱子,就需要18个数字” 更正为 “如,8个箱子,就需要16个数字”
Haven 2011-05-31
  • 打赏
  • 举报
回复
有了一个相对好一点的方法。因为目标位置不会变,墙也不会变,会变的只是人和箱子。因此箱子状态只需要记下箱子坐标即可。如,8个箱子,就需要18个数字(按指定规则排列)即可表示状态。人的可达区域也只记坐标,如果有10个格子可达,则只需要20个数字(按指定规则排列),这样一个完整状态只需要几十个数字,比原来应该小于十分之一。
Haven 2011-05-31
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 cfvmario 的回复:]
用hash吧,想办法把你说的那些状态信息映射到一个hash数
[/Quote]
哈希与数组是同样的问题,不是实现不了,是存储需要资源太多,而且比较效率也太低。当然,这同时也是最容易想到的最直接的办法,但效果并不好。
还是感谢你的参与。
acdbxzyw 2011-05-31
  • 打赏
  • 举报
回复
要记录中间状态挺难的。
简单的搜索已经不行了,可以考虑A*等算法。。。
cfvmario 2011-05-30
  • 打赏
  • 举报
回复
用hash吧,想办法把你说的那些状态信息映射到一个hash数

33,010

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧