【问题标题】:Transitive closure in a graph图中的传递闭包
【发布时间】:2015-11-09 13:23:02
【问题描述】:

我有一个有向图 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

【问题讨论】:

  • G 是有向图吗?这当然看起来应该有效。您是否尝试在for 循环中打印出所有边缘(v,u)

标签: python graph networkx


【解决方案1】:

您可以尝试迭代解决方案。首先,不要使用最后一个的所有节点和边创建一个新图,只需复制它:

TC = G.copy()

然后遍历节点,将所有neighbors的邻居添加为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) 将从a 中删除b 的条目。

使用列表推导可以减少提取所有邻居的 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

【讨论】:

  • 我试过你的代码,但似乎 TC = nx.copy(G) 不工作 文件“Graphs.py”,第 89 行,transitive_closure TC = nx.copy(G) TypeError: '模块的对象不可调用
  • @user4252332 所以,在我为你编写了整个函数之后,你甚至不能用 5 秒的时间自己解决这个错字吗?就像谷歌如何使用networkx 复制图表一样简单。我不会为你解决那个问题。
  • 好的,打扰您了。我更改了代码以解决复制问题。请问你如何获得而不是边缘(没有方向或双向的单向边缘)
  • @user4252332 不明白最后一个问题。就像现在的代码一样,它应该从x to z 生成定向边。你想要的行为是什么?
  • 没关系,对不起,这是我的错误
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多