I am looking for a random number generator that can be biased. For instance, say I want a random number between 1-5, with the probability being:
1: Comes up 20% of the time
2: Comes up 10% of the time
3: Comes up 40% of the time
4: Comes up 25% of the time
5: Comes up 5% of the time
Is there anything in the standard library, or other libraries out there that would do this? Alternatively, is there an efficient way to do this myself?
Kenny gave an appropriate answer tailored to your particular frequency distribution.
The more general answer works with a CDF - Cumulative Distribution Function - for the data, and uses a uniform random number to pick a value within the distribution.
Coming late to the party on this one. Here is the C++0x answer:
Which for me outputs:
The Boost random number library provides the ability to specify different shaped distributions for your generator. It's a great library - see http://www.boost.org/doc/libs/1_42_0/libs/random/index.html.
Best way's probably to just take the normal unbiased random generator then return based on the interval its value falls into.
Just an if statement that gives 1 for 0:0.2, 2 for 0.2:0.3, 3 for 0.3:0.7, 4 for 0.7:0.95 and 5 for 0.95:1. Best to make either the lower or upper limit of the interval inclusive and the other exclusive.
Something like that.
For your problem, just pick a random element from this list uniformly:
In general, check this answer: Weighted random numbers
In TR1 and C++0x, there is
<random>
header which contains thediscrete_distribution
class to generate such numbers, among others.You may also want to check out GSL which contains much more random distributions (and random number generators) than the standard
<random>
library. (But note that GSL uses GPLv3.)What you are describing is the implementation of a random number generator that draws from a particular probability distribution. For example, drawing numbers from a Gaussian distribution should draw random numbers such that the probability of a particular draw, x is proportional to alt text http://upload.wikimedia.org/math/1/8/4/184fa5540b76903b1653d9f83912265d.png.
In general, the approach is to draw from a uniform random distribution and then pick the value of the desired distribution's cumulative distribution function (CDF) at that drawn location. In the case of a Normal Gaussian, draw a random number, x from a uniform distribution (this is what standard random number generators should give) and then choose as the random, Gaussian distributed value. For your case, the CDF you describe is a piece-wise continuous stair-step function which could be implemented using any of the many (correct) answers you have already received.
Of course, this is all trivia. What you should be doing is using a library that already handles this for you. Statistics and random number generation are not trivial and there's no need to re-invent the wheel. See Neil's answer (and check out the Boost random number library).