I have this code, it produces a random matrix of 1s and 0s. I want to create a graph from this matrix where the 1s in the matrix represent a node and each node has a maximum of 3 edges. How can i implement this, please help?
import numpy as np
from random import sample
N = int(input("Enter the number of nodes:"))
my_matrix = np.zeros((N,N), dtype='int8')
rows = sample(range(N), N)
cols = sample(range(N), N)
points = zip(rows, cols)
for x, y in points:
my_matrix[x, y] = 1
print(my_matrix)
If you matrix is just random, probably, you don't need it. Instead, you can create graph from list of edges
import networkx as nx
from random import sample
import numpy as np
from numpy.random import randint
n = 7 # number of nodes in graph
max_connections = int(input("Enter max connections per node:")) # input: 3
nodes = np.arange(n)
# create graph based on list of edges [(0, 1), (0, 4), ...]
gr = nx.Graph([
# for each node select <= 'max_connections' nodes as connections
(i, j) for i in range(n) for j in sample(nodes[nodes != i].tolist(), randint(1, max_connections+1))
])
# check number of connections
for n in gr.nodes():
nei = list(gr.neighbors(n))
while len(nei) > max_connections:
gr.remove_edge(n, random.choice(nei))
nei = list(gr.neighbors(n))
nx.draw_networkx(gr, with_labels=True, node_color='#7d99f5')
And you can get adjacency matrix using nx.adjacency_matrix()
nx.adjacency_matrix(gr, nodelist=sorted(gr.nodes())).todense()
matrix([[0, 1, 1, 0, 1, 0, 0],
[1, 0, 0, 0, 0, 1, 1],
[1, 0, 0, 1, 0, 1, 0],
[0, 0, 1, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 1, 1],
[0, 1, 1, 0, 1, 0, 0],
[0, 1, 0, 1, 1, 0, 0]])
Addition to your code (function check_graph ()
fix two problems we have discussed):
def check_graph(graph, max_conn):
# 1) remove self loops
graph.remove_edges_from(nx.selfloop_edges(graph))
# 2) remove random edge(s) if limit of edges per node have been exceeded
for i in graph.nodes():
# list of connections - nodes that are connected to the selected node 'i'
nei = list(graph.neighbors(i))
if len(nei) > max_conn:
graph.remove_edges_from(
# like if len(nei) - max_conn = 5 - 4 = 1, then one random edge will be selected
np.random.choice(nei, size=(len(nei)-max_conn))
)
# <-- insert your code here --> N = 20
gr = nx.from_numpy_matrix(my_matrix)
check_graph(gr, max_conn=N)
nx.draw_networkx(gr, with_labels=True, node_color='#7d99f5')
Result looks a bit strange for me, but I don't know purposes of your graph, probably, it's okay.
This code generates randomly in maximum Nedges=3 edges (or less, if there is a self-adjacency or a bi-directional connection by the random process). The self-adjacency is removed by setting the diagonal of the adjacency matrix to zero. Might this hit the basic idea? (omg, no: at node 4 there are more connections. A removal process might be incorporated)
import numpy as np
import networkx as nx
Nnodes = 6
Nedges = 3
#---- to initialize: generate a random adjacency matrix
rng = np.random.default_rng()
adjM = rng.integers(1, size=(Nnodes,Nnodes)) # random adjacency matrix / with upper=1 it is a zero matrix
print(adjM)
#---- for eaach node generate randomly Nedges edges
for node in range(Nnodes):
rand_ind = np.random.choice(np.arange(Nnodes), size=Nedges, replace=False, p=None) # generate randomly indexes
# you might use replace=False too with different results
adjM[node, rand_ind] = 1 # insert the connections
print(rand_ind)
print(adjM)
#---- remove self-adjacency
jDiag = np.arange(Nnodes)
adjM[jDiag, jDiag] = 0 # set the diagonals to zero
print(adjM)
#---- grafics
gr = nx.from_numpy_matrix(adjM)
nx.draw_networkx(gr, with_labels=True, node_size=400, node_color='#7d99f5', edge_color='orange', width=3, font_weight='bold')
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.