I have to basically create a symmetric matrix of NxN. Which has 1s and 0s randomly populated into it. However the only constraint is I need only one ‘1’ in any row and any column.
I wrote a code to generate the matrix but it has more than one ‘1’ in any row or column. I need to follow the constraint mentioned above, how can i modify my code?
import numpy as np N = int(input("Enter the number of row and col:")) my_matrix = np.random.randint(2,size=(N,N)) print(my_matrix)
Advertisement
Answer
Create a matrix with zeros. Then, you need to take randomly N row numbers, without repetition, and randomly N column numbers, without repetition. You can use random.sample
for this. Then put 1 on the row/column positions.
import numpy as np from random import sample N = int(input("Enter the number of row and col:")) 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 want a symmetrical matrix: In case N is even, I would take N random numbers out of N, half of them as x, half as y; and on both positions (x,y) and (y,x) put a 1. If N is uneven, an additional 1 needs to be put on a random position on the diagonal.
import numpy as np from random import sample, randint N = int(input("Enter the number of row and col:")) even = N%2 == 0 my_matrix = np.zeros((N,N), dtype='int8') N_range = list(range(N)) if not even: diagonal = randint(0, N-1) N_range.remove(diagonal) my_matrix[diagonal, diagonal] = 1 N = N - 1 rowcol = sample(N_range, N) rows = rowcol[:N//2] cols = rowcol[N//2:] for x, y in zip(rows,cols): my_matrix[x, y] = 1 my_matrix[y, x] = 1
Here is a better version. Take the first free row, get a random free column, put a 1 on (row,col) and (col,row). Remove the used col/row. Repeat until all numbers 0-(N-1) are used.
import numpy as np import random N = int(input("Enter the number of row and col:")) my_matrix=np.zeros((N,N)) not_used_number = list(range(N)) while len(not_used_number) != 0: current_row = not_used_number[0] random_col = random.choice(not_used_number) my_matrix[current_row, random_col] = 1 my_matrix[random_col, current_row] = 1 not_used_number.remove(current_row) if current_row != random_col: not_used_number.remove(random_col)