我想在此图中识别满足以下条件的所有此类节点组:
组中的所有节点都没有相互连接
组中的节点具有完全相同的父节点和子节点集
例如,将从上图获得以下节点组:
第1组:{3,4,5,6,7,8}
第2组:{16,17}
第3组:{19,20}
第4组:{21,22}
我有成千上万的这样的图表(有些图表有10k个节点)。我正在寻找一种使用networkx在Python中执行此操作的有效算法。
由于
答案 0 :(得分:3)
请注意,第一个请求是多余的,因为第二个请求会覆盖它。对于两个连接的节点,不可能具有相同的父和子集。对于连接的节点,一个节点在父集中具有其他节点,在子集中具有反节点。
因此,同一组中的节点具有相同的父节点和子节点集。在python中,有一个简单的解决方案,通过父对子集和子集对进行dict索引来实现。我不确定它的效率如何,但值得一试。
from collections import defaultdict
children = {
1: [2, 3, 4, 5, 6, 7, 8],
2: [3, 4, 5, 6, 7, 8, 9],
3: [9, 10],
4: [9, 10],
5: [9, 10],
6: [9, 10],
7: [9, 10],
8: [9, 10],
9: [10],
10: [11, 12, 13],
11: [14, 15],
12: [13, 14, 15],
13: [16, 17],
14: [16, 17],
15: [16, 17],
16: [18],
17: [18],
18: [19, 20],
19: [21, 22],
20: [21, 22],
21: [],
22: [],
}
# Collect parents
parents = defaultdict(list)
for a, bs in children.iteritems():
for b in bs:
parents[b].append(a)
# Use default dict to collect nodes that have same parents and children
store = defaultdict(list)
for node in children.iterkeys():
store[(tuple(sorted(children[node])), tuple(sorted(parents[node])))].append(node)
# Result
for s in store.itervalues():
if len(s) > 1:
print s
从图像来看,组{11,12}不是结果。 11未连接到13。
答案 1 :(得分:0)
Ante为我的问题提供了一个优雅的解决方案。 我已经修改了他的代码,以便与Python 3.5中的networkx图一起使用
给定有向无环图G
。
lineage = defaultdict(list)
for node in G.nodes():
lineage[frozenset(G.predecessors(node)), frozenset(G.successors(node))].append(node)
for i in lineage.values():
if len(i) > 1:
print (i) # a list containing the groups defined in the question
再次感谢Stack Overflow!