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

Hash 仅在方向上不同的几何图形的哈希代码,hash,Hash,我有一个包含几何图形(通常是(多边形)线)的集合。现在我想为这些几何体实现一个HashCode,以便将它们放入集合中。为此,我在每个几何体中都有三个成员,它们不会改变,因此适用于哈希代码:几何体类型(对于所有几何体,它是多段线,起点和终点) 所以我写了这个代码 int hash = 17; // this hascode-implementation uses the geometry-type and the from- and toPoints of the geometry hash

我有一个包含几何图形(通常是(多边形)线)的集合。现在我想为这些几何体实现一个HashCode,以便将它们放入集合中。为此,我在每个几何体中都有三个成员,它们不会改变,因此适用于哈希代码:几何体类型(对于所有几何体,它是多段线,起点和终点)

所以我写了这个代码

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();
现在我们在应用程序中有另一个先决条件,这使我无法编写哈希函数:当两个几何体相反时,它们也被认为是相等的。由于每个实际相等的对象必须具有相同的哈希代码,因此我必须更改实现,以便允许对角冲突

这意味着:

当几何体1的fromPoint等于几何体2的toPoint(反之亦然)时,它们的哈希代码也必须相等


在我的实现中,我必须改变哪些因素来启用对角碰撞,或者我完全不同意我的实现/有更好的方法来实现吗)?

对于交换的点,以产生相同的结果,您需要一个数学运算,其中
a op B==B op a
,在将结果添加到哈希之前,您需要将其应用于两个坐标

我想试试这个:

hash = hash * 31 + (
       this.Geometry.FromPoint.X.GetHashCode()
       + this.Geometry.ToPoint.X.GetHashCode
);
无论以何种顺序传递X坐标,此行都返回相同的结果

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

如果需要更改几何体,首先必须从哈希映射/集合中删除对象,更改几何体并再次添加


注:代码最后一行中的
X
应该是
Y

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

  • 你有多少物品?如果它适合于不太多的内容,那么不太担心hashcode实现可能是可以接受的,只要将其设置为常量即可

  • 如果任意两个几何体的equals操作都是非常重要的,那么将它们包装到一个对象中,在这个对象中,您在谈论相等时遇到的问题就更少了?e、 g.
    新的MyGeometry(“Id”,年龄测量)
    ?那么,实现hashCode/equals应该很简单


我也有您的第二种方法,但问题是:当两个几何体相等时,如何生成这些ID?我必须检测它们是否相等,这样我才能给它们相同的ID,不是吗?顺便说一句:这个问题与JAVA无关,因为其他语言也有哈希代码。所以我没有用JAVA标记它…好吧,这取决于你需要equals操作做什么。当然,拥有一组
MyGeometry
并手动执行诸如insert之类的操作是可以接受的。@HimBromBeere:jan groth的意思是允许您从
hashCode()
返回a常量值(例如,
5
equals()
将用于区分对象。但是如果你有很多对象,那会很慢。是的,我已经知道了这一点,但是对象的数量可能会以不可预测的方式变化(根据检索到的数据),不幸的是,因此我不能假设对象会更少……是的,就是这样,简单的数学,谢谢你的编辑建议:D