Reputation:
I need a random number generator that generates various number between n and m, but no with a equal probability. I want to set a value x between n and m where the possibility is the highest:
Is there an easy way to do that using the Random class? The likelihood should have the form of a binominal distribution or something similar (it is not important that its an exact binominal distributon, rough approximations are also ok)
Maybe I have to clarify: I'm not looking for a binominal or gaussian distribution but also for something like this:
I want to to define the value x where the highest likelihood should be.
Unfortunately the previously accepted answer does not seem to work how i suspected. So I'm still looking for an answer!
Upvotes: 6
Views: 2385
Reputation: 23624
Java SDK has good implementation Random.nextGaussian (taken from http://download.oracle.com/javase/1.4.2/docs/api/java/util/Random.html#nextGaussian())
I hope it is rather clear how to parse from java source to c#
synchronized public double nextGaussian() {
if (haveNextNextGaussian) {
haveNextNextGaussian = false;
return nextNextGaussian;
} else {
double v1, v2, s;
do {
v1 = 2 * nextDouble() - 1; // between -1.0 and 1.0
v2 = 2 * nextDouble() - 1; // between -1.0 and 1.0
s = v1 * v1 + v2 * v2;
} while (s >= 1 || s == 0);
double multiplier = Math.sqrt(-2 * Math.log(s)/s);
nextNextGaussian = v2 * multiplier;
haveNextNextGaussian = true;
return v1 * multiplier;
}
}
UPDATE: How I've made shift of median:
public static float gaussianInRange(float from, float mean, float to)
{
if( !(from < mean && mean < to) )
throw new IllegalArgumentException(MessageFormat.format("RandomRange.gaussianInRange({0}, {1}, {2})", from, mean, to));
int p = _staticRndGen.nextInt(100);
float retval;
if (p < (mean*Math.abs(from - to)))
{
double interval1 = (_staticRndGen.nextGaussian() * (mean - from));
retval = from + (float) (interval1);
}
else
{
double interval2 = (_staticRndGen.nextGaussian() * (to - mean));
retval = mean + (float) (interval2);
}
while (retval < from || retval > to)
{
if (retval < from)
retval = (from - retval) + from;
if (retval > to)
retval = to - (retval - to);
}
return retval;
}
Upvotes: 5
Reputation: 12056
smth relatively simple. You can generate 2 random numbers: 1st defines how close to x the 2nd random number would be.
You can use any breakpoint/function levels you like.
Upvotes: 0
Reputation: 33252
You need a generator working on a "Normal Distribution". Have a look here: http://www.csharpcity.com/reusable-code/random-number-generators/
Upvotes: 1
Reputation: 838156
You can use the Box-Muller transform to generate a sequence of psuedorandom normally distributed numbers from a sequence of numbers uniformally distributed between 0 and 1.
Upvotes: 6