类似华容道一类搜索中,状态的Hash方法(转)

本文探讨了在解决华容道类游戏中,如何有效地实现状态转移和状态判重。通过位压缩和棋子顺序表示布局的方法,提出使用棋子形状数组和放置顺序来生成状态的Hash码,从而减少状态空间并提高搜索效率。最后,文章提出了状态数量的估算,并讨论了可能存在的优化问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

标准的华容道游戏是在一个4*5的方阵中,布有一些各种形状的棋子,当然留有若干空格.你的任务是移动棋子,并把其中的一枚棋子移动到指定的位置,如以下布局,要求把上面的A棋子移动到最下方的中间(其中一个字母为一个棋子,*表示空格):
B A A C
B A A C
D E E F
G H I J
G * * J
 
解法就是朴素的,搜!
 
搜索有两个难点,一个是状态转移,一个是状态判重.对于本题来说,状态转移是简单的,只用考虑与空格相邻的棋子怎么运动就行了.不过注意,不能用移动空格来状态转移,因为很多时候要多个空格同时作用.
 
状态判重却要花点脑筋,自然是用Hash表,不过怎样去Hash?
 
直观的想法是,把布局图进行位压缩然后变成一个数字,不过是个很大的数字,可以吓死人.再想几秒钟就会发现刚才的想法是多么地愚蠢,因为把很多棋子拉散了的状态也考虑到了,而显然这些状态是不会出现的.
 
棋子的形状是固定的,因此可以开个数组保存每个棋子的形状.
 
然后,思考把每一个棋子左上角的坐标保存下来,不过,每一个棋子需要两个整数来记录,也不划算.其实这样也存在大量的多余状态,如A,B棋子同时在(1,1)就不可能存在.
 
我们来做一个实验,先把空格看作棋子,接着,你把一个布局中的棋子从上到下,从左到右地取出来,如上图为BACDEFGHIJkl,然后取一个空棋盘,按顺序把棋子添入其中,结果,得到一个一模一样的棋盘.
 
这启发我们用放置顺序来表示一个布局,不过仍然存在不足,因为有些棋子是一样的,如B,C,G,J.可以把他们看作一种棋子,比如都是B,然后让第一个取出的是B,第二个是C...
 
于是,如果设
##
##=A
 
#
#=B
 
##=C
 
#=D
 
空格=E
 
则上图状态的Hash码是BABDCDBDDBEE
 
而所有状态的Hash码也无非是A B B B B C D D D D E E这12个字母的不同组合而已.
 
这时,我们可以说,状态最多只有12!/(1!*4!*1!*4!*2!)种,其实还要少一些,因为以BBBA...打头的状态是不可能存在的,要解决这个我无能为力了,大家可以一起思考.
 
然后,用组合公式求得字符串的字典序号,或者看作一个5进制数,取模.前者的优点是无重复,后者的优点是速度快些.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值