How can I pseudorandomize with constrains and make spesific number spread equally among the array?
Show older comments
Hello everybody,
I have a question regarding to pseudorandomization and more. Sorry I am new on Matlab and I feel very stuck!
I have an array consist of 4 numbers (1,2,3,4). The lenght of the array is 330. Number 1,2,3 are repeated 100 times, whereas number 4 is repeated 30 (%10 of total)times.
A=[1,1,2,3,4,2,3.....]
How can I randomize this array in a way that the maximum number of repetition of spesific number is 3 (for expample [1,3,2,2,2,2,1,1,1,3,..] is not correct) and
the number 4 is positioned more less equily spreed along the array (like in every 8-12 position)?
Thank you very much.
Stay happy and healthy!
Accepted Answer
More Answers (1)
Walter Roberson
on 13 Sep 2020
1 vote
the number 4 is positioned more less equily spreed along the array (like in every 8-10 position)?
You cannot achieve that constraint.
If you were to distribute the 30 entries that are 4 equally across the 330 positions, they would have to be every 11 apart. If you put them closer together (maximum 10 apart) then that can only occupy at most 300 of the 330 entries, leaving an uncovered gap of at least 15 on both sides. If you say that the minimum distance must be 8 and the maximum must be 10, then you cannot spread the 30 entries out over the 330 elements of the array without ending up with a portion of the array for which that does not hold.
7 Comments
Doli Swey
on 14 Sep 2020
Walter Roberson
on 14 Sep 2020
9-11 would stil force them to be 11 apart in order to be able to fit the 30 distinguished values in the vector of length 330.
30*11 = 330. If even one location had only 10 instead of 11, the maximum coverage would be 29*11+10 = 329 and so there would have to be at least one location that was 12 away instead of at most 11 away.
You have to permit 12 or more if you want some values less than 11.
Doli Swey
on 14 Sep 2020
Walter Roberson
on 14 Sep 2020
N = 30;
offsets = 11 * ones(1,N);
%the following guarantees that sum(offsets) stays the same
%K = 50 rounds is arbitrary
for K = 1 : 50
PQ = randperm(N, 2);
if offsets(PQ(1)) < 12 & offsets(PQ(2)) > 8
offsets(PQ(1)) = offsets(PQ(1)) + 1;
offsets(PQ(2)) = offsets(PQ(2)) - 1;
end
end
position4 = cumsum(offsets) - randi(offsets(1)-1);
Now the 4's go at the positions indicated in position4.
Doli Swey
on 14 Sep 2020
Walter Roberson
on 14 Sep 2020
I suggest starting with
NB = 100;
M = [1 * ones(1,Nb), 2 * ones(1,NB), 3 * ones(1,NB)];
M = M(randperm(length(M)));
Now assign 4s into your result vector at locations position4, and assign M into your result vector at locations that are not position4
results = zeros(1,NB*3+N);
results(position4) = 4;
results(~ismember(1:NB*3+N, position4)) = M;
After that I would suggest scanning results looking for more than 3 in a row and taking that element and exchanging it with a random location that is not the same value and is not a 4 and where it will not trigger 4+ in a row.
Doli Swey
on 15 Sep 2020
Categories
Find more on Matrices and Arrays in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!