This should do the trick. Basically what you need to do, since there is really no straight fotward way of defining a custom weighted distribution, you can simply create an array that has the higher weighted elements in it more often, and then uniformly sample that array. So if some element has a probability of 0.5 then half the elements in your created array will be that value with probability of 0.5. Then, as said, simply use randi
(with the whole array length) to select an index from that array, which will follow your custom distribution.
See code below
sizes = [1,2,3,4,5];
probs = [0.125,0.125,0.125,0.125,0.5];
% some initial sanity checks.
assert(numel(sizes) == numel(probs),'probability must be defined for each size')
assert(sum(probs)==1,'Probabilities must sum to 1')
numEach = round((probs/min(probs)));
weightedSizes = zeros(1,sum(numEach));
start = 1;
for i = 1:numel(sizes)
weightedSizes(start:start+numEach(i)-1) = sizes(i);
start = start+numEach(i);
end
holder = cell(1,10);
for i = 1:10
randSize = weightedSizes(randi(numel(weightedSizes)));
holder{i} = randperm(randSize);
end
Note, be very careful using this method if you have something with a very small probability as it will create a very large matrix. This is because it assumes that the element with the smallest probability only appears once. There will be as many elements as 1/min(probability)