您如何验证两个图表是否相同?

时间:2012-10-06 19:52:16

标签: algorithm tree graph-theory

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

为了使其更容易,假设每个图形从相同的根原子氮分支,我们可以将其用作算法的起始节点。

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

3 个答案:

答案 0 :(得分:9)

那是Graph Isomorphism Problem;

  

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

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

答案 1 :(得分:5)

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


首先让我们定义一种形式或语言来描述该图独有的分子图 - 图中只能形成一个字符串。这将允许我们比较两个字符串以确定两个图是否相同,以便您的问题减少到创建两个正确的字符串进行比较。 (这种方法还具有比直接图形比较算法更容易在视觉上调试的好处。)我通常看到以H 2 O和H 2 等形式描述的分子。 SO 4 ,但这种方法不能保留分子的图形,因此不能用于比较(H 2 O可能是水或其他一些非常奇怪的元素排列)。因此,让我们根据这些规则使用类似Lisp的东西来描述分子:

  1. 每个图表(包括子图)以(开头,以)
  2. 结尾
  3. 任何有子项的节点A是新图表中列出的第一个节点,此图表按其特定顺序列在其父图表中(稍后确定)
  4. 任何没有孩子的节点A都按其特定顺序列在其父图表中(稍后确定)
  5. 根据这些起始规则,我们现在可以用更多类似图形的术语来描述H 2 O:

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

      graph of H2O

      变为O

      在这种情况下订购并不重要,因为这两个(OHH)是无子女的,在元素上是等价的。

      让我们尝试一种奇怪的,非理性的H 2 O形式来测试这种方法:

      graph of O-H-H

      1. (OHH)是图表的根,因此它会启动一个新图表:H
      2. O(O)的第一个孩子。它有一个孩子,所以它开始一个新的图表:H
      3. O(O(H))的第一个孩子,但是没有孩子,所以它在其父级中按原样列出,而不是子图的开头:{{1 }}
      4. 我们知道到目前为止我们的方法可以处理简单的情况,例如H 2 O,其中排序不是关注,但是H 2 SO 4 < / sub>在没有始终如一地排序H来自H的{​​{1}}元素的情况下工作。在计算子图(如果有子图)之前,不可能给孩子一个有意义的命令,所以我们要添加一个最终规则来执行:

        1. 每个图表(包括子图)以(O(HH))开头,以O
        2. 结尾
        3. 任何有孩子的节点A是新图表中列出的第一个节点,该图表按其特定顺序列在其父图表中(参见步骤4)
        4. 任何没有子节点的节点A都按其特定顺序列在其父图中(参见步骤4)
        5. 访问完所有子节点并创建子图(如果有)后,按字母顺序排列父节点中的子节点/子子图
        6. 使用此新规则重新访问H 2 O会产生相同的输出,因为两个S按字母顺序排列,并且没有子项。所以让我们试试H 2 SO 4

          graph of h2so4

          1. (是图表的根,因此它会启动一个新图表:)
          2. HS的第一个孩子。它有子项,因此它会启动一个新图表:(S)
          3. &#39; H&#39;是O的第一个孩子。它没有孩子。没有其他孩子可以处理,因此不需要在此级别进行排序:S

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

          5. OS的第三个孩子。它有子项,因此它会启动一个新图表:(S[unsorted:](OH)O)

          6. &#39; H&#39;是O的第一个孩子。它没有孩子。没有其他孩子可以处理,因此不需要在此级别进行排序:S

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

          8. 最后,按字母顺序对O的孩子进行排序:S(请注意,我在字母比较中给出子图特殊处理,但这不是必需的。)
          9. 最终结果为(S[unsorted:](OH)O(OH)O)

            让我们试一下H 2 SO 4 的变体,看看它产生了什么。请注意,这并不能证明方法是好的,只是演示图表中的变化如何产生不同的结果。

            graph of some weird H2SO4

            1. S是图表的根,因此它会启动一个新图表:(S(OH)(OH)OO)
            2. (S(OH)(OH)OO)S的第一个孩子。它有子项,因此它会启动一个新图表:(S)
            3. O是第一个孩子。它没有孩子。 S
            4. (S[unsorted:](O))是第二个孩子,没有孩子。 O
            5. 现在对(S[unsorted:](O[unsorted:]O))的孩子进行排序:H
            6. (S[unsorted:](O[unsorted:]OH))O的第二个孩子。它有子项,因此它会启动一个新图表:(S[unsorted:](OHO)
            7. O是第一个孩子。它没有孩子。 S
            8. (S[unsorted:](O))是第二个孩子,没有孩子。 H
            9. 现在对(S[unsorted:](OHO)(O[unsorted:]H))的孩子进行排序:O
            10. 最后,按字母顺序对(S[unsorted:](OHO)(O[unsorted:]HO))的孩子进行排序:O
            11. 此H 2 SO 4 (S[unsorted:](OHO)(OHO)))与前一个(S)不同。


              我没有试图正式证明这种方法可以保证正常工作,甚至可以正式描述,或者考虑到那里广泛的分子细节,如债券数量等。但至少,我希望这可以鼓励您尝试解决图形比较问题。我认为这是可行的。

答案 2 :(得分:3)

您的问题已被标记为&#34;树&#34;这可能意味着图中没有循环?

如果是这种情况,那么有一种有效的算法来确定分子是否相同。

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

我们的想法是从树的底部开始迭代地确定哪些子树是等价的。

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

然后努力到下一个最低级别。对于每个原子,给它一个基于原子类型的标签,以及它连接到的子树的排序标签。

再次对此列表进行排序并检查列表匹配。

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