python - NetworkX 化学 : how to check if a smaller molecular graph A is a valid subgraph of a larger molecular graph B?

标签 python networkx graph-theory chemistry cheminformatics

我正在尝试通过 Python 使用图论,以验证分子片段是否是较大分子的有效子结构。让我们看一个神经递质血清素的例子:

from pysmiles import read_smiles
import networkx as nx
import matplotlib.pyplot as plt

# Descriptor of serotonin, via SMILES notation
serotonin = "C1=CC2=C(C=C1O)C(=CN2)CCN"
# Uses pysmiles to convert the SMILES into a Graph object
serotonin_graph = read_smiles(serotonin)

# Function for plotting Graph objects of molecules
def plot_graph(graph):
    # Small dictionary of how elements should be coloured
    colors_dict = {"C": "grey", "N": "green", "O": "red"}
    # Finds elements corresponding to nodes in the graph
    elements = nx.get_node_attributes(graph, name = "element")
    # Defines a list of colours for the nodes, accordingly
    element_colors = [colors_dict[elements[e]] for e in elements]
    # Displays the molecular graph
    nx.draw(graph, node_color=element_colors, with_labels=True, labels=nx.get_node_attributes(graph, name = "element"))
    plt.show()

# Runs the plotting function for serotonin
plot_graph(serotonin_graph)

# First three SMILES are valid fragments of serotonin, whereas the last is not
fragments = ['Oc:1:c:c:[c]:[c]:c1', 'NC[CH2]', 'CNCC', 'NC[CH2]:O:O:C']

# Converts fragments into Graph objects and displays them
for frag in fragments:
    fragment_graph = read_smiles(frag)
    plot_graph(fragment_graph)

在本例中,我们正在处理血清素,上面的代码可能会将其绘制成分子图,如下所示(请注意,我们使用的符号自动忽略氢原子):

Generated molecular graph for serotonin

代码中考虑的 4 个分子片段也可以绘制成图表,如下所示:

Graphs of molecular fragments

通过肉眼可以轻松推断出,前三个是血清素的有效子图,而最后一个(右下)则不是 - 例如,最后一个片段包含两个氧原子,而血清素图显然不包含。

因此,我希望获得一个能够执行以下操作的函数:

>>> subgraph_checker(serotonin_graph, valid_substructure)
True
>>> subgraph_checker(serotonin_graph, invalid_substructure)
False

因此,除了最后一个右下角的片段图之外,该函数将为上面的所有片段图返回 True。

这里已经提出了关于使用 NetworkX 进行子图搜索的类似问题,但到目前为止还没有一个足够 - 例如有些解决方案特定于有向图,或推荐无效的解决方案。

这是我尝试过的一种解决方案,但它不起作用,使用 NetworkX 的函数来搜索同构子图:

GM = nx.algorithms.isomorphism.GraphMatcher(serotonin_graph, fragment_graph)
print(GM.subgraph_is_isomorphic())

当将上述应用于所有片段时,所有片段都返回 True,当然最后一个片段不应该出现这种情况。

我还尝试了替代解决方案,例如使用 RDKit 函数来直接搜索血清素内的子结构,但这些解决方案效果不佳,而且似乎是一个错误。

非常感谢您通过 NetworkX 使用图论解决此问题的任何帮助或见解!

最佳答案

您仅通过查看图的结构来检查同构。相反,在您的情况下,您还需要检查每个节点的内容。换句话说,您应该定义两个节点(无边)何时相等。我认为在你的情况下,这两个节点共享相同的“元素”就足够了。

for frag in fragments:
    fragment_graph = read_smiles(frag)
    gm = nx.isomorphism.GraphMatcher(
        serotonin_graph,
        fragment_graph,
        node_match=lambda n1, n2: n1.get('element') == n2.get('element'),
    )
    print(gm.subgraph_is_isomorphic())

这是输出:

True
True
True
False

node_match 是一个返回 True 的函数,当且仅当在同构测试期间第一个图中的节点 n1 和第二个图中的节点 n2 应被视为相等。该函数将被调用如下: node_match(G1.nodes[n1], G2.nodes[n2])

也就是说,该函数将接收正在考虑的节点的节点属性字典。如果无,则在测试同构时不考虑任何属性。

更多信息可以找到here 。请注意,您还可以定义 edge_match 函数。

关于python - NetworkX 化学 : how to check if a smaller molecular graph A is a valid subgraph of a larger molecular graph B?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73530124/

相关文章:

algorithm - 广度优先搜索和层序遍历有什么区别?

python - 为什么我的 Python 代码可以在 Jupyter Notebook 中运行,但不能作为脚本运行?

python - NetworkX:从以列表为值的字典向图形添加边

python - 创建一个图形,其中节点为带有文本的圆圈

python - 为 Networkx 图添加标题?

data-structures - 以多面体图为键的映射

python - 与 Python 相比,具有动态分配的结构数组在 C 中运行非常慢

python - 如何按月屏蔽数据框?

python - Pyomo CBC 求解器错误 : Solver (cbc) returned non-zero return code (3221225781); Solver (cbc) did not exit normally

python - 计算矩阵与其转置的相关性