首页 > 解决方案 > 如何散列具有两个对称等效特征的对象?

问题描述

我有一个对象(边缘),其中包含其他两个 3D 对象(点 A 和 B)。在几何上,从 A = (0, 0, 0) 到 B = (1, 0, 0) 的边应该与从 A = (1, 0, 0) 到 B = (0, 0, 0) 的边相同),并且很容易做出两条边的相等性声明。但是,我在实现散列此对象的方法(在 Python 中)时遇到了一些概念性问题。例如,hash((A, B)) 将返回与 hash((B, A)) 不同的值。

我在这个网站上看到过类似问题的答案,但它们都涉及对这两个元素进行比较。我真的不想这样做,因为虽然我可以想出一种严格的方法来比较两点(首先比较 x 坐标,如果 x 相等则比较 y 坐标,如果 y 相等则比较 z),但我没有不知道我是否要实现一个在数学上似乎毫无意义且仅对这个单一实例有用的比较。语句 (1, 0, 0) > (0, 300, 10^10) 对于这种方法可能是正确的,但它不是很有意义。

class Edge(object):
    def __init__(self, pointA, pointB):
        self._A = pointA
        self._B = pointB
        ab = pointA + pointB
        self._midpoint = Vector(ab.x / 2, ab.y / 2, ab.z / 2)


    def get_A(self):
        return self._A

    def set_A(self, point):
        self._A = point

    def get_B(self):
        return self._B

    def set_B(self, point):
        self._B = point

    A = property(get_A, set_A)
    B = property(get_B, set_B)

    def __eq__(self, other):
        if isinstance(other, Edge):
            if (self.A == other.A) and (self.B == other.B):
                return True
            elif (self.B == other.A) and (self.A == other.B):
                return True
            else:
                return False

    def __ne__(self, other):
        return not self.__eq__(other)

    def __hash__(self):
        return hash((self.A, self.B)) # =/= hash((self.B, self.A))!

    def __str__(self):
        return "[{}, {}]".format(self.A, self.B)

总之,我想知道是否有一个实现会给两个等效的边缘相同的哈希值,而不会在点之间创建一些任意的比较函数。(PS我的“点”类被称为“向量”)

标签: pythonhashgeometry

解决方案


将 A 和 B 的哈希与 XOR 组合:

def __hash__(self):
    return hash(self.A) ^ hash(self.B)

推荐阅读