使用Networkx进行有向图遍历

时间:2018-07-09 23:52:39

标签: python pandas networkx

我有一个大的有向图(networkx.DiGraph()),它由几棵有向树组成,每棵有一个根。我还有一个函数,它可以接收特定的图形并输出其某些节点。这是我要执行的操作。

  1. 给出一个任意的有向林并提供一个级别,在该给定级别上剪切该图,然后通过该函数运行每个新创建的子图。
  2. 如果新创建图形的根出现在函数的输出中,请继续从该图形中删除该子图形。否则,从图中删除其所有后代。

我知道那很复杂,所以让我们看一下示例运行。

为简单起见,让我们的任意图是一棵树,而不是几棵树。我将选择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。

我为此感到抱歉,但实际上,我认为这是一系列简单步骤串联在一起的。但是,我的循环方法肯定不是最佳的。最好的方法是什么?

1 个答案:

答案 0 :(得分:1)

好吧,我要介绍的解决方案有点笨拙,但我愿意提出更多优化建议。

首先,我们将创建一个虚拟图进行测试

import networkx as nx
G = nx.balanced_tree(2,4,create_using=nx.DiGraph()) 

接下来,我们将dfs_tree networkx的API(使用最新版本)并使用depth_limit属性提取树,直到深度nn+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}