散列浮动向量的好方法?

Good way to hash a float vector?


问题 [散列浮动向量的好方法?] 已获得7个答案 2020-07-24 01:45:25 floating-point

我很清楚比较浮动所涉及的所有问题.这正是这个问题的原因.
我想为 3D向量 (3 个浮点数-x,y,z) 的值创建一个快速哈希表.可以假设矢量的长度始终为 1.0 ( sqrt(x*x+y*y+z*z) 为 1.0)

本质上,这意味着我正在寻找一个哈希函数,它的值几乎等于相同的unsigned int值和相应的相等运算符,如果哈希值相等 (不是不一定只有当他们是平等的)

编辑 -
假阳性 (即不同但映射到同一个桶的向量) 是给定的,因为这是一个哈希表.
假阴性 (即接近但映射到不同桶的向量) 是不可取的,但似乎没有办法避免它们.在我的情况下,它们不会导致完全损坏,只是一些数据重复,这是我必须接受的.


问题 [散列浮动向量的好方法?] 的第1个答案

我认为你要找的东西是不可能直接实现的.等式的一个重要属性是它是传递性的.如果a = = b和b = = c,则a = = c).不过,用距离测量,你真的不想要这个财产.示例:

采取单一的浮动 (为简单起见).假设我们想对每个浮点数进行散列,以便小于 1e-3 的浮点数是相同的值.现在,假设我们将所有 1e-4 相距的 1000 浮点值添加到这个哈希表中.任何相邻的 2 值都应该散列到相同的浮点,因为它们比 1e-3 更接近.然而,由于传递性,这些值的邻居也应该具有相同的值,它们的邻居等等.结果,所有 1000 个值,包括距离 1e-3 更远的对,将散列为相同的整数.如果你要在图片上画这些点:

A  B  C  D  E  F  G  H ... Y Z

假设所有间隙间隔 <1e-3,但A和Z间隔> 1e-3 (不按比例!).这不能满足,因为如果所有对的哈希 (A) = = 哈希 (B) 和哈希 (B) = = 哈希 (C) 等,(因为它们间隔 <1e-3) 比哈希 (A) 必须 = = 哈希 (Z).

一个可能的选择是定义你的向量空间的区域,其中所有向量都会散列到相同的值 (即在散列之前将它们变圆),但是你仍然可以在它们各自空间的边缘得到 2 个向量,它们靠近在一起,但是散列到不同的值.你可以通过搜索矢量的所有相邻空间来绕过它.(即在上面的 1-d情况下,您将所有向量舍入到 1e-3 的最接近倍数,然后搜索邻居,因此 5.3e-3 将搜索 5e-3 、 4e-3 和 6-e3.在更高维度的情况下,你必须搜索所有维度的邻居.)


问题 [散列浮动向量的好方法?] 的第2个答案

某些语言 (C,Java 5) 允许您访问浮动的二进制值.这样,您可以提取尾数的前N位 (忽略在比较期间导致麻烦的最后几位) 并从中计算哈希.


问题 [散列浮动向量的好方法?] 的第3个答案

我将float值转换为像这样的整数:

unsigned int IntValue = (int)(floatValue * MULT) + MULT;

所以你得到一些第一个数字,然后使用

const MULT1 = (MULT << 1) + 1;
unsigned long long HashValue = (xIntValue * MULT1  * MULT1) + (yIntValue * MULT1) + zIntValue;

作为哈希值 (使用 (MULT * 2) 1,因为IntValues将介于 0 和MULT * 2 之间 (含)).

所需的内存将取决于乘法器MULT.例如,使用 32,您将获得使用 64 * (哈希项目大小) = 262144 * (哈希项目大小) 字节的哈希表.


问题 [散列浮动向量的好方法?] 的第4个答案

你能解决你的问题吗?

假设您使用hashmap将一些额外的数据映射到特定的向量,您可以只使用组件的二进制表示的XOR (如果这在您选择的语言中是可能的).然后根据哈希映射的需要使用尽可能多的lsb (以减少冲突).这当然具有两个相等的 (通过浮点比较) 向量可能不具有相同散列 (e g. IEEE浮点 0 等于-0,但它们有不同的符号位).

但是,如果您计划使用不同计算结果的向量进行哈希查找,由于舍入错误,您正在设置自己没有匹配哈希代码的可能性,无论如何,您可能应该使用其他东西.


问题 [散列浮动向量的好方法?] 的第5个答案

我认为你有效地试图解决K最近的问题.我相信你要找的是局部敏感哈希.您也可以使用四叉树结构来实现相同的结果.


问题 [散列浮动向量的好方法?] 的第6个答案

不知道这可能有多快,但是既然你有单位向量,它们都在球体的表面上.转换为 http://en.wikipedia.org/wiki/Spherical_coordinate_system .然后使用phi和theta选择一个桶.不会有假阳性.您可以在相邻的单元格中查找假阴性.


问题 [散列浮动向量的好方法?] 的第7个答案

你需要它是一个快速哈希表还是一个树结构?

在我看来,在某种搜索树中查找匹配的浮点数会更容易.AB-树假设您选择了正确的节点大小,则最大限度地减少缓存未命中的次数.这在实践中应该会很快.


.htaccess .net .net-core 3d actionscript-3 activemq ajax akka algorithm alignment amazon-cognito amazon-deequ amazon-ec2 amazon-redshift amazon-s3 amazon-web-services amp-html android android-activity android-fragments android-management-api android-ndk android-studio angular angularjs animation ant apache apache-camel apache-drill