我正在实现一个只有两种类型的板,并且正在寻找一个从该板映射到Long Integer(64位)的函数。我认为这不应该这么难,因为一个长整数包含比8乘8数组更多的可用信息(称之为grid [x] [y]),每个点中只有3个可能的元素,包括空元素。我尝试了以下几点:
(1)Zobrist用Longs而不是int进行散列(只是为了测试 - 我实际上并不希望它能完美地工作)
(2)将网格转换为基数为3的64字符串,然后取出该数字并将其解析为长数。我认为这应该有效,但需要很长时间
是否有一些更简单的解决方案(2)涉及转移的位操作或类似的东西?
编辑:请不要给我实际的代码,因为这是一个类项目,在我们的部门可能被认为是不道德的(或者至少不是Java)。
编辑2:基本上,在任何给定时间板上只有10个白色和10个黑色,其中在水平,垂直或对角线方向上没有两个相同颜色的相邻颜色。此外,每种颜色有12个空格,只有那种颜色可以放置。
答案 0 :(得分:2)
如果游戏中的每个图块在游戏中的任何一点都可以是任何3个状态中的1个,那么在任何给定时刻散列游戏板的每个可能状态时,“完美哈希”所需的最小存储量将
=电源(3,8 * 8)个别哈希
= log2(3^64)位
=约。 101.4位,因此您至少需要102位才能存储此信息
此时,您可以说每个磁贴有4种状态,这将使您需要128 bits。
执行此操作后,很容易为电路板制作快速哈希算法。
E.g。 (写作c ++,如果平台不支持128位数,则可能需要更改代码)
uint_128 CreateGameBoardHash(int (&game_board)[8][8])
{
uint_128 board_hash = 0;
for(int i = 0; i < 8; ++i)
{
for(int j = 0; j < 8; ++j)
{
board_hash |= game_board[i][j] << ((i * 8 + j) *2);
}
}
return board_hash;
}
这种方法在102位的最佳解决方案上只会浪费26位(略多于3个字节),但是您将节省大量的处理时间,否则这些处理时间将用于进行3位数学运算。
编辑这是一个不需要128位的版本,可以在任何16位(或更好)处理器上运行
struct GameBoardHash
{
uint16 row[8];
};
GameBoardHash CreateGameBoardHash(int (&game_board)[8][8])
{
GameBoardHash board_hash;
for(int i = 0; i < 8; ++i)
{
board_hash.row[i] = 0;
for(int j = 0; j < 8; ++j)
{
board_hash.row[i] |= game_board[j] << (j*2);
}
}
return board_hash;
}
答案 1 :(得分:0)
它不适合64位整数。你有64个方格,你需要超过1位来记录每个方格。为什么需要它适合64位int?你在瞄准ZX81吗?
答案 2 :(得分:0)
包含这些位的16字节数组怎么样?每个2位代表一个位置的值,因此给定8x8板中的位置(pos = 0-63),你可以通过将pos除以4来计算出索引,你可以通过进行位操作得到该值。两位(bit0 = pos mod 4和bit1 = bit0 + 1)。这两位可以是00,01或10。
答案 3 :(得分:0)
将你的评论读给David,看起来你真的不需要一个完美的哈希值。你只需要一个可清洗的物体。
让自己变得简单......在覆盖到GetHashCode()时为你做一些哈希,然后在Equals函数中完成剩下的工作。
如果你真的需要它是完美的,那么你必须使用GUID对你的数据进行编码并制作你自己的哈希,它可以使用128位密钥。但这对于小小的利益来说只是一个巨大的时间投入。