关于python:NetworkX DiGraph按节点创建子图(DiGraph)

NetworkX DiGraph create subgraph (DiGraph) by node

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

like G.subgraph(3) returns a new DiGraph from the red area.

enter image description here

例如,我创建一个DiGraph:

1
2
3
4
5
6
7
8
9
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/generation/networkx.Graph.subgraph.html并将其转换为单向。我测试了out_egdes,strong / weak_connected_component,但从未成功。
我还查看了如何在有向图中查找子图而不转换为无向图?和Networkx:提取包含给定节点的有向组件(有向图)。

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

有人可以告诉我该怎么做吗?如果结果图也是DiGraph


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

1
2
3
4
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)

我复制了代码以创建图形,初始化了一个空的有向图,并按如下所示调用了函数:

1
2
3
4
5
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


详细阐述@vaettchen关于如何从点文件中提取子图的神秘评论

  • 从https://gist.github.com/blabber/74b8d9ed59d0b2ad0d7a734113996424#file-reduce-g

    中获取gvpr命令文件reduce.g

  • reduce.g上运行gvpr

  • 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


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

    1
    2
    3
    4
    5
    6
    7
    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)

    或单向的简洁版本:

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

    在我看来,内置版本的速度是递归版本的3倍。它从5000个节点中细分了3000个:

    1
    2
    3
    4
    5
    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