Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NetworkX: adjacency matrix does not correspond to graph

Say I have two options for generating the Adjacency Matrix of a network: nx.adjacency_matrix() and my own code. I wanted to test the correctness of my code and came up with some strange inequalities.

Example: a 3x3 lattice network.

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)

This is the visualization: enter image description here

The adjacency matrix with 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]]

According to it, node 0 (entire 1st row and entire 1st column) is connected to nodes 5 and 8. But if you look at the image above this is wrong, as it connects to nodes 1 and 3.

Now my code (to be run in in the same script as the above):

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)

This yields:

[[ 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.]]

which says that node 0 is connected to nodes 1 and 3. Why does such difference exist? What is wrong in this situation?

like image 357
FaCoffee Avatar asked May 19 '16 17:05

FaCoffee


People also ask

How do you draw a graph from adjacency matrix in python?

Using an adjacency matrix The following code implements a graph using an adjacency matrix: add_vertex(v) adds new vertex v to the graph, and add_edge(v1, v2, e) adds an edge with weight e between vertices v1 and v2 . print("Vertex ", v1, " does not exist. ") print("Vertex ", v2, " does not exist.

Does NetworkX support heterogeneous graph?

Can this construct a heterogeneous graph directly? A NetworkX graph inherently does not have node and edge types. Instead, the nodes can have different feature dimensions. So there is currently no one-liner to copy node features from a NetworkX graph to a DGL HeteroGraph.

How do you find the directed graph of adjacency matrix?

Adjacency Matrix If there is an edge between Vx to Vy then the value of A[Vx][Vy]=1 and A[Vy][Vx]=1, otherwise the value will be zero. For a directed graph, if there is an edge between Vx to Vy, then the value of A[Vx][Vy]=1, otherwise the value will be zero.

Does NetworkX use adjacency list?

Read and write NetworkX graphs as adjacency lists. Adjacency list format is useful for graphs without data associated with nodes or edges and for nodes that can be meaningfully represented as strings.


1 Answers

Networkx doesn't know what order you want the nodes to be in.

Here is how to call it: adjacency_matrix(G, nodelist=None, weight='weight').

If you want a specific order, set nodelist to be a list in that order. So for example adjacency_matrix(G, nodelist=range(9)) should get what you want.

Why is this? Well, because a graph can have just about anything as its nodes (anything hashable). One of your nodes could have been "parrot" or (1,2). So it stores the nodes as keys in a dict, rather than assuming it's the non-negative integers starting at 0. Dict keys have an arbitrary order.

like image 66
Joel Avatar answered Sep 26 '22 00:09

Joel