【问题标题】:Hashing integer coordinates of different sizes散列不同大小的整数坐标
【发布时间】:2015-06-08 06:51:56
【问题描述】:

我正在尝试将一些 3D 坐标散列为 16 位整数。 坐标具有以下约束:

x [0, 16]
y [0,256]
z [0, 16]

是否有可能获得 O(1) 访问、零冲突并且仍然适合 16 位字?

我的想法是移动坐标,使 x 占据前 4 位,y 占据下一个 8 位,z 占据最后 4 位。经过一些迭代后,我想出了以下内容,它会移动并屏蔽这些位,以便它们不应该t 重叠并导致碰撞:

unsigned int hash(unsigned char x, unsigned char y, unsigned char z) {
  return (x << 12) & 0xF000 |
         (y << 8)  & 0x0FF0 |
          z        & 0x000F;
}

但是,这确实会以某种方式产生碰撞!我不知道为什么,如果有人能告诉我,我将不胜感激。

在研究散列时,我发现 z 阶曲线/morton 编码将是一个很好的方法,但假设每个维度中的坐标范围是恒定的。是否可以选择将 x 和 z 编码为 8 位,并以某种方式将其与 y 坐标组合为 16 位字?

【问题讨论】:

    标签: hash voxel


    【解决方案1】:

    我尝试使用以下代码映射到 32 位整数。

    return ((x) << 24)  & 0xFF000000 |
           ((y) << 16)  & 0x00FFFF00 |
           z            & 0x000000FF;
    

    我的单元测试通过了,它似乎可以工作,但是我担心这可能会比 16 位哈希消耗更多的内存。

    我会将其标记为已回答,但如果有人能启发我,原来的问题仍然存在。

    【讨论】:

      【解决方案2】:

      可能是因为你写过

      x        & 0x000F
      

      应该是什么时候

      z        & 0x000F
      

      第二个班次计数也是错误的,所以试试:

      unsigned int hash(unsigned char x, unsigned char y, unsigned char z) {
        return (x << 12) & 0xF000 |
               (y << 4)  & 0x0FF0 |
                z        & 0x000F;
      }
      

      【讨论】:

      • 该死!感谢您发现这一点,但它仍然会产生碰撞。它似乎只产生 4096 个可能的哈希值,留下 61440 个冲突!
      • @perryperry:如果你的意思是这些是包容性的上限,那么不可能将它们放入 16 位中而不会发生冲突。无论如何,请参阅编辑 - 您还需要移动 4 而不是 8。
      猜你喜欢
      • 2014-10-28
      • 2015-10-26
      • 1970-01-01
      • 1970-01-01
      • 2013-04-21
      • 2022-01-02
      • 1970-01-01
      • 1970-01-01
      • 2015-02-08
      相关资源
      最近更新 更多