My program is suppose to change 12 zeros on random positions to 1 in python 6x6 matrix. This is my code.
from random import randint
M = []
i = 0
for i in range(6):
M.append([])
for j in range(6):
M[i].append(0)
while i < 12:
index = randint(0,5)
index2 = randint(0,5)
if (M[index][index2] == 0):
M[index][index2] = 1
i =1
print(M)
So my matrix is going to look like this at the beggining
[[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]
So I randomly chose an array and the element in chosen array. The problem is that different number of zeros is changed every time. Not 12 like I want them to change. Does anyone know how to solve this problem?
CodePudding user response:
The problem is that the two indices index1 and index2 are randomly chosen with replacement, so a pair of indices can appear more than once. This means that one value will be set to 1 two or more times.
One slightly complicated way to do this is to create a list of all possible indices and choose a random set from this.
from random import randint, sample
import itertools
M = []
i = 0
for i in range(6):
M.append([])
for j in range(6):
M[i].append(0)
indices = list(itertools.product(range(6), range(6))
random_indicies = sample(indices, 12)
for ind in random_indicies:
if (M[ind[0]][ind[1]] == 0):
M[ind[0]][ind[1]] = 1
i =1
print(M)
This creates a list indices which contains all pairs of possible indicies. sample picks 12 from these without replacement, which is iterated over and used in the matrix.
A much slower, but functional way is to just keep looping until 12 indices are set to 1
from random import randint
M = []
i = 0
for i in range(6):
M.append([])
for j in range(6):
M[i].append(0)
while i < 12:
index = randint(0,5)
index2 = randint(0,5)
if (M[index][index2] == 0):
M[index][index2] = 1
i =1
print(M)
Which just skips i =1 if an element in M isn't changed, so it keeps iterating until 12 elements in M are changed.
CodePudding user response:
You could instead make a flat array of length 36, randomly choose 12 indeces, change values at indeces to 1, and then reshape to 6x6 in the end:
import numpy as np
array = np.zeros(36)
indeces = np.random.choice(np.arange(36), 12, replace = False)
array[indeces] = 1
M = np.reshape(array, (6,6))
print(M)
CodePudding user response:
Two issues in the code:
- just before the while loop the value of "i" var is "5", from previous for loop
- you should increment the "i" var in the while loop, only if one value has been changed from 0 to 1
Here is the code
from random import randint
M = []
i = 0
for i in range(6):
M.append([])
for j in range(6):
M[i].append(0)
print(M)
i=0
while i < 12:
index = randint(0,5)
index2 = randint(0,5)
if (M[index][index2] == 0):
M[index][index2] = 1
i =1
print(M)
and the output
[[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]
[[0, 1, 1, 1, 0, 1], [0, 1, 0, 1, 1, 1], [0, 0, 0, 1, 0, 0], [1, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0], [1, 0, 0, 0, 0, 0]]
CodePudding user response:
So you have two issues with your code. First off, you use the variable i in your for loop. By the time that's finished running, Python has stored the variable and assigned the value 5 to it. So when you run your while-loop, you're instead starting at 5 rather than zero like how you would like. A simple fix would be to use a different variable or assign i=0 again.
The second problem is your if statement and i =1. This makes your while loop subject to repeating probabilities, with a 1/36 chance of having only 1 zero change! Including the i =1 statement inside the if statement should fix your issue.
