关于python:从有向图networkx中删除可逆边

Remove reversible edges from directed graph networkx

有没有一种方法可以消除图中的可逆边缘。 例如,假设下图

1
2
3
4
5
6
7
8
9
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)创建了图,是否有办法消除这些边缘?


方法1:

删除边列表中的重复条目->从图形中删除所有内容->添加单个边=>具有单个边的图

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

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

然后从图中移除所有当前存在的边,然后重新添加刚创建的列表中的边:

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

方法2:

查找重复的边->仅从图上删除那些边=>单边图

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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不会存储添加边的顺序,因此除非您要编写进一步的逻辑,否则您将删除所有重复的边(从编号较小的节点到编号较大的节点),或者反过来。