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

时间:2014-03-04 18:50:40

标签: python graph extract networkx subgraph

我想知道我是否可以使用networkx从输入大图中提取子图中具有特定节点数的所有可能的诱导子图(graphlet),或者是否有其他包可以完成这项工作?例如,如果我有一个大图,以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

看起来像

enter image description here

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

subgraph1:

1 2 3
2 1
3 1

[(1,2),(1,3)] enter image description here subgraph2:

1 3 7
3 1
7 1

[(1,3),(1,7)] enter image description here subgraph3:

3 4 5
4 3 5
5 3 4

[(3,4),(3,5),(4,5)] enter image description here

subgraph4,subgraph5,subgraph6 ...

以下是@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)]

2 个答案:

答案 0 :(得分:9)

这假设您需要您必须定义的给定target的所有匹配子图。本机方式是遍历节点的所有组合,找到那些连接的节点,然后检查同构。目前还不清楚你是否需要网络主题或图形。在图表中,原始图表中存在的所有边都必须存在 - 这将从目标中排除3-4-5。如果有一个诱导子图(以及有多少!),这个方法会找到graphlet,找到你必须检查每个组合的图案。

import networkx as nx

g = nx.Graph()
g.add_edge(1,2);g.add_edge(1,3)
g.add_edge(1,7);g.add_edge(2,4)
g.add_edge(3,4);g.add_edge(3,5)
g.add_edge(3,6);g.add_edge(4,5)
g.add_edge(5,6);g.add_edge(6,7)

import itertools

target = nx.Graph()
target.add_edge(1,2)
target.add_edge(2,3)

for sub_nodes in itertools.combinations(g.nodes(),len(target.nodes())):
    subg = g.subgraph(sub_nodes)
    if nx.is_connected(subg) and nx.is_isomorphic(subg, target):
        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, 6)]
[(3, 6), (6, 7)]
[(4, 5), (5, 6)]
[(5, 6), (6, 7)]

您的示例在此处列出。

答案 1 :(得分:0)

对于那些遇到同样问题但节点太多的人来说,@ Hooked的答案很少有简单的改进(虽然我确信有更好的解决方案,因为@Hooked在评论中提到,这只是一个快速的复制粘贴修复程序,适用于那些以与我相同的原因结束此处并且存在扩展问题的人员。

1)igraph缩放方式比networkx更好

2)我们只能取一个节点的邻域来消除大部分不必要的组合

例如,如果我们在较大的motif(两个igraph对象)中寻找network

    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