Hash 如何散列并检查具有循环引用的对象的相等性

Hash 如何散列并检查具有循环引用的对象的相等性,hash,graph,equals,circular-reference,cyclic,Hash,Graph,Equals,Circular Reference,Cyclic,我有一个循环的类似于图的结构,由节点对象表示。 节点是标量值(叶)或n>=1个节点的列表(内部节点) 由于可能存在循环引用,我不能简单地使用递归HashCode()函数,该函数组合了所有子节点的HashCode():它将以无限递归结束 虽然HashCode()部分似乎至少可以通过标记和忽略已访问的节点来实现,但我在思考Equals()的有效算法时遇到了一些困难 令我惊讶的是,我没有找到任何有用的信息,但我相信很多聪明人都想到了解决这些问题的好方法……对吗 示例(python): A等于B,因为它

我有一个循环的类似于图的结构,由节点对象表示。 节点是标量值(叶)或n>=1个节点的列表(内部节点)

由于可能存在循环引用,我不能简单地使用递归HashCode()函数,该函数组合了所有子节点的HashCode():它将以无限递归结束

虽然HashCode()部分似乎至少可以通过标记和忽略已访问的节点来实现,但我在思考Equals()的有效算法时遇到了一些困难

令我惊讶的是,我没有找到任何有用的信息,但我相信很多聪明人都想到了解决这些问题的好方法……对吗

示例(python):

A等于B,因为它表示完全相同的图形


顺便说一句,这个问题不针对任何特定的语言,但在Java中为所描述的节点对象实现hashCode()和equals()将是一个很好的实际例子。

如果您将其视为图形,则叶节点是只有一个连接的节点,而复杂节点是至少有两个连接的节点。因此,如果你这样做了,实现一个简单的BFS算法,将哈希函数应用到它通过的每个节点,然后丢弃结果。通过这种方式,您可以确保自己不会落入圆环或多次通过任何节点


实施可能非常艰难。阅读相关信息。

你需要浏览图表

这里有一个问题:这些图是相等的吗

A = [1,2,None]; A[2] = A
B = [1,2,[1,2,None]]; B[2][2] = B
如果是这样,您需要一组(Node,Node)元组。使用此集合捕捉循环,并在捕捉循环时返回“true”


如果没有,您可以更高效一点,使用节点到节点的映射。然后,在浏览图形时,建立一组对应关系。(在上述情况下,A将对应于B,A[2]将对应于B[2],&c。)然后,当您访问一个节点对时,请确保映射中存在精确的对;如果不是,则图表不匹配。

我也想知道一个好的答案。到目前为止,我使用基于访问集的解决方案

在计算散列时,我遍历图结构并保留一组访问的节点。我不会两次进入同一个节点。当我点击一个已经访问过的节点时,哈希返回一个没有递归的数字


这项工作甚至可以用于平等比较。我比较节点数据并递归调用子节点。当我点击一个已经访问过的节点时,比较结果返回true而不递归。

感谢您的响应,但是这并不能真正帮助我:在我知道一个节点的所有子节点的哈希之前,我无法计算该节点的哈希。对于BFS或DFS,我可以避免无限递归,但如果存在循环,我得到的哈希可能不是一个好的哈希:例如,当我忽略第二次看到的节点时,节点的哈希将与没有循环的节点的哈希相同。我正在寻找一些有意义的哈希算法,并且不会引入不必要的冲突(如果这种情况下存在的话)。
A = [1,2,None]; A[2] = A
B = [1,2,[1,2,None]]; B[2][2] = B