Удалить все ребра из графа в networkx

Я выполняю следующие команды python, пытаясь удалить все ребра из графа G.

def method(G):
  edges = G.edges()
  G.remove_edges_from(edges)

Но это дает следующую ошибку:

RuntimeError: dictionary changed size during iteration.

Кажется, что команда выполняет итерацию по ребрам, но когда я удаляю ребро, она изменяет итератор во время итерации, что вызывает ошибку.

Как мне это обойти?

Что такое type(edges)? Вы умеете делать edges = G.edges().copy()?

Mad Physicist 10.09.2018 07:33
5
1
5 040
3

Ответы 3

Вы можете изучить метод create_empty_copy, который копирует узлы без ребер в новый граф. Документы буквально читают:

Return a copy of the graph G with all of the edges removed.

Если вы хотите сохранить исходный график как есть, вы можете сделать что-то вроде

edges = list(G.edges)

чтобы убедиться, что вы копируете края, прежде чем запрашивать их удаление.

Будьте осторожны, чтобы края не имели атрибута копирования! Вы должны сделать что-то вроде: edges = list(G.edges.keys())

Lucas 10.09.2018 07:49

@ Лукас. Спасибо. Фиксированный.

Mad Physicist 10.09.2018 07:51

В пакете networkx уже есть несколько методов:

  1. remove_edges_from: удалить все ребра из графа
  2. clear: удалить все узлы и ребра из графа

почему бы просто не использовать любой из них для своих нужд? например.,

G.remove_edges_from(G.edges()) должен выполнять эту работу вместо того, чтобы определять еще одну функцию, выполняющую то же самое. Например, рассмотрим следующий код, запущенный на python 3.5 в Windows 11 с jupyter notebook:

import platform 
print(platform.python_version())
# 3.5.4
import networkx as nx
print(nx.__version__)
# 1.11
G=nx.complete_graph(5)
print(G.edges())
# [(0, 1), (0, 2), (0, 3), (0, 4), (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]
G.remove_edges_from(G.edges())
print(G.edges())
# []    

Ваше предложение фактически то, что OP сказал, что не удалось.

Joel 10.09.2018 09:38
G.remove_edges_from(G.edges()) не работает на моем компьютере с версией 2.0 (и получает те же отчеты об ошибках). OP использует G.remove_edges_from(edges) вместо edges=G.edges(), поэтому я достаточно уверен, что он эквивалентен G.remove_edges_from(G.edges()).
Joel 10.09.2018 19:10

@Joel обновил платформу os, версию python и версию networkx, для которых работает приведенный выше код.

Sandipan Dey 10.09.2018 19:36

имеет смысл - в networkx 2.0 вывод G.edges() поменял тип.

Joel 10.09.2018 20:31

Я не уверен, насколько здесь уместен clear, но хорошо знать, что разница между старой и новой версией заключается в том, что у новой, по-видимому, меньше накладных расходов.

Mad Physicist 10.09.2018 20:36

G.edges - это «представление ребер», а G.edges () - «представление данных ребер», которые привязаны к графу и обновляются при каждом изменении графа.

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

Следовательно, вы можете использовать эти обходные пути:

G.remove_edges_from(list(G.edges()))
G.remove_edges_from(list(G.edges))
G.remove_edges_from(dict(G.edges))

Другие вопросы по теме