8×8板的完美哈希功能?

时间:2010-11-29 07:22:48

标签: theory hash

我正在实现一个只有两种类型的板,并且正在寻找一个从该板映射到Long Integer(64位)的函数。我认为这不应该这么难,因为一个长整数包含比8乘8数组更多的可用信息(称之为grid [x] [y]),每个点中只有3个可能的元素,包括空元素。我尝试了以下几点:
(1)Zobrist用Longs而不是int进行散列(只是为了测试 - 我实际上并不希望它能完美地工作)
(2)将网格转换为基数为3的64字符串,然后取出该数字并将其解析为长数。我认为这应该有效,但需要很长时间 是否有一些更简单的解决方案(2)涉及转移的位操作或类似的东西?
编辑:请不要给我实际的代码,因为这是一个类项目,在我们的部门可能被认为是不道德的(或者至少不是Java)。
编辑2:基本上,在任何给定时间板上只有10个白色和10个黑色,其中在水平,垂直或对角线方向上没有两个相同颜色的相邻颜色。此外,每种颜色有12个空格,只有那种颜色可以放置。

4 个答案:

答案 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位密钥。但这对于小小的利益来说只是一个巨大的时间投入。