【发布时间】:2014-10-28 06:00:52
【问题描述】:
拥有 3D 统一网格,为了在大型模型中节省内存,不需要保存空单元格(不与任何对象重叠的单元格)。为此,我在 c# 中使用字典。尽管性能已经下降,但这仍然比创建 3D 网格时出现异常要好。现在我的问题是找到一个快速散列函数,将网格的 3d 整数坐标映射到唯一的数字。
我已经尝试过 ((x * 73856093 + y * 19349669 + z * 83492791))% n ,它并不总是生成唯一的数字。
【问题讨论】:
-
如果数字可以是任意大小,那么您只需执行 x * MAXINT * MAXINT + y * MAXINT + z。如果数字必须与整数大小相同,那么由于pigeonhole principle,唯一性是不可能的。有 2^32 个可能的整数值和 2^96 个可能的整数三元组值。如果没有重叠,就不能将后一类归入前一类。
-
x、y 和 z 坐标的可能值是多少?
-
哈希值根本不需要唯一。当不同输入值的 2 个哈希值相同时,就会发生冲突。您只需要将冲突保持在最低限度(以提高性能),这通常很容易,例如
hash = (x * 31) + (y * 37) + (z * 41)绰绰有余。 -
假设您的哈希值可以高达 2^48,则更好的哈希(在您的情况下没有冲突)将是
hash = (x * 18397) + (y * 20483) + (z * 29303)。 -
@Floris:只有当哈希映射本身具有相同的大小(即 2^48)时,避免冲突才会有所帮助。否则你在某处有一个 mod 步骤,所以你只推迟了碰撞。
hash=x*16777216+y*4096+z也可以避免冲突,只使用 36 位(每个坐标 12 位)。它可以使用位移来实现。 但是如果以较小的 2 次幂为模减少,它会执行 可怕,这很可能发生在真正的哈希映射中。
标签: math voxel geohashing