几何图形的哈希代码仅在方向上有所不同

时间:2014-03-03 11:19:19

标签: hash

我有一个包含几何的集合(通常是(Poly)Lines)。现在我想为这些几何实现一个HashCode,以便将它们放入集合中。为此,我在每个几何体中都有三个不会改变的成员,因此适用于HashCode:几何类型(所有几何的PolyLine,从 - 和到 - 点)

所以我写了这段代码

int hash = 17;

// this hascode-implementation uses the geometry-type and the from- and toPoints of the geometry

hash = hash * 31 + this.Geometry.GeometryType.GetHashCode();
hash = hash * 31 + this.Geometry.FromPoint.X.GetHashCode();
hash = hash * 31 + this.Geometry.FromPoint.Y.GetHashCode();
hash = hash * 31 + this.Geometry.ToPoint.X.GetHashCode();
hash = hash * 31 + this.Geometry.ToPoint.Y.GetHashCode();

现在我们在应用程序中有另一个先决条件,这使我无法编写散列函数:两个几何在相反时也被视为相等。由于每个实际的相等对象必须具有相同的hashCode,因此我必须更改实现,以便允许对角线冲突。

这意味着以下内容:

当几何1的fromPoint等于几何2的Point(反之亦然)时,它们的hashCodes也必须相等。

我在实现中需要更改哪些因素才能启用对角线冲突,或者我对我的实现完全错误/有更好的方法吗?

2 个答案:

答案 0 :(得分:0)

要使交换点产生相同的结果,您需要一个A op B == B op A的数学运算,并且需要在将结果添加到哈希值之前将其应用于两个坐标。

我会试试这个:

hash = hash * 31 + (
       this.Geometry.FromPoint.X.GetHashCode()
       + this.Geometry.ToPoint.X.GetHashCode
);

无论您传递X坐标的顺序如何,此行都会返回相同的结果。

注意:如果添加/删除多边形的线条或移动端点,则哈希码会更改。因此,只要这样的对象存储在哈希映射/集中,就必须确保几何不会改变。

如果您需要更改几何图形,首先必须从哈希图/集中删除对象,更改几何图形并再次添加。

PS:代码最后一行的X应为Y

答案 1 :(得分:0)

我还没有真正理解你所描述的问题的几何方面,但这里有一些想法:

  • 你有多少个物品?如果它适合而不是太多,那么不必过多担心哈希码实现,只需使其保持不变

  • 如果任何两个几何的等于运算都是非平凡的,那么将它们包装到一个对象中,那么你在讨论相等问题时会遇到什么问题呢?例如new MyGeometry("an Id", aGeometry)?实现hashCode / equals应该是微不足道的。