[英]How can I extract all possible induced subgraphs from a given graph with networkx
I am wondering whether can I use networkx to extract all possible induced subgraphs (graphlets) with specific number of nodes in the subgraphs from an input large graph, or is there another package that can do the job? 我想知道我是否可以使用networkx从输入大图中提取子图中具有特定节点数的所有可能的诱导子图(graphlet),或者是否有其他包可以完成这项工作? For example, if I have a large graph, which is illustrated in networkx adjacency list format,
例如,如果我有一个大图,以networkx邻接列表格式说明,
graph G: 图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
which will be look like 这看起来像
if I want to extract graphlet with 3 nodes the algorithm should return me 如果我想用3个节点提取graphlet,算法应该返回给我
subgraph1: subgraph1:
1 2 3
2 1
3 1
[(1,2),(1,3)] [(1,2),(1,3)]
subgraph2:
subgraph2:
1 3 7
3 1
7 1
[(1,3),(1,7)] [(1,3),(1,7)]
subgraph3:
subgraph3:
3 4 5
4 3 5
5 3 4
[(3,4),(3,5),(4,5)] [(3,4),(3,5),(4,5)]
subgraph4,subgraph5,subgraph6... subgraph4,subgraph5,subgraph6 ...
The following is the code of the question suggested by @Hooked. 以下是@Hooked建议的问题代码。 Let's say n=3
假设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()
the the output will look like 输出看起来像
[(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)]
This assumes you want all matching subgraphs of a given target
which you'll have to define. 这假设您需要您必须定义的给定
target
所有匹配子图。 The native way is to loop over all combinations of nodes, find those connected then check for an isomorphism. 本机方式是遍历节点的所有组合,找到那些连接的节点,然后检查同构。 It's unclear if you want a network motif or a graphlet.
目前还不清楚你是否需要网络主题或图形。 In a graphlet all edges present in the original graph must be there - this would exclude 3-4-5 from your target.
在图表中,原始图表中存在的所有边都必须存在 - 这将从目标中排除3-4-5。 This method finds graphlets, to find motifs you'll have to check for each combination if there is an induced subgraph (and how many!).
这个方法找到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()
For me, this gives the edge set matches of: 对我来说,这给出了边缘集匹配:
[(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)]
Your examples are listed in here. 您的示例在此处列出。
For people who ended up here having the same problem but have too many nodes, here are few simple improvements on @Hooked's answer (although I am sure there are better solutions out there as @Hooked mentioned in comments, this is just a quick copy-paste fix for people who ended up here with the same reason as I did and had scaling problems) 对于那些最终遇到相同问题但节点太多的人来说,@ Hooked的答案很少有简单的改进(虽然我确信有更好的解决方案,因为@Hooked在评论中提到,这只是一个快速的副本 - 粘贴修复为最终在这里的人与我做的相同的原因,并有缩放问题)
1) igraph scales way better than networkx 1)igraph缩放方式比networkx更好
2) we can only take a neighborhood of a node to eliminate most of the unnecessary combinations 2)我们只能取一个节点的邻域来消除大多数不必要的组合
For example if we are looking for a motif
in larger network
(both igraph objects) 例如,如果我们正在寻找更大
network
的motif
(两个igraph对象)
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.