Python 如何使用networkx从给定的图中提取所有可能的诱导子图

Python 如何使用networkx从给定的图中提取所有可能的诱导子图,python,graph,extract,networkx,subgraph,Python,Graph,Extract,Networkx,Subgraph,我想知道是否可以使用networkx从输入的大型图中提取子图中具有特定节点数的所有可能的诱导子图(图),或者是否有其他包可以完成这项工作?例如,如果我有一个用networkx邻接列表格式显示的大型图形 图G: 1 2 3 7 2 1 4 3 1 4 6 5 4 2 3 5 5 3 4 6 6 3 5 7 7 1 6 看起来是什么样子 如果我想提取具有3个节点的graphlet,算法应该返回我 子图1: 1 2 3 2 1 3 1 [(1,2)、(1,3)] 子图2: 1 3 7 3 1 7

我想知道是否可以使用networkx从输入的大型图中提取子图中具有特定节点数的所有可能的诱导子图(图),或者是否有其他包可以完成这项工作?例如,如果我有一个用networkx邻接列表格式显示的大型图形

图G:

1 2 3 7
2 1 4
3 1 4 6 5
4 2 3 5
5 3 4 6
6 3 5 7
7 1 6
看起来是什么样子

如果我想提取具有3个节点的graphlet,算法应该返回我

子图1:

1 2 3
2 1
3 1
[(1,2)、(1,3)] 子图2:

1 3 7
3 1
7 1
[(1,3)、(1,7)] 子图3:

3 4 5
4 3 5
5 3 4
[(3,4)、(3,5)、(4,5)]

子图4,子图5,子图6

以下是@Hooked建议的问题代码。 假设n=3

import itertools
target = nx.complete_graph(3)
for sub_nodes in itertools.combinations(g.nodes(),len(target.nodes())):
    subg = g.subgraph(sub_nodes)
    if nx.is_connected(subg):
        print subg.edges()
输出结果如下所示

[(1, 2), (1, 3)]
[(1, 2), (2, 4)]
[(1, 2), (1, 7)]
[(1, 3), (3, 4)]
[(1, 3), (3, 5)]
[(1, 3), (3, 6)]
[(1, 3), (1, 7)]
[(1, 7), (6, 7)]
[(2, 4), (3, 4)]
[(2, 4), (4, 5)]
[(3, 4), (3, 5), (4, 5)]
[(3, 4), (3, 6)]
[(3, 5), (3, 6), (5, 6)]
[(3, 6), (6, 7)]
[(4, 5), (5, 6)]
[(5, 6), (6, 7)]

这假设您需要给定
目标的所有匹配子图,您必须定义这些子图。本机方法是在所有节点组合上循环,找到那些连接的节点,然后检查同构。现在还不清楚你想要的是网络图案还是笔画。在图形中,原始图形中的所有边都必须在那里-这将从目标中排除3-4-5。这个方法可以找到图形,要找到图案,你必须检查每个组合是否有一个诱导子图(以及有多少个!)

对我来说,这提供了以下边集匹配:

[(1, 2), (1, 3)]
[(1, 2), (2, 4)]
[(1, 2), (1, 7)]
[(1, 3), (3, 4)]
[(1, 3), (3, 5)]
[(1, 3), (3, 6)]
[(1, 3), (1, 7)]
[(1, 7), (6, 7)]
[(2, 4), (3, 4)]
[(2, 4), (4, 5)]
[(3, 4), (3, 6)]
[(3, 6), (6, 7)]
[(4, 5), (5, 6)]
[(5, 6), (6, 7)]

这里列出了您的示例。

对于那些在这里遇到相同问题但节点太多的人,这里有一些关于@Hooked答案的简单改进(虽然我确信有更好的解决方案,如评论中提到的@Hooked,但这只是一个快速复制粘贴修复程序,适用于那些以与我相同的原因来到这里并遇到缩放问题的人)

1) igraph比networkx更具扩展性

2) 我们只能利用节点的一个邻域来消除大多数不必要的组合

例如,如果我们在更大的
网络中寻找
主题
(两个igraph对象)


你是说非同构诱导子图吗?为什么不在345上画三角形呢?@hivert Graphles对我来说也是一个新名词。维基百科上说它们是“…大型网络的小连通非同构诱导子图”。@Hooked:triangle 3 4 5是连通的。@hivert抱歉我不清楚,我是在回答你的问题,OP是否指非同构诱导子图,但试图解释“graphlet”的含义。是的,3,4,5是连接的,是的,如果我理解这个问题,我想应该包括它。@Hooked:因为连接这个词在问题的任何地方都没有出现,我不确定OP是否也有这个意思!感谢您的回答,但我的目的是,对于给定的大图G和子图n中的节点数,我想提取所有可能的3节点连通子图,这些子图包含与原始大图相同的边。@我不确定是否理解。列出的每个集合都是一个适当的诱导子图。您的两个示例是该列表中的
[(1,2)、(1,3)]
[(1,3)、(1,7)]
<代码>[(3,4)、(4,5)]
不在建议注释中列出的范围内,因为它不会是一个诱导子图,因为需要存在边
(5,3)
。[(3,4)、(4,5)、(3,5)]也应在列表中。该算法将生成许多子图。我的示例不够清楚,因为只有一个子图样式。@tohnperfect如果将
target
更改为三个节点(K3)上的完整图,此算法将匹配它。您的示例仅在三个节点上与折线图匹配,这就是我所看到的。如果删除对
target
的检查,
nx.is_同构(subg,target)
您将获得给定大小n的所有匹配项。如果您的graphlet大于几个节点,您将开始遇到其他问题
itertools.combinations
是一个组合过程,它尝试节点的每个组合,例如,100个主节点和10个节点的子图。这大约是10^13个组合。有更聪明的方法来解决这个问题,但这超出了问题的范围。尝试数学堆栈交换一些想法,因为这偏离了编程领域。
[(1, 2), (1, 3)]
[(1, 2), (2, 4)]
[(1, 2), (1, 7)]
[(1, 3), (3, 4)]
[(1, 3), (3, 5)]
[(1, 3), (3, 6)]
[(1, 3), (1, 7)]
[(1, 7), (6, 7)]
[(2, 4), (3, 4)]
[(2, 4), (4, 5)]
[(3, 4), (3, 6)]
[(3, 6), (6, 7)]
[(4, 5), (5, 6)]
[(5, 6), (6, 7)]
    motif_rank = max(max(motif.shortest_paths_dijkstra()))
    result = collections.OrderedDict.fromkeys(network.vs['label'], 0)

    for node in self.network.vs:
        # Get relevant nodes around node of interest that might create the motif of interest
        nodes_to_expand = {node}
        for rank in range(motif_rank):
            nodes_expanded = nodes_to_expand
            for node_to_expand in nodes_to_expand:
                nodes_expanded = set.union(nodes_expanded, set(node_to_expand.neighbors()))
            nodes_to_expand = nodes_expanded

        # Look at all combinations
        for sub_nodes in itertools.combinations(nodes_to_expand, motif.vcount()):
            subg = network.subgraph(sub_nodes)
            if subg.is_connected() and subg.isomorphic(motif):
                result[node['label']] = result[node['label']]+1