Search code examples
pythonnumpymatrix

How to put number of a particular element in a particular row and column constraints in a matrix?


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)

Solution

  • 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)