【问题标题】:How would you verify that two graphs are the same?您将如何验证两个图表是否相同?
【发布时间】:2012-10-06 19:52:16
【问题描述】:

假设我们想用图来表示分子,其中每个节点是一个原子,每个边是原子之间的连接。什么是确定两个图(代表分子)是否等价的算法。由于正在表示分子,因此每个节点都需要一个属性来定义它是哪个分子(碳、氮、氧等)。

为了方便起见,假设每个图都从同一个根原子 Nitrogen 分支出来,我们可以将其用作算法的起始节点。

例如。 N-X,N-Y,N-Z。其中 N 是根 Nitrogen 节点,X,Y,Z 是图的其余部分。

【问题讨论】:

    标签: algorithm tree graph-theory


    【解决方案1】:

    那是Graph Isomorphism Problem

    图同构问题是少数几个标准问题之一 属于 NP 的计算复杂性理论,但不为人所知 属于其众所周知的(并且,如果 P ≠ NP,不相交)子集: P 和 NP 完全的。它是总共 12 个问题中仅有的两个问题之一 在 Garey & Johnson (1979) 中列出,其复杂性仍未解决, 另一个是整数分解。

    换句话说,在一般情况下解决它是困难

    【讨论】:

    • 从维基百科我发现平面图有一个多项式时间解。我将对此进行调查。表示分子的图形将是平面的。
    【解决方案2】:

    我同意Joachim Isaksson's answer 的观点,即一般情况——哎呀,即使是不太一般的情况——也很难解决。但我想提出一种策略来解决具有指定起始元素的分子树图的相对狭窄情况。 [请注意,这相当于我在处理此答案时发布的Peter de Rivaz's answer。]


    首先让我们定义一种形式或语言来描述该图独有的分子图——该图只能形成一个字符串。这将允许我们比较两个字符串以确定两个图表是否相同,从而将您的问题简化为创建两个正确的字符串进行比较。 (这种方法还具有比直接图比较算法更易于直观调试的优点。)我通常看到以 H2O 和 H2 等形式描述的分子SO4,但这种方法不保留分子的图形特性,因此不能用于比较(H2O 可能是水或其他一些其元素的排列非常奇怪)。所以让我们根据这些规则使用类似 Lisp 的东西来描述分子:

    1. 每个图(包括子图)以( 开头,以) 结尾
    2. 任何具有子节点的节点 A 都是新图中列出的第一个节点,并且该图按特定顺序列在其父图中(稍后确定)
    3. 任何没有子节点的节点 A 都按特定顺序列在其父图中(稍后确定)

    有了这些起始规则,我们现在可以用更多类似图形的术语来描述 H2O:

    1. O 是图的根,因此它会启动一个新图:(O)
    2. HO 的第一个孩子,但它没有孩子,所以它按原样列在其父级中,而不是作为子图的开头:(OH)
    3. HO 的第二个孩子,但它没有孩子,所以它按原样列在其父级中,而不是作为子图的开头:(OHH)

    所以

    变成(OHH)

    在这种情况下排序无关紧要,因为两个Hs 是无子元素并且在元素上是等价的。

    让我们尝试一种奇怪的、非理性的 H2O 形式来测试这种方法:

    1. O 是图的根,因此它开始一个新图:(O)
    2. HO 的第一个孩子。它有一个孩子,所以它开始一个新的图表:(O(H))
    3. HH 的第一个孩子,但它没有孩子,所以它按原样列在其父级中,而不是作为子图的开头:(O(HH))

    我们知道到目前为止,我们的方法可以处理简单的情况,例如 H2O,其中排序不是问题,但 H2SO4如果没有一致地对来自SO 元素进行排序,sub> 将无法工作。在计算子图(如果有的话)之前,不可能给一个子图一个有意义的命令,所以我们将添加一个最终规则来执行:

    1. 每个图(包括子图)以( 开头,以) 结尾
    2. 任何具有子节点的节点 A 都是新图中列出的第一个节点,并且该图按特定顺序列在其父图中(参见步骤 4)
    3. 任何没有子节点的节点 A 都按特定顺序列在其父图中(参见步骤 4)
    4. 访问完所有子节点并创建子图(如果有)后,按字母顺序排列父节点中的子节点/子子图

    使用这个新规则重新访问 H2O 会产生相同的输出,因为这两个 Hs 在字母顺序上是等效的,并且它们没有子级。所以让我们试试 H2SO4:

    1. S 是图的根,因此它开始一个新图:(S)
    2. OS 的第一个孩子。它有孩子,所以它开始一个新的图表:(S[unsorted:](O))
    3. 'H' 是O 的第一个孩子。它没有孩子。没有其他子要处理,因此不需要在此级别进行排序:(S[unsorted:](OH))

    4. OS 的第二个孩子。这个没有孩子:(S[unsorted:](OH)O)

    5. OS 的第三个孩子。它有孩子,所以它开始一个新的图表:(S[unsorted:](OH)O(O))

    6. 'H' 是O 的第一个孩子。它没有孩子。没有其他子要处理,因此不需要在此级别进行排序:(S[unsorted:](OH)O(OH))

    7. OS 的第四个孩子。这个没有孩子:(S[unsorted:](OH)O(OH)O)

    8. 最后,按字母顺序对S 的孩子进行排序:(S(OH)(OH)OO)(请注意,我在字母比较中对子图进行了特殊处理,但这不是必需的。)

    最终结果是(S(OH)(OH)OO)

    让我们尝试 H2SO4 的变体,看看它会产生什么。请注意,这并不能证明该方法是好的,只是演示图表中的变化如何产生不同的结果。

    1. S 是图的根,因此它开始一个新图:(S)
    2. OS 的第一个孩子。它有孩子,所以它开始一个新的图表:(S[unsorted:](O))
    3. O 是第一个孩子。它没有孩子。 (S[unsorted:](O[unsorted:]O))
    4. H 是第二个孩子,没有孩子。 (S[unsorted:](O[unsorted:]OH))
    5. 现在对O 的孩子进行排序:(S[unsorted:](OHO)
    6. OS 的第二个孩子。它有孩子,所以它开始一个新的图表:(S[unsorted:](O))
    7. H 是第一个孩子。它没有孩子。 (S[unsorted:](OHO)(O[unsorted:]H))
    8. O 是第二个孩子,没有孩子。 (S[unsorted:](OHO)(O[unsorted:]HO))
    9. 现在对O 的孩子进行排序:(S[unsorted:](OHO)(OHO))
    10. 最后,按字母顺序对S 的孩子进行排序:(S(OHO)(OHO))

    这个 H2SO4 ((S(OHO)(OHO))) 与前一个 ((S(OH)(OH)OO)) 不同。


    我没有试图正式证明这种方法可以保证有效,甚至没有正式描述它,也没有试图解释广泛的分子细节,如债券计数等。不过,至少,我希望这能鼓励您尝试解决图形比较问题。我认为这是可行的。

    【讨论】:

      【解决方案3】:

      您的问题被标记为“树”,这可能意味着图中没有循环?

      如果是这种情况,那么有一种有效的算法可以确定分子是否等价。

      给定根原子,想象这是一棵向下延伸的树的顶部。

      这个想法是从树的底部迭代地计算出哪些子树是等效的。

      从底部开始,标记两个分子中的所有等效原子。 对该列表进行排序并检查两个列表是否匹配。 (在底层,这只是简单地计算每种原子的数量是否相同。)

      然后工作到下一个最低级别。对于每个原子,根据原子类型和它连接的子树的排序标签给它一个标签。

      再次对该列表进行排序并检查列表是否匹配。

      当你到达根节点时,如果所有的检查都通过了,那么分子是同构的。

      【讨论】:

        猜你喜欢
        • 2011-01-28
        • 1970-01-01
        • 2020-09-10
        • 2014-07-19
        • 2013-09-21
        • 2020-01-02
        • 1970-01-01
        • 2018-03-01
        • 1970-01-01
        相关资源
        最近更新 更多