The simple solution is to generate a number with a uniform distribution (using rand
), and manipulate it a bit:
r = rand;
prob = [0.5, 0.1, 0.4];
x = sum(r >= cumsum([0, prob]));
or in a one-liner:
x = sum(rand >= cumsum([0, 0.5, 0.1, 0.4]));
Explanation
Here r
is a uniformly distributed random number between 0 and 1. To generate an integer number between 1 and 3, the trick is to divide the [0, 1] range into 3 segments, where the length of each segment is proportional to its corresponding probability. In your case, you would have:
- Segment [0, 0.5), corresponding to number 1.
- Segment [0.5, 0.6), corresponding to number 2.
- Segment [0.6, 1], corresponding to number 3.
The probability of r
falling within any of the segments is proportional to the probabilities you want for each number. sum(r >= cumsum([0, prob]))
is just a fancy way of mapping an integer number to one of the segments.
Extension
If you're interested in creating a vector/matrix of random numbers, you can use a loop or arrayfun
:
r = rand(3); % # Any size you want
x = arrayfun(@(z)sum(z >= cumsum([0, prob])), r);
Of course, there's also a vectorized solution, I'm just too lazy to write it.