6

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:

enter image description here

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)

EDIT

Maybe I have to clarify: I'm not looking for a binominal or gaussian distribution but also for something like this: enter image description here

I want to to define the value x where the highest likelihood should be.

EDIT

Unfortunately the previously accepted answer does not seem to work how i suspected. So I'm still looking for an answer!

Community
  • 1
  • 1
  • 2
    see if this helps: http://stackoverflow.com/questions/218060/random-gaussian-variables – Paolo Falabella Feb 24 '11 at 11:45
  • possible duplicate of [Algorithm to generate Poisson and binomial random numbers?](http://stackoverflow.com/questions/1241555/algorithm-to-generate-poisson-and-binomial-random-numbers) – Lasse V. Karlsen Feb 24 '11 at 11:47
  • `double random() { return 17; }` - responding to your subject only. This `(17, 17, 17, ...)` is actually called a `"Hebrew University Random Sequence"`. Every teacher in HUJI says at least once a week "let's take any number. Say... 17" :) – davka Feb 24 '11 at 11:50

4 Answers4

6

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.

Box-Muller transform

Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
  • Note that this methods generates *two* gaussian distributed numbers from to uniformly distributed numbers. So it's easy to make it about twice as fast compared to just generating one as you posted. – CodesInChaos Mar 12 '11 at 11:29
5

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;
}
Dewfy
  • 23,277
  • 13
  • 73
  • 121
  • Yes that would be clear. But how can I now set the most likelihood to my value? – RoflcoptrException Feb 24 '11 at 11:50
  • @Roflcoptr - per SDK return value of nextGaussian is a value around 0.0 with deviation 1.0 (so result is in range(-1;1)). So just append +2 to get values in range (1..3) – Dewfy Feb 24 '11 at 11:54
  • @Dewfy: yes I understand this, but then the highest likelihood is at 0 respectively 1.5. But what if the highest likelihood should be close to 3? – RoflcoptrException Feb 24 '11 at 12:12
  • @Roflcoptr - well, actually I had the same problem - make shift relative median, so look my update in answer. – Dewfy Feb 24 '11 at 12:27
  • @Dewfy Thanks a lot that is exactly the whole method I'm looking for! – RoflcoptrException Feb 24 '11 at 12:32
  • @Dewfy: Have you tested you're solution? I implemented it an tested it with n=10'000 and gaussianInRange(0, 0.2, 1) and the average result is always slightely above 0.4. – RoflcoptrException Feb 24 '11 at 13:06
1

You need a generator working on a "Normal Distribution". Have a look here: http://www.csharpcity.com/reusable-code/random-number-generators/

Felice Pollano
  • 32,832
  • 9
  • 75
  • 115
0

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.

bestsss
  • 11,796
  • 3
  • 53
  • 63