Удалить обратимые ребра из ориентированного графа networkx - PullRequest
0 голосов
/ 20 апреля 2019

Есть ли способ удаления обратимых ребер в графе. Например, скажем, следующий график

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 Ответ

0 голосов
/ 20 апреля 2019

Метод 1:

удалить дубликаты записей в списке ребер -> удалить все из графика -> добавить обратно отдельные ребра => график с одиночными ребрами

Края сохраненыкак кортежи.Вы можете потерять информацию индекса путем временного преобразования в наборы.Затем вы можете потерять дубликаты кортежей, опять же, путем временного преобразования в набор.После преобразования обратно в список у вас есть список ребер с удаленными дублирующимися записями, например:

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)

Метод 2:

найти повторяющиеся ребра -> удалить только те из графа => граф с одиночными ребрами

снова, потеря позиционной информации путем преобразования в наборы:

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 не сохраняет порядок, в котором были добавлены ребра, поэтому, если вы не хотите писать дополнительную логику, вы либо удалитевсе повторяющиеся ребра идут от узлов с меньшим номером к узлам с большим номером или наоборот.

...