图中的传递闭包

时间:2015-11-09 13:23:03

标签: python graph networkx

我有一张有向图 X-> Y Y-> Z

我想补充一下这个grpah传递闭包 X-> Z

我在算法中应该改变什么现在我在两个方向上创建x,y和z之间的所有可能组合。

我的代码如下。

def transitive_closure(G):
    TC = nx.DiGraph()
    TC.add_nodes_from(G.nodes())
    TC.add_edges_from(G.edges())
    for v in G:
        TC.add_edges_from((v, u) for u in nx.dfs_preorder_nodes(G, source=v)
                      if v != u)
    return TC

1 个答案:

答案 0 :(得分:1)

您可以尝试迭代解决方案。首先,不要创建包含最后一个节点和边缘的新图形,而是复制它:

TC = G.copy()

然后迭代节点并将邻居的所有邻居添加为x的邻居:

for x in G:
    # Extract all neighbours of neighbours of x (from G)
    all_nh = []
    for y in G.neighbours(x):
        all_nh += G.neighbours(y)

    # Remove from the list of neighbors the current node and its immediate neighbors
    all_nh = set(all_nh) - set([x]) - set(G.neighbours(x))

    # Create new edges (x -> z)
    edges = map(lambda z: (x, z), all_nh)

    # Add them to the new graph
    TC.add_edges_from(edges)

请注意,python中的set唯一值的容器,因此set(a) - set(b)会从b中删除a的条目。

通过使用列表解析,可以减少提取邻居的所有邻居的for循环并且(可能加速)更多:

all_nh = [z for y in G.neighbors(x) for z in G.neighbors(y)]

产生这样的东西:

def transitive_closure(G):
    TC = G.copy()
    for x in G:
        all_nh = [z for y in G.neighbors(x) for z in G.neighbors(y)]
        all_nh = set(all_nh) - set([x]) - set(G.neighbors(x))
        edges = map(lambda z: (x, z), all_nh)
        TC.add_edges_from(edges)
    return TC