2015-03-30 3 views
0

Заданный ориентированный сетевой график. Я хотел бы иметь функцию, например «abc()», для каждого узла, который удален из графика. Я просмотрел документацию networkx, но не нашел такой функции обратного вызова.Обратный вызов удаления/удаления узла Networkx

То, что я считал:

  1. Добавление вызова abc() к (Разрушитель) метод __del__() объекта, связанного с узлом. Тем не менее, помимо ловушек использования __del__() (см., Например, here), это не работает, если какие-либо ссылки на объект узла существуют где-то в памяти.
  2. Подкласс класса networkx.DiGraph() и переопределение метода remove_node(). Недостаток: для этого потребуется переопределить все методы, удаляющие узел, например. remove_nodes_from (есть ли еще?)
  3. Поскольку реализация графика gridx основана на словарях, это может быть решением как-то «подключить» функцию del этого словаря. Однако вмешательство этого в сетевую систему кажется неуместным.

Что является самым простым способом реализации функции обратного вызова, которая вызывается каждый раз, когда удаляется узел networkx?

+1

Вам просто нужно настроить два метода на подкласс: DiGraph.remove_node() и DiGraph_remove_nodes_from(). Взгляните на https://github.com/networkx/networkx/blob/master/examples/subclass/printgraph.py. Я думаю, что это в основном то, что вы хотите. – Aric

+0

Итак, вы предлагаете второй из указанных выше вариантов. Это имеет смысл, поскольку я ошибался, полагая, что удаление ребер может удалить узлы. Если есть только две две функции, которые удаляют узлы, это, вероятно, лучший подход. В настоящий момент я не могу принять ваш ответ, поскольку это комментарий. Не могли бы вы перевести его в ответ? – stackoverflowwww

ответ

1

В этом случае вам нужно только подклассифицировать два метода. Вот пример из NetworkX импорта Digraph

class RemoveNodeDiGraph(DiGraph): 
    def remove_node(self, n): 
     DiGraph.remove_node(self, n) 
     print("Remove node: %s"%n) 

    def remove_nodes_from(self, nodes): 
     for n in nodes: 
      self.remove_node(n) 

if __name__=='__main__': 
    G = RemoveNodeDiGraph() 
    G.add_node('foo') 
    G.add_nodes_from('bar',weight=8) 
    G.remove_node('b') 
    G.remove_nodes_from('ar') 

Это не будет столь же быстро, как и оригинальные методы в классе орграфа (особенно remove_nodes_from()), но если у вас нет очень больших графов это не будет, вероятно, быть значительным. Если вам нужна более высокая производительность, вы можете скопировать код непосредственно из этих методов вместо вызова суперкласса.

+0

Один небольшой комментарий: Как я понимаю, 'adj = self.adj' не является необходимым, не так ли? Я имею в виду, что он не используется в вашем фрагменте кода и удаляет края из или, к целевому узлу позаботится 'remove_node'. BTW: То же самое относится к 'remove_nodes_from' в подклассе образца в https://github.com/networkx/networkx/blob/master/examples/subclass/printgraph.py Или я что-то упускаю? – stackoverflowwww

+1

Еще один намек на любого, кто также пойдет на это решение: обратите внимание, что оригинальный 'Digraph.remove_nodes_from()' "молча игнорирует, если узел в контейнере отсутствует в графике". Использование (аккуратного) решения от Aric вызовет исключение, если узел не найден, поскольку это регулярное поведение для 'remove_node()'. – stackoverflowwww

+0

Вы правы - я удалил эту дополнительную строку. – Aric

Смежные вопросы