Networkx:获取DAG中所有可能的路径

时间:2019-04-16 15:41:09

标签: python graph networkx directed-graph

我正在尝试根据 connectivity 将有向(无环)图分成方向连接的路径:

Example graph

当我测试弱连通性图和强连通性子图时,这是我得到的:

Weak connectivity :
['16', '17'], ['3', '41', '39', '42']
Strong connectivity :
['17'], ['16'], ['39'], ['41'], ['3'], ['42']

我理解弱连通性的结果,但不理解强连通性的结果,因为我期望3个子图:[16、17],[42、39]和[3、41、39]。

我在这里想念的是什么,为什么那些单节点列表呢?如何获得预期的结果?

这是代码:

import networkx as nx
import matplotlib.pyplot as plt

G = nx.DiGraph()
G.add_edges_from([('16', '17'), ('3', '41'), ('41', '39'), ('42', '39')])

print("Weak connectivity : ")
for subgraph in (G.subgraph(c).copy() for c in nx.weakly_connected_components(G)) :
    print(subgraph.nodes)
print("Strong connectivity : ")
for subgraph in (G.subgraph(c).copy() for c in nx.strongly_connected_components(G)) :
    print(subgraph.nodes)

nx.draw_networkx(G, pos=nx.circular_layout(G))
plt.show()

3 个答案:

答案 0 :(得分:1)

您缺少的是strongly connected的定义:

  

[有向图]是牢固连接,相互连接或简单连接的   如果包含从u到v的定向路径和定向路径,则为强   从v到u,每对顶点u,v。强分量是   最大强连通子图。

在显示的图的任何两个节点之间没有没有牢固的连接,更不用说列出的3节点子图了。实际上,您可以遍历3-> 41-> 39,但是没有返回41的路径,更不用说3了。因此,该图不是牢固连接。

答案 1 :(得分:1)

因此,多亏了评论和答案,我意识到“连接性”对于我想要实现的目标是错误的。需要明确的是:我想在有向无环图中以所有起始节点到其连接的终止节点之间的所有可能路径作为路径

因此,我最终编写了自己的解决方案,该解决方案很容易理解,但关于性能或样式(pythonic / networkx)可能不是最好的。欢迎提出改进建议:)

import networkx as nx
import matplotlib.pyplot as plt

G = nx.DiGraph()
G.add_edges_from([('16', '17'), ('3', '41'), ('41', '39'), ('42', '39')])

roots = []
leaves = []
for node in G.nodes :
  if G.in_degree(node) == 0 : # it's a root
    roots.append(node)
  elif G.out_degree(node) == 0 : # it's a leaf
    leaves.append(node)

for root in roots :
  for leaf in leaves :
    for path in nx.all_simple_paths(G, root, leaf) :
      print(path)

nx.draw_networkx(G, pos=nx.circular_layout(G))
plt.show()

(如果networkx中有内置功能,我显然会错过它)

答案 2 :(得分:0)

根据强连通图的定义,您得到的结果是正确的。

定义:强连通图

如果V中的每个顶点v均可从V中的其他顶点到达,则称有向图G =(V,E)是强连通的。