MATLAB: How to check if the next generated row has no repetitions in the same columns in the previous row using a while loop

conditionsMATLABmatrixsequancewhile loop

Hello,
I want to generate a random matrix using 1 and 0. The matrix is a representation of the sequence of elements (type 1 is the first row, type 2 is the second row, etc.).
I managed to create a loop that generates a matrix with almost all the conditions that I expect.
w = [3,2,4,6] %% quantities of elements
zw = sum(w)
s = zeros (numel(w),zw) %% initial "empty" matrix
for k=1:numel(w)
while sum(s(k,:))<w(k) && sum(sum(s))<zw %%loop is generating random matrix until all rows will
%% have demand quantities and overall sum will be equal total quantity of elements
s(k,randi(15)) = 1 %% generating "1" in random columns in k-th row
end
end
The effect is this:
s =
0 0 0 1 0 1 0 0 0 1 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 1 0 1 0 1 0 0 0
0 1 0 0 0 1 0 1 1 0 1 0 0 0 1
But I need each column to have only one "1" (I can't have more than one element in one position). To limit the number of calculations, I would like to check every generated row, if the column in which it placed "1" has it in any previous rows. If it has – generate the same row again. If not, go to the next row.
Expected effect:
s =
1 0 0 1 0 0 0 0 0 1 0 0 1 0 0
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 1 0 0 0 1 0 1 0
0 1 1 0 0 1 0 0 1 0 1 0 0 0 1
I tried to add another 'for' loop and the sum (s (:, j)) ~ = 1 condition, but it did not give the expected effect:
for k=1:numel(w)
for j=1:zw
while sum(s(k,:))<w(k) && sum(sum(s))<zw && sum(s(:,j))~=1
s(k,randi(15)) = 1
end
end
end
I will be grateful for any tips! 🙂

Best Answer

Your problem is that the check you add in the end, (s (:, j)) ~ = 1, examines if the sum in column j is more than 1 - but the index in which you add your 1 is a random index between 1 and 15. So the event you wish to avoid can very easily happen in column 14 while you are checking column 1. In addition, because your while loop runs until a mistake is found and then stops - it does not correct the mistake that caused it to exit.
Here is my suggestion:
w = [3,2,4,6]; %% quantities of elements
zw = sum(w);
s = zeros (numel(w),zw); %% initial "empty" matrix
for k=1:numel(w)
for j=1:zw
while sum(s(k,:))<w(k) && sum(sum(s))<zw %move the third condition down
rando=randi(15); %log which index you insert the most recent 1 in
s(k,rando) = 1;
if sum(s(:,rando))~=1 %if that most recent 1 caused your column sum to exceed 1, undo it.
s(k,rando)=0;
end
end %and the while loop will keep running, until you have w(k) 1's in the k'th row.
end
end