Hash 对图形进行散列以查找重复项(包括旋转和反射版本)

Hash 对图形进行散列以查找重复项(包括旋转和反射版本),hash,graph,language-agnostic,Hash,Graph,Language Agnostic,我正在做一个游戏,涉及通过图形求解路径。根据图表的大小,这可能需要一点时间,因此我希望缓存结果 这让我在寻找一种算法来散列一个图以找到重复项。 这对于图形的精确副本很简单,我只是使用相对于上角的节点位置。对于旋转图形甚至反射图形来说,它变得相当复杂。我怀疑这不是一个新问题,但我不确定它的术语是什么 我的具体案例是在一个网格上,因此一个节点(如果存在)将始终连接到它的四个邻居,北、南、东和西。在我当前的实现中,每个节点存储其相邻节点的一个数组 建议进一步阅读,甚至完整的算法是非常感谢 我当前的哈

我正在做一个游戏,涉及通过图形求解路径。根据图表的大小,这可能需要一点时间,因此我希望缓存结果

这让我在寻找一种算法来散列一个图以找到重复项。

这对于图形的精确副本很简单,我只是使用相对于上角的节点位置。对于旋转图形甚至反射图形来说,它变得相当复杂。我怀疑这不是一个新问题,但我不确定它的术语是什么

我的具体案例是在一个网格上,因此一个节点(如果存在)将始终连接到它的四个邻居,北、南、东和西。在我当前的实现中,每个节点存储其相邻节点的一个数组

建议进一步阅读,甚至完整的算法是非常感谢


我当前的哈希实现从图中第一个找到的节点开始,这取决于我在游戏场上迭代的方式,然后记录所有节点相对于它的位置。基本图将有一个散列,可能类似于:
0:1,0:2,1:2,1:3,-1:1,

基于twitter对话,让我重新表述这个问题(我希望我理解正确):

如何比较在90度旋转和反射下视为不变的图形(平面、网格上)。如果使用哈希,则可获得额外积分。

我没有完整的答案,但有一些想法可能会有所帮助:

将问题划分为独立可解的子问题。那将使

  • 如何比较给定不变性条件的图
  • 如何将它们转换为规范基
  • 如何在权衡(速度、大小、冲突等)的基础上散列此规范基础
  • 你可以试着一步一步地解1和2。简单的几何方法可以如下所示:

    对于旋转不变性,可以尝试计算每个方向上的边,并旋转图形,以便主方向始终指向右侧。如果没有主方向,您可以将图形视为其顶点的点云,并使用特征向量和原理成分分析(PCA)获得主方向并相应旋转

    对于反射问题,我没有一个聪明的解决方案。我的蛮力方法就是一直创建反射图。假设您有一个图g和反射图
    r(g)
    。如果你想知道某个其他图形是否
    h==g
    ,你必须回答
    h==g | | h==r(g)

    现在进入散列: 对于散列,您可能需要权衡速度、大小和冲突。如果只使用边串,则速度和大小较高,碰撞较少。如果您只是获取这个字符串并对其应用一些通用的字符串哈希器,您会得到不同的结果

    如果使用较短的散列,并且冲突更频繁,那么比较不匹配图的成本就相当小。匹配图的成本要高一些,因为您必须进行完整的比较,以查看它们是否真正匹配

    希望这有点道理

    最好的,西蒙

    更新:如果边没有给出明确的赢家,那么关于旋转问题的另一个想法是:计算顶点的质心,并查看它落在边界框中心的哪一侧。相应地旋转。

    我建议您这样做:

    • 创建一个函数,为任何图形生成哈希,位置独立。听起来你已经有这个了

    • 当您第一次为图形生成寻路解决方案时,请通过该图形的哈希缓存它

    • …然后还生成该图形的其他7种独特形式(旋转90度;旋转270度;翻转x;翻转y;翻转x&y;沿一条对角线翻转;沿另一条对角线翻转)。当然,您可以使用简单的向量/矩阵变换生成这些。对于这7个已转换的图中的每一个,您还将生成该图的哈希,并缓存相同的寻路解决方案(首先对其应用相同的转换,以便解决方案适当地映射到新的图配置)

    • 你完了。稍后,您的代码将查找图形的路径查找解决方案,即使它是您找到早期解决方案的图形的替代(旋转、翻转)形式,缓存也已包含正确的解决方案

    今天早上我花了一些时间思考这个问题,我认为这可能是最理想的解决方案。但我将分享我也在考虑的解决方案的其他过度分析版本

    我在考虑这样一个事实,即您真正需要的是一个函数,它将获取一个图G,并返回G的“规范版本”(我称之为G'),以及将G转换为G'所需的转换矩阵。(看起来您需要进行转换,以便将其应用于寻路数据并获得G的正确路径,因为您只需要存储G'的寻路数据。)当然,您可以查找G'的寻路数据,对其应用转换矩阵,并获得寻路解决方案

    问题是,我不认为有任何明确和有效的方法来确定G的“规范版本”,因为这意味着你必须识别G的所有8个变体,并且总是根据一些标准选择同一个作为G。我想我可以做一些聪明的事情,通过查看图表的每个轴,计算该轴中每行/每列的点数,然后旋转/翻转,将更不平衡的轴的一半始终放在顶部或左侧。。。换言之,如果你传递“d”、“q”、“b”、“d”、“p”等形状,你总是会得到“p”形状(不平衡朝向左上角)。这将有一个很好的属性,它应该识别wh