我见过this question about the representation of molecules in memory,这对我来说很有意义(tl; dr将它表示为原子作为节点和键作为边缘的图形)。但现在我的问题是:我们如何检查两个分子是否相等?这可以概括为我们如何检查(非循环)图的相等性?现在我们将忽略stereoisomers和循环结构,例如第一个给出的示例中的碳环链接。
以下是我的问题的更详细描述:对于我的Molecule
类(截至目前),我打算有一个Atom
数组和一个Bond
数组。每个Bond
将指向任一端的两个Atom
,并且将具有权重(即,该边缘中的化学键的数量)。换句话说,这将最类似于边缘列表图。我的第一个猜测是在一个分子中迭代Atom
并尝试根据包含Atom
的{{1}}在另一个分子中找到相应的Bond
,但这是一种相当天真的方法,而且复杂性看起来相当大(最佳猜测接近 O(n!)。哎呀。)。
无论复杂程度如何,这种方法似乎在大多数情况下都可以使用,但是对于某些分子来说似乎有所不同。以这些为例(注意OH组的不同位置):
Atom
如果我们检查这些分子,对于一个分子中的每个原子,在另一个分子中有一个独特的相同元素原子具有相同数量和类型的键,但这两个分子显然不相同,也不是立体异构体(我现在不考虑)。相反,它们是structural isomers。有没有办法我们可以检查这个相对结构?使用邻接列表而不是边缘列表会更容易吗?是否有任何图形相等算法,我应该研究(理想情况下在Java中)?我看起来有点graph canonization,但这似乎可能是NP难的。
编辑:查看Graph Isomorphism Problem Wikipedia Article,似乎有限度的图形具有此问题的多项式时间解决方案。此外,平面图还具有多项式解(即,边仅在它们的端点处相交)。在我看来,分子满足这两个条件,那么这个问题的多项式时间解决方案是什么,或者我在哪里可以找到它?我这次谷歌搜索让我失望。
答案 0 :(得分:3)
如果图是非循环的,那么它就是一个树同构问题,它有一个非常简单的解决方案。
现在让我们假设所有内部节点都是碳,并且所有边都相同(稍后将介绍如何放宽此限制。)
将叶节点表示为数字 - 例如它们的原子序数。将高度为1的树表示为其叶节点的排序列表,所以:
H Cl
| |
H - C - H and Cl-C-Cl
| |
H H
分别是[1,1,1,1]和[1,17,17,17]。显然,如果排序列表相同,则两个分子是同构的。
这概括为更高的树木 - 代表一个高度为n
的树作为其子树的表示列表,以lexigoraphically方式排序,所以
Cl H H H
| | | |
H - C -C-Cl and Cl- C - C - Cl
| | | |
Cl H H Cl
都是[[1,1,17],[1,17,17]]。如果它们的表示是两棵树是同构的。
注意:通常树同构算法适用于有根树。在这里,我们只是从叶子递归到图的中心,这有时会让我们留下两个"根"。
H H Cl
| | |
H - C - C - C - H
| | |
H H H
这里,左边C是[1,1,1],右边C是[1,1,17]。中间的C(这里是根)有这两个列表和两个叶子。按字典顺序排序它[1,1,[1,1,1],[1,1,17]]。
现在用于表示不是C的内部节点 - 您可以通过附加带有特殊数字的假叶来模拟它们,所以
H
|
H - C - O - H
|
H
可以编码为
H
|
H - C - C - H
| |
H Fake
"假"可以说是511,这样我们就知道它不会与任何现有的原子发生冲突。因此整个分子将是[[1,1,1],[1,511]]。
所以算法是:
答案 1 :(得分:0)
@Rafal讨论了树木的情况。但是如果你没有树呢?这是我的两分钱:
Mathematica方法
Mathematica有一个内置的谓词来检查两个图是否是同构的。如果您没有,可以试用30天。
检查美丽
nauty是一个求解器,您可以在其中下载并测试同构。
提前检测到真阴性
您可以通过简单地计算和比较某些数字/序列来提前检测到真阴性。这包括计算顶点和边缘设定度数的度序列。通过这一对的图形并不一定意味着它们是同构的,但会减少你的空间(也许会大幅减少!)。
最重要的是,问题有一个recent进展,表明同构测试是有界树宽图的多项式。即使您的图表看起来很一般,它们也可能表现出这种属性(或者您可以简单地假设它)。