【问题标题】:Remove reversible edges from directed graph networkx从有向图网络中删除可逆边
【发布时间】:2019-04-21 14:52:48
【问题描述】:

有没有办法去除图中的可逆边。比如下面这张图

import networkx as nx
G=nx.DiGraph()
G.add_edge(1,2)
G.add_edge(2,3)
G.add_edge(2,1)
G.add_edge(3,1)
print (G.edges())

[(1, 2), (2, 3), (2,1), (3,1)]

我想删除 (2,1) 和 (3,1),因为我希望图形只指向一个方向。我知道您可以使用G.remove_edges_from(G.selfloop_edges()) 删除自循环,但这里不是这种情况。我正在寻找的输出是[(1, 2), (2, 3)]。一旦通过networkx或其他图形工具(如cytoscape)创建图形,有没有办法删除这些边?

【问题讨论】:

    标签: python graph networkx


    【解决方案1】:

    方法一:

    删除 edgelist 中的重复条目 -> 从图中删除所有内容 -> 添加回单边 => 带有单边的图

    边存储为元组。您可能会通过临时转换为集合而丢失索引信息。然后,您可能会再次通过临时转换为集合来丢失重复的元组。转换回列表后,您将获得边缘列表,并删除了重复条目,如下所示:

    stripped_list = list(set([tuple(set(edge)) for edge in G.edges()]))
    

    然后从图中删除当前存在的所有边,并添加回刚刚创建的列表中的边:

    G.remove_edges_from([e for e in G.edges()])
    G.add_edges_from(stripped_list)
    

    方法二:

    找到重复的边 -> 只从图中删除那些 => 带有单边的图

    再次,通过转换为集合而丢失位置信息:

    set_list = [set(a) for a in G.edges()] # collect all edges, lose positional information
    remove_list = [] # initialise
    
    for i in range(len(set_list)):
        edge = set_list.pop(0) # look at zeroth element in list:
    
        # if there is still an edge like the current one in the list, 
        # add the current edge to the remove list:
        if set_list.count(edge) > 0:
            u,v = edge 
    
            # add the reversed edge
            remove_list.append((v, u))
    
            # alternatively, add the original edge: 
            # remove_list.append((u, v))
    
    G.remove_edges_from(remove_list) # remove all edges collected above
    

    据我所知,networkx 不存储添加边的顺序,因此除非您想编写更多逻辑,否则您要么删除从编号较小的节点到编号较大的节点的所有重复边,或者反过来。

    【讨论】:

    • 您的提案将获得一个唯一的集合列表,但我认为它会增加新的优势。我编辑问题只是为了使所需的输出更清楚。
    • 方法 1 确实添加了新边,但首先删除了所有边,所以你最终只会得到唯一的边。因为您丢失了所有边缘的方向信息,所以一些边缘可能会被翻转。我添加了另一种方法,它只删除重复项。
    猜你喜欢
    • 2017-08-26
    • 1970-01-01
    • 1970-01-01
    • 2017-05-08
    • 1970-01-01
    • 2017-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多