Как использовать определяемый пользователем объект класса в качестве узла networkx?

Точка класса определяется как (в ней также есть некоторые методы, атрибуты и прочее, но это минимальная часть):

class point():
    def ___init___(self, x, y):
        self.x = x
        self.y = y

Итак, я увидел этот вопрос, но когда я попытался применить его, он вернул ошибку:

G = nx.Graph()
p = point(0,0)
G.add_node(0, p)

NetworkXError: аргумент attr_dict должен быть словарем.

Если я использую

G = nx.Graph()
p = point(0,0)
G.add_node(0, data = p)

Я не получаю сообщения об ошибке, но когда я пытаюсь получить доступ к координате x, оказывается, что она не сохранила ее как точку.

G[0].x

возвращает: AttributeError: объект 'dict' не имеет атрибута 'x'

делает

G = nx.Graph()
G.add_node(0, data = point(0,0))
G[0]

возвращает: {}

это означает, что он по-прежнему сохраняет его как словарь.

Я видел, что могу сделать свои точки хешируемыми и использовать эти объекты в качестве узлов, поэтому я добавил идентификатор атрибута, поскольку точки будут перемещаться. Я добавил это в класс и __repr__ для красивого рисования графиков:

def __hash__(self):
    return self.id_n
def __cmp__(self, p):
    if self.id_n < p.id_n: return -1
    elif self.id_n == p.id_n: return 0
    else: return 1
def __eq__(self, p):
    if p.id_n == self.id_n: return True
    else: return False
def __repr__(self):
    return str(self.id_n) 

но это немного странно, так как я не понимаю, как выбрать узел,

G[<what should i put here?>]

Итак, вопрос в том, как это сделать правильно?

Я надеялся, что смогу использовать что-то вроде

G[node_id].some_method(some_args)

person Luka Petrović    schedule 31.01.2018    source источник


Ответы (2)


изменить - в приведенном ниже тексте заменить G.node[] на G.nodes[] - в версии 2.4 G.node устарел.

Вы смотрите на G[0]. Но это не то, что вам нужно. G[0] содержит информацию о соседях узла 0 и атрибутах ребер, но ничего об атрибутах узла 0.

class point():
    def __init__(self, x, y):
        self.x = x
        self.y = y

import networkx as nx
G = nx.Graph()
p0 = point(0,0)
p1 = point(1,1)

G.add_node(0, data=p0)
G.add_node(1, data=p1)
G.add_edge(0,1, weight=4)
G[0]
> AtlasView({1: {'weight': 4}})  #in networkx 1.x this is actually a dict. In 2.x it is an "AtlasView"

Для networkx ожидается, что с узлом может быть связано много данных. В вашем случае у вас есть только один фрагмент данных, а именно точка. Но вы также можете назначить цвет, вес, время, возраст и т. Д. Итак, networkx будет хранить все атрибуты в другом словаре, но доступ к этому словарю осуществляется через G.node[0], а не через G[0].

G.node[0]
> {'data': <__main__.point at 0x11056da20>}
G.node[0]['data'].x
> 0

Обратите внимание, что data в вашем вводе становится строкой 'data'.

Возможно, будет лучше ввести узлы типа G.add_node(0, x=0, y=0), а затем вы сможете получить доступ к записям как G.node[0]['x'].

person Joel    schedule 02.02.2018
comment
Спасибо, теперь я это понимаю. Я не знал, что мне нужно использовать «данные». Я просто воспользуюсь отдельным списком с данными. - person Luka Petrović; 02.02.2018
comment
Используйте G.nodes [] вместо G.node []. G.node [] не рекомендуется в NetworkX 2.4. - person Francesco Laiti; 22.06.2021

Вы добавили node и поэтому можете изучить nodes, который является набором представления. Цитата из документов:

Это подобные наборы представлений узлов, ребер, соседей (смежности) и степеней узлов в графе. Они предлагают постоянно обновляемое представление структуры графика только для чтения.

Например:

mynodes = list(G.nodes())
print(mynodes)

Теперь вы также можете делать:

mynode = mynodes[0]  # because we have converted the set-like view to a list

См. Руководство: https://networkx.github.io/documentation/stable/tutorial.html

person mementum    schedule 31.01.2018
comment
В: При изменении mynode изменяется G [0]? E: Кроме того, это немного грязно. - person Luka Petrović; 31.01.2018
comment
G[0], как указано выше, не дает вам доступа к узлу. В любом случае mynodes теперь является списком, который не привязан к вашему графику, поэтому изменение mynodes[0] ничего не изменит в графике. Он был извлечен из read-only вида. - person mementum; 31.01.2018
comment
Таким образом, это в основном то же самое, что наличие на стороне словаря индексации объекта. Как вы думаете, это лучший способ использовать объекты в качестве узлов? - person Luka Petrović; 31.01.2018