Как реализовать генератор случайных чисел, который не является случайным? - PullRequest
6 голосов
/ 24 февраля 2011

Мне нужен генератор случайных чисел, который генерирует различное число между n и m, но не с равной вероятностью. Я хочу установить значение x между n и m, где вероятность самая высокая:

enter image description here

Есть ли простой способ сделать это, используя класс Random? Вероятность должна иметь форму биноминального распределения или чего-то подобного (не важно, что это точное биноминальное распределение, грубые приближения также приемлемы)

EDIT

Может быть, я должен уточнить: я не ищу биноминальный или гауссовский дистрибутив, но также что-то вроде этого: enter image description here

Я хочу определить значение x, где должна быть максимальная вероятность.

EDIT

К сожалению, ранее принятый ответ , похоже, не работает , как я и подозревал. Так что я все еще ищу ответ!

Ответы [ 4 ]

6 голосов
/ 24 февраля 2011

Вы можете использовать преобразование Box-Muller для генерации последовательности псевдослучайных нормально распределенных чисел из последовательности чисел, равномерно распределенных между 0 и 1.

Box-Muller transform

5 голосов
/ 24 февраля 2011

Java SDK имеет хорошую реализацию Random.nextGaussian (взято из http://download.oracle.com/javase/1.4.2/docs/api/java/util/Random.html#nextGaussian())

Надеюсь, довольно понятно, как разобрать исходный код Java в 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;
    }
 }

ОБНОВЛЕНИЕ: Как я изменил медиану:

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;
}
1 голос
/ 24 февраля 2011

Вам нужен генератор, работающий по «нормальному распределению». Посмотрите здесь: http://www.csharpcity.com/reusable-code/random-number-generators/

0 голосов
/ 24 февраля 2011

что-то относительно простое.Вы можете сгенерировать 2 случайных числа: 1-е определяет, насколько близко к x будет 2-е случайное число.

Вы можете использовать любые уровни останова / функции, которые вам нравятся.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...