FaCoffee
FaCoffee

Reputation: 7929

NetworkX: Adjacency Matrix of partially failed graphs/networks

Recalling that the Adjacency Matrix gives us 1 if two nodes are connected and 0 otherwise, I wanted to compute one matrix for a regular graph with all its nodes active, and one for the same graph where a few nodes have failed.

Let's consider a Lattice Network of 2x2 nodes. Its Adjacency Matrix (A) is:

0  1  1  0
1  0  0  1
1  0  0  1
0  1  1  0

resulting in this graph: enter image description here

Now, let's remove node 0:

G.remove_node(0)

This is what the new Adjacency Matrix (A1) looks like:

0  0  1
0  0  1
1  1  0

returning this graph: enter image description here

Now, the two Matrices are noticeably different in terms of size.

My question: how can I make sure that Matrix A1 has the same size of Matrix A? Which is to say, if node 0 is not going to be present because it has failed, I want a 0 to be placed in A1 in correspondence of the 0-th row and column, so that the size of the matrix remains unaltered. I need to do this for purposes of comparison and computation. But to do this I assume I need to access the function creating the adjacency matrix. Can I do it in a simpler way?

Example with node 0 failed:

0  0  0  0
0  0  0  1
0  0  0  1
0  1  1  0

This is how I create the 2x2 network and generate the Adjacency Matrix:

import networkx as nx

N=2
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))
nx.draw_networkx(G, pos=pos2, with_labels=True, node_size = 200)

A=nx.adjacency_matrix(G)
A.toarray()

#G.remove_node(i) to remove node i

Upvotes: 3

Views: 859

Answers (2)

FaCoffee
FaCoffee

Reputation: 7929

Based on a little research and the advice of Joel, I've come up with this method. I want to post it here so that anyone who has the will can propose improvements.

For a regular 3x3 network, this is how we can obtain the adjacency matrix in a righteous way:

#Create the graph (see question above)
A=nx.adjacency_matrix(G, nodelist=range(N*N))
A=A.todense()

This yields a N^2xN^2 matrix where each row/column corresponds to a specific node (using nodelist allows to have the rows/columns to be printed out sorted 0 to K where K is the total number of nodes):

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

enter image description here

If node 0 had failed, we would have to replace its connections (1) with absent connections (0), while preserving the size of the adjacency matrix. In this case, row 0 and column 0 would be filled with 0. My solution then goes as follows:

P=K #Total number of nodes before failures

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

A1=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():
            A1[i][:]=0
            A1[:][i]=0
        elif i in G.nodes():
            A1[i][j]=nodes_connected(i,j)
                A1[j][i]=A1[i][j]
for i in range(0,P*P,1):
    for j in range(0,P*P,1):
            if math.isnan(A1[i][j]):
                A1[i][j]=0              
print(A1)

This yields the following:

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

Matrix A1 now tells us that node 0 has no connections whatsoever. It also tells us, similar to matrix A, that node 1 is connected to nodes 2 and 4.

If anyone has corrections to propose, please feel welcome to do so.

Upvotes: 1

Joel
Joel

Reputation: 23887

Try G.remove_edges_from(G.edges(0)) which will remove all of the edges of 0 rather than the entire node. Then generate the adjacency matrix.

Upvotes: 4

Related Questions