我有一个大的有向图(networkx.DiGraph()),它由几棵有向树组成,每棵有一个根。我还有一个函数,它可以接收特定的图形并输出其某些节点。这是我要执行的操作。
我知道那很复杂,所以让我们看一下示例运行。
为简单起见,让我们的任意图是一棵树,而不是几棵树。我将选择nx.balanced_tree(2,4,create_using = nx.DiGraph())作为我的图。该图的边列表如下所示
(0,1),(0,2),(1,3),(1,4),(2,5),(2,6),(3,7),(3,8),(4,9),(4,10),(5,11),(5,12),(6,13),(6,14),
(7,15),(7,16),(8,17),(8,18),(9,19),(9,20),(10,21),(10,22),(11,23),(11,24),(12,25),(12,26),
(13,27),(13,28),(14,29),(14,30)
请注意,0具有0级,1-2具有1级,3-6具有2级,7-14具有3级,15-30具有4级。
假设我在程序中输入了3。然后,我将级别3中的每个节点作为其自己的子图的根,并在程序中处理每个节点。因此,子图表示为
Subgraph 1: (7,15),(7,16)
Subgraph 2: (8,17),(8,18)
etc
将被输入到我的函数中。让函数输出7作为节点,但不输出8。然后,应将所有节点7、15、16都删除,而将节点17和18删除,而不是8。
我为此感到抱歉,但实际上,我认为这是一系列简单步骤串联在一起的。但是,我的循环方法肯定不是最佳的。最好的方法是什么?
答案 0 :(得分:1)
好吧,我要介绍的解决方案有点笨拙,但我愿意提出更多优化建议。
首先,我们将创建一个虚拟图进行测试
import networkx as nx
G = nx.balanced_tree(2,4,create_using=nx.DiGraph())
接下来,我们将dfs_tree networkx的API(使用最新版本)并使用depth_limit
属性提取树,直到深度n
和n+1
,其中{{1 }}是用户输入的深度(因为它从1开始索引深度)
n+1
然后对深度T1 = nx.dfs_tree(G, source=0,depth_limit=3) #here n=3
T1_edges = list(T.edges())
#[(0, 1), (0, 2), (1, 3), (1, 4), (2, 5), (2, 6), (3, 8), (3, 7), (4, 9), (4, 10), (5, 11), (5, 12), (6, 13), (6, 14)]
做同样的操作
n+1
现在对这两个列表进行异或
T2 = nx.dfs_tree(G, source=0,depth_limit=4)
T2_edges =list(T2.edges())
#[(0, 1), (0, 2), (1, 3), (1, 4), (2, 5), (2, 6), (3, 8), (3, 7), (4, 9), (4, 10), (5, 11), (5, 12), (6, 13), (6, 14), (7, 16), (7, 15), (8, 17), (8, 18), (9, 19), (9, 20), (10, 21), (10, 22), (11, 24), (11, 23), (12, 25), (12, 26), (13, 27), (13, 28), (14, 29), (14, 30)]
这些是第3层的边缘。现在提取这些层上的节点
edges_left = list(set(T1_edges).symmetric_difference(T2_edges))
#[(14, 30), (11, 23), (10, 21), (7, 16), (11, 24), (7, 15), (10, 22), (9, 20), (12, 25), (13, 28), (8, 17), (14, 29), (12, 26), (13, 27), (8, 18), (9, 19)]
然后使用bfs_tree在这些节点上提取树
nodes_at_level = set([x[0] for x in edges_left])
#{7, 8, 9, 10, 11, 12, 13, 14}