How can I check if the next generated row has no repetitions in the same columns in the previous row using a while loop

1 view (last 30 days)
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! :)

Accepted Answer

Jakob B. Nielsen
Jakob B. Nielsen on 13 Feb 2020
Edited: Jakob B. Nielsen on 13 Feb 2020
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

More Answers (0)

Categories

Find more on Creating and Concatenating Matrices in Help Center and File Exchange

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!