具有容差级别的双精度哈希方法

时间:2018-01-24 16:48:48

标签: java hash equals

我实现了一个如下所示的equals方法,其公差等级为双精度。

public boolean equals(Object obj) {
    // Checking for not null and same class etc.
    return approxEqual(this,other);
}

private static boolean approxEqual(final Position p1, final Position p2) {
    double distance = // distance function between positions
    return Double.compare(distance, TOLERANCE) <= 0;
}

当我使用HashSet时,我需要一个具有相同功能的哈希方法。 你们有什么想法怎么做?

我知道,公差等级不是很好,因为equals方法应该是可传递的。但我需要平衡测量误差。

4 个答案:

答案 0 :(得分:4)

假设:假设您现在的容忍度为1。这意味着0等于0.8,因为它们的差异低于容差。然后让我们比较0.8和1.5,它们是相等的,因为它们的差值是0.7 <1。 1.这意味着它们将获得相同的哈希值,这意味着0和1.5具有相同的哈希值,重复该过程并且所有将获得相同的哈希值/相等。

这没有意义,是吗?您不能容忍equalhashcode

答案 1 :(得分:1)

不幸的是,我认为这违背了哈希的性质。

作为替代解决方案,首先想到的是k-d-tree或二元搜索。

答案 2 :(得分:1)

使用TreeMap代替HashMap

如果您在compareTo / compare方法中实施容差,那么任何键查找/插入都将&#34; snap&#34;到容忍范围内的现有密钥。

当然还有一点需要注意,插入顺序可能会影响结果。例如。如果公差为5,并且您具有值2,6和9,则先添加6将同时将2和9捕捉到6值,结果是一个键(6),否则最终会得到两个键( 2和9)并且它是任意的6是否捕捉到2或9。

有了宽容,你无法对这种不可预测性做任何事情,所以我相信这是解决你问题的最佳方案。

答案 3 :(得分:0)

您可以将数据拆分为范围,并说某些范围内的所有内容都相同 您可以通过舍入来完成此操作(确切的详细信息取决于您要查找的容差级别,下面您只需使用floor)。

因此,如果我们分成1的范围,我们可以说0到1之间的所有内容(不包括1,即在[0,1)范围内)相等,1到2之间的所有内容都相等等等。

然而,这确实会产生一个问题,即彼此非常接近的元素可能不相等如果它们处于不同的范围内,例如,对于上述情况,0.9999将不会被视为相等到1.0001。

如果您尝试仅使用相等(和散列)来解决此问题,则无法完全避免此问题,因为扩展这些范围并不能解决此问题,并且尝试使它们重叠会产生新问题。

根据您尝试使用此方法的方式,可以通过执行多次查找来解决上述问题,因此您在[0,1]范围和[1]中都考虑0.9999 2]范围。如果您试图进行查找以查找在某些其他元素的某些容差范围内的所有元素(这与将元素视为相等的非常相同),这将有效。 / p>

如果这对您不起作用,哈希可能不是您正在寻找的解决方案,您可能希望考虑有序数据集,例如{{1 (或者确实是kd-tree,如另一个答案所述)。

这主要基于1D数据(即双精度数),但通过对每个维度进行舍入,可以很容易地将其扩展到2D(方形范围)或3D(立方体范围)。如果你正在进行如上所述的多次查找,你可能不需要进行1次查找(最近的范围),但最多可以进行3次2D(水平和垂直方向最接近的方形范围,以及&#39; s与这两者相邻),类似于3D。