Reputation: 11
I am relatively new to MATLAB and I need to design a 200x1 matrix, which is filled with random integers that can be either 1/2/3/4, so 4 possible numbers. However, in the matrix I want '1' to occur 70% (thus a total frequency of 140 for number 1), '2', '3' and '4', to occur 10% (thus a frequency of 20 for 2,3 and 4).
Moreover, I want the matrix to be filled so that the values of 2,3, and 4 never display a consecutive repeat, but that 1 may feature consecutive repeats (as it takes 70%)
I had a solution (without the consecutive repeat constraint), using the repelem function. However, on the target PC, an older version of matlab is installed (2013) and does not include this function. Could someone provide me with a solution?
Thanks
Upvotes: 1
Views: 66
Reputation: 30101
Here is one approach:
Create a 60 element vector, with the values 2, 3 and 4 (randomly ordered) appearing 20 times each.
a = repmat([2;3;4],20,1); % Create vector of [2;3;4] 20 times
a = a(randperm(numel(a))); % Randomise intial vector
Get the indices of all locations where there are equal consecutive values.
d = find(diff(a)==0);
Get the maximum number of ones which you could put at every one of these locations to break up consecutives.
maxones = floor(200/numel(d));
Put between 1 and maxones
number of ones at each location. This is to try and maintain some amount of "randomness", could just put one at each location to break them up!
for ii = numel(d):-1:1;
a = [ a(1:d(ii)) ; ones(randi(maxones), 1) ; a(d(ii)+1:end) ];
end
Now randomly add the remaining number of ones to make the vector 200 elements long
idx = randperm(numel(a), 200 - numel(a));
for ii = numel(idx):-1:1;
a = [ a(1:idx(ii)); 1 ; a(idx(ii)+1:end) ];
end
Output is a 200 element vector, with 20 elements each with the value 2, 3 or 4, and 140 elements have the value 1.
% Using nnz (number of non-zero elements) to count matching condition
nnz(a == 1) % = 140
nnz(a == 2) % = 20
nnz(a == 3) % = 20
nnz(a == 4) % = 20
No consecutive 2s, 3s or 4s:
% Get number of elements where difference to next is 0, and value isn't 1
nnz([false; diff(a) == 0] & a ~= 1) % = 0
Upvotes: 0
Reputation: 5822
You can use the following approach
%represents odds map for 1,2,3,4
oddsMap = [0,0.7,0.8,0.9];
N = 200;
isValid = false;
while ~isValid
%generate vector
probVect = rand(N,1);
randVect = ones(N,1);
for ii=1:length(oddsMap)
randVect(probVect>=oddsMap(ii)) = ii;
end
%check [2,3,4] constraint
isValid = isempty(findstr(randVect',[2,3,4]));
end
Upvotes: 0