NetworkX: матрица смежности не соответствует графу

Скажем, у меня есть два варианта создания матрицы смежности сети: nx.adjacency_matrix() и мой собственный код. Я хотел проверить правильность своего кода и придумал несколько странных неравенств.

Пример: решетчатая сеть 3x3.

import networkx as nx
N=3
G=nx.grid_2d_graph(N,N)
pos = dict( (n, n) for n in G.nodes() )
labels = dict( ((i,j), i + (N-1-j) * N ) for i, j in G.nodes() )
nx.relabel_nodes(G,labels,False)
inds=labels.keys()
vals=labels.values()
inds.sort()
vals.sort()
pos2=dict(zip(vals,inds))
plt.figure()
nx.draw_networkx(G, pos=pos2, with_labels=True, node_size = 200)

Это визуализация: введите здесь описание изображения

Матрица смежности с nx.adjacency_matrix():

B=nx.adjacency_matrix(G)
B1=B.todense()

[[0 0 0 0 0 1 0 0 1]
 [0 0 0 1 0 1 0 0 0]
 [0 0 0 1 0 1 0 1 1]
 [0 1 1 0 0 0 1 0 0]
 [0 0 0 0 0 0 0 1 1]
 [1 1 1 0 0 0 0 0 0]
 [0 0 0 1 0 0 0 1 0]
 [0 0 1 0 1 0 1 0 0]
 [1 0 1 0 1 0 0 0 0]]

Согласно ему узел 0 (вся 1-я строка и весь 1-й столбец) соединен с узлами 5 и 8. Но если вы посмотрите на изображение выше, это неправильно, так как оно соединяется с узлами 1 и 3.

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

import numpy
import math

P=3

def nodes_connected(i, j):
     try: 
        if i in G.neighbors(j):
            return 1
     except nx.NetworkXError:
        return False          

A=numpy.zeros((P*P,P*P))

for i in range(0,P*P,1):
    for j in range(0,P*P,1):

        if i not in G.nodes():
            A[i][:]=0
            A[:][i]=0
        elif i in G.nodes():
            A[i][j]=nodes_connected(i,j)
                A[j][i]=A[i][j]

for i in range(0,P*P,1):
    for j in range(0,P*P,1):
            if math.isnan(A[i][j]):
                A[i][j]=0 

print(A)

Это дает:

[[ 0.  1.  0.  1.  0.  0.  0.  0.  0.]
 [ 1.  0.  1.  0.  1.  0.  0.  0.  0.]
 [ 0.  1.  0.  0.  0.  1.  0.  0.  0.]
 [ 1.  0.  0.  0.  1.  0.  1.  0.  0.]
 [ 0.  1.  0.  1.  0.  1.  0.  1.  0.]
 [ 0.  0.  1.  0.  1.  0.  0.  0.  1.]
 [ 0.  0.  0.  1.  0.  0.  0.  1.  0.]
 [ 0.  0.  0.  0.  1.  0.  1.  0.  1.]
 [ 0.  0.  0.  0.  0.  1.  0.  1.  0.]]

в котором говорится, что узел 0 соединен с узлами 1 и 3. Почему существует такая разница? Что не так в этой ситуации?


person FaCoffee    schedule 19.05.2016    source источник
comment
не уверен на 100%, но в связи с ответом ниже, где вы используете dict выше, вы должны перейти на использование collections.OrderedDict...   -  person Corley Brigman    schedule 19.05.2016


Ответы (2)


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

Вот как это назвать: adjacency_matrix(G, nodelist=None, weight='weight').

Если вам нужен определенный порядок, установите nodelist как список в этом порядке. Так, например, adjacency_matrix(G, nodelist=range(9)) должен получить то, что вы хотите.

Почему это? Ну, потому что граф может иметь что угодно в качестве узлов (все, что можно хэшировать). Один из ваших узлов мог быть "parrot" или (1,2). Таким образом, он сохраняет узлы как ключи в словаре, а не предполагает, что это неотрицательные целые числа, начинающиеся с 0. Ключи словаря иметь произвольный порядок.

person Joel    schedule 19.05.2016

Более общее решение, если ваши узлы имеют некоторый логический порядок, как в случае, если вы создаете график с использованием G=nx.grid_2d_graph(3,3) (который возвращает кортежи от (0,0) до (2,2), или в вашем примере будет использовать:

adjacency_matrix(G,nodelist=sorted(G.nodes()))

Это сортирует возвращенный список узлов G и передает его как список узлов.

person LeoAnth    schedule 11.09.2017