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

Python Networkx:获取DAG中所有可能的路径,python,graph,networkx,directed-graph,Python,Graph,Networkx,Directed 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] 我在这里遗漏了什么,为什

我试图根据连通性将有向无环图拆分为方向连通路径:

当我测试弱连通子图和强连通子图时,我得到以下结果:

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()

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

定义:强连通图


有向图G=V,E称为强连通,如果V中的每个顶点V都可以从V中的每个其他顶点到达。

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

定义:强连通图


如果V中的每个顶点V都可以从V中的每个其他顶点到达,则有向图G=V,E称为强连通图。

缺少的是以下定义:

[有向图]是强连通、双连通或简单连通的 如果包含从u到v的有向路径和有向路径,则为strong 对于每对顶点u,v,从v到u。强有力的组成部分是 极大强连通子图


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

您缺少的是以下定义:

[有向图]是强连通、双连通或简单连通的 如果包含从u到v的有向路径和有向路径,则为strong 对于每对顶点u,v,从v到u。强有力的组成部分是 极大强连通子图


所示图的任何两个节点之间都没有强连接,更不用说列出的3节点子图了。确实,您可以遍历3->41->39,但是没有返回41的路径,更不用说3了。因此,这张图没有很强的关联性。

因此,多亏了评论和回答,我意识到,对于我想要实现的目标,关联性是一个错误的线索。需要明确的是:我想在一个有向无环图中,得到所有起始节点到它们连接的结束节点之间的所有可能路径

因此,我最终编写了自己的解决方案,这很容易理解,但在性能或风格方面可能不是最好的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中有一个内置功能,那么我显然错过了它

,因此,多亏了评论和回答,我意识到连接对于我想要实现的目标来说是一个错误的引导。需要明确的是:我想在一个有向无环图中,得到所有起始节点到它们连接的结束节点之间的所有可能路径

因此,我最终编写了自己的解决方案,这很容易理解,但在性能或风格方面可能不是最好的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中有一个内置函数,我显然错过了它

强连接组件被定义为子图,这样就存在从任何节点到任何其他节点的路径。networkx给出的答案是正确的。也许你在寻找别的东西?那么[16,17]将是一个强连通子图,因为你可以从16中得到17,不是吗?或者你也需要从17中得到16吗?我想得到的是在这个图中得到所有可能的全定向路径,所以我从我的例子中得到[16,17],[42,39]和[3,41,39]。[16,17]不是强定向的,因为从17到16没有路径。我现在意识到这与连接性无关,我对那些过于具体的案件下了决心。一旦我知道我真正想要的是什么,我就会编辑我的帖子,因为强连接组件被定义为一个子图,这样就存在从任何节点到任何其他节点的路径。networkx给出的答案是正确的。也许你在寻找别的东西?那么[16,17]将是一个强连通子图,因为你可以从16中得到17,不是吗?或者你也需要从17中得到16吗?我想得到的是在这个图中得到所有可能的全定向路径,所以我从我的例子中得到[16,17],[42,39]和[3,41,39]。[16,17]不是强定向的,因为从17到16没有路径。我现在意识到这与连接性无关,我对那些过于具体的案件下了决心。一旦我知道我真正想要的是什么,我就会编辑我的帖子