2009-10-07 1 views
5

Мне нужен генератор случайных чисел, который выбирает числа в указанном диапазоне с программируемым значением.Внеоборотная реализация генератора случайных чисел?

Например, мне нужно выбрать число от 2 до 14 лет, и мне нужно в среднем случайных чисел, чтобы быть 5.

Я использую генераторы случайных чисел много. Обычно мне просто нужно равномерное распределение.

Я даже не знаю, как назвать этот тип распространения.

Благодарим вас за любую помощь или понимание, которое вы можете предоставить.

+9

Вы уверены, что вы предоставили достаточно информации о распределении? Я считаю, что среднего значения недостаточно. Рассмотрим этот пример: скажем, мы генерируем случайные числа из '{0, 1, 2}' с 1 значением. Теперь взгляните на эти два генератора: 'Generator1 (0: 40%, 1: 20%, 2: 40%)', 'Generator2 (0: 10%, 1: 80%, 2: 10%)'. Для обоих из них средний результат будет равен 1. –

+1

Почти дубликат: http://stackoverflow.com/questions/977354/generating-non-uniform-random-numbers. А не плоские псевдослучайные распределения - это стандартная тема, которая неоднократно рассматривалась на SO. Дайте больше информации, и мы можем указать вам в правильном направлении. – dmckee

+0

Если целевое распределение нелегко представить интегрируемым PDF-обращением: http://stackoverflow.com/questions/423006/how-do-i-eneration-points-that-match-a-histogram – dmckee

ответ

0

Моя первая идея была бы:

  • генерации чисел в диапазоне 0..1
  • шкалы в диапазоне -9..9 (х-0,5; х * 18)
  • сдвига диапазон от 5 -> -4 .. 14 (добавление 5)
  • обрежут диапазон 2..14 (отбрасывать номера < 2)

, которые должны дать вам номер в диапазоне вы хотите.

+0

Но как вы отбрасываете цифры <2, ваш средний возраст движется вверх от 5, не так ли? –

6

Возможно, вы сможете использовать binomial distribution, если вы довольны формой этого дистрибутива. Установите n = 12 и p = 0,25. Это даст вам значение от 0 до 12 со средним значением 3. Просто добавьте 2 к каждому результату, чтобы получить диапазон и значение, которое вы ищете.

Редакция: Что касается реализации, возможно, вы найдете библиотеку для выбранного языка, которая поддерживает неравномерные распределения (у меня есть written one myself for Java).

Биномиальное распределение можно довольно легко приблизить, используя единый RNG. Просто выполните n проб и зарегистрируйте количество успехов. Поэтому, если у вас есть n = 10 и p = 0,5, это точно так же, как разворачивание монеты 10 раз подряд и подсчет количества голов. При p = 0,25 просто генерируют равномерно распределенные значения между 0 и 3 и только рассчитывают нули как успехи.

Если вы хотите более эффективную реализацию, есть умный алгоритм, спрятанный в упражнениях тома 2 «Искусство программирования» Кнута.

+0

ссылка на ["(я сам написал для Java)." (Https://uncommons-maths.dev.java.net/) недоступно – yishaiz

+1

@yishaiz Просто обновил его. –

0

Вам необходим распределенный/взвешенный генератор случайных чисел. Here's a reference, чтобы вы начали.

3

Вы не сказали, какое распределение вы после. Что касается вашего конкретного примера, функция, которая обеспечивала равномерное распределение между 2 и 8, будет удовлетворять вашим требованиям, строго так, как вы их написали :)

+0

Я думаю, что OP намеревается для значений от 9-14 иметь определенную вероятность выбора. – fbrereto

1

Если вы хотите неравномерное распределение случайного числа, для осуществления какого-либо сопоставления, например:

// returns a number between 0..5 with a custom distribution 
int MyCustomDistribution() 
{ 
    int r = rand(100); // random number between 0..100 
    if (r < 10) return 1; 
    if (r < 30) return 2; 
    if (r < 42) return 3; 
    ... 
} 
1

Вы можете создать неравномерный PRNG из однородного. Это имеет смысл, так как вы можете представить себе единый PRNG, который возвращает 0,1,2 и создает новый неравномерный PRNG, возвращая 0 для значений 0,1 и 1 для значения 2.

Существует больше, если вам нужны конкретные характеристики при распределении вашего нового, неравномерного PRNG. Это описано в the Wikipedia page on PRNGs, и конкретно указывается Ziggurat algorithm.

С этими подсказками вы сможете найти код.

1

Основываясь на Wikipedia sub-article о неравномерных генераторах, кажется, вы хотите применить выход генератора псевдослучайных чисел к распределению области, которое соответствует требуемому среднему значению.

0
Assign all numbers equal probabilities, 

пока currentAverage не равна intendedAverage (Whithin возможно маржа)

pickedNumber = pick one of the possible numbers (at random, uniform probability, if you pick intendedAverage pick again) 

if (pickedNumber is greater than intendedAverage and currentAverage<intendedAverage) or (pickedNumber is less than intendedAverage and currentAverage>intendedAverage) 

    increase pickedNumber's probability by delta at the expense of all others, conserving sum=100% 

else 

    decrease pickedNumber's probability by delta to the benefit of all others, conserving sum=100% 

end if 

delta=0.98*delta (the rate of decrease of delta should probably be experimented with) 

конца в то время как