NetworkX DiGraph按节点创建子图(DiGraph)

时间:2015-10-04 16:06:38

标签: python networkx subgraph

我想按节点得到一个子图(红色区域): 子图由输入节点可到达的所有节点组成。

  

像G.subgraph(3)从红色区域返回一个新的DiGraph。

enter image description here

例如,我创建了一个DiGraph:

import networkx as nx
G = nx.DiGraph()

G.add_path([1,2,3,4])
G.add_path([3,'a','b'])

A = nx.to_agraph(G)
A.layout()
A.draw('graph.png')

我调查https://networkx.github.io/documentation/latest/reference/generated/networkx.Graph.subgraph.html并将其转换为单向。我测试了out_egdes,strong / weak_connected_component,但它从未奏效。 我还查看了How to find subgraphs in a directed graph without converting to undirected graph?Networkx: extract the connected component containing a given node (directed graph)

我知道Subgraph在DiGraph中不起作用。

有人可以告诉我该怎么做吗?如果得到的Graph也是DiGraph

,那将会很好

3 个答案:

答案 0 :(得分:3)

根据我的理解,子图的创建标准取决于从输入节点可到达的节点。然后,下面的递归函数应该足以完成工作。

def create_subgraph(G,sub_G,start_node):
    for n in G.successors_iter(start_node):
        sub_G.add_path([start_node,n])
        create_subgraph(G,sub_G,n)

我复制了你的代码来创建图表,初始化了一个空的Directed图,并调用了如下函数:

G = nx.DiGraph()
G.add_path([1,2,3,4])
G.add_path([3,'a','b'])
sub_G = nx.DiGraph()
create_subgraph(G, sub_G,3)

结果Digraph显示在图中。enter image description here

答案 1 :(得分:2)

使用内置遍历算法可以获得更好的性能,支持双向选项,并避免递归深度限制。

def create_subgraph(G, node):
    edges = nx.dfs_successors(G, node)
    nodes = []
    for k,v in edges.items():
        nodes.extend([k])
        nodes.extend(v)
    return G.subgraph(nodes)

或单向的简洁版本:

def create_subgraph(G, node):
    nodes = nx.single_source_shortest_path(G,node).keys()
    return G.subgraph(nodes)

在我的情况下,内置版本的速度是递归版本的3倍。它来自5000个节点的子图3000:

In [1]: %timeit -n10 use_built_in('O_CONTRACT_PRODUCT') 
10 loops, best of 3: 102 ms per loop 

In [2]: %timeit -n10 use_recursive('O_CONTRACT_PRODUCT')
10 loops, best of 3: 341 ms per loop

create_subgraph(G,3)的结果如图所示: enter image description here

答案 2 :(得分:0)

详细阐述@ vaettchen对How to extract a subgraph from a dot file

的神秘评论
  1. https://gist.github.com/blabber/74b8d9ed59d0b2ad0d7a734113996424#file-reduce-g

  2. 抓取gvpr命令文件reduce.g
  3. gvpr上运行reduce.g

  4. gvpr -f reduce.g -a '"3" 10' mygraph.dot > myreduced.graph.dot

    其中-areduce.g程序的参数,即目标节点= 3和要跟随的跃点。如果你跳过-a,它会告诉你它。

    This script takes exactly two parameter. 1: name of node, 2: number of hops

    现在,因为它reduce.g似乎确实修改了图表 - 我从水平方向切换到垂直方向。

    顺便说一下,由于将参数输入到bash脚本中,我对引号有很多不满,我补充说它有用。

    gvpr -f reduce.g -a " \"$node_to_select\" 10" mygraph.dot