Python Networkx, автоматически обновляющий атрибуты

все. Я создаю DiGraph, используя NetworkX, и повторяю алгоритм над ним. В определенной итерации каждый узел «n» изменяет определенный атрибут, скажем, «A_n». Теперь каждое ребро, относящееся к этому конкретному узлу «n» и данному предшественнику «m», имеет еще один интересующий атрибут, который зависит от «A_n», назовем его «B_mn». Мой вопрос: возможно ли обновить «B_mn» «автоматически», изменив «A_n» для всех «n», «m» в моем наборе узлов? Я имею в виду не перебор узлов, а затем их предшественников, а использование некой динамической функции "B_mn(A_n)", которая меняет свое значение в тот момент, когда изменяется "A_n". Это возможно?

Я думаю примерно так:

Пусть X и Y - числа, предположим, что

G.node["n"]["A"]=X и G.edge["m"]["n"]["B"]= Y+G.node["n"]["A"]

Я хочу, чтобы при изменении значения X значение атрибута «B» в крае также обновлялось.

Заранее большое спасибо за помощь :)


person Lucho_TJ    schedule 12.01.2016    source источник
comment
Я не совсем понял, что вы хотите, но решение этого вопроса может помочь вам.   -  person macabeus    schedule 12.01.2016
comment
Вы согласны с тем, что атрибут B просто является функцией, которая оценивается каждый раз, когда вы пытаетесь получить к ней доступ (в зависимости от того, что вы делаете, это может быть дорого, если оценивается много раз), или вы действительно хотите, чтобы он имел определенное значение, которое обновляется каждый раз при изменении узла (в зависимости от того, что вы делаете, это может быть дорого, если веса узлов сильно меняются, а веса ребер не используются часто). Первый относительно прост. Второй тяжелее.   -  person Joel    schedule 13.01.2016


Ответы (1)


Одна проблема с этим вопросом -> Никогда не удаляйте узлы.

В вашем примере вы назначаете X G.node["n"]["A"]. Если вы скажете:

G.node["n"]["A"] = 5
G.node["n"]["A"] = 6

Это уничтожает местоположения данных, и теперь G.node["n"]["A"] указывает на новый объект с новой ячейкой памяти.

Вместо присваивания типа «=» вам нужно обновить X. Это оставит тип данных и место в памяти на месте. Это означает, что вам нужен тип данных, который поддерживает ".update()", например словарь.

Все прошлое здесь зависит от вашего варианта использования:


Если данные узла являются значением (например, int или float), то у вас не возникнет проблем с их сложением. Вы можете продолжать выполнять расчеты на основе добавленной стоимости изменений только на 1 уровень глубже, чем выполняется расчет.

Однако, если данные узла являются выражением выражений... пример G.node.get('n')['A']+ G.node.get('m')['A'] (который G.node .get('m')['A'] также является выражением, которое необходимо вычислить.)

то у вас есть одна из 2 проблем:

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

Все это можно сделать внутри графа, используя что-то вроде ast.literal_eval() (предупреждаю, что это не ХОРОШАЯ идея)

Если вам нужно выполнить только одну операцию (сложение?), то есть несколько приемов, которые вы можете использовать, например, сохранить текущий список местоположений данных, а затем выполнить sum().

person Back2Basics    schedule 17.01.2016