Реализация неоднородного генератора случайных чисел? - PullRequest
5 голосов
/ 08 октября 2009

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

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

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

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

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

Ответы [ 8 ]

6 голосов
/ 08 октября 2009

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

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

Биномиальное распределение можно довольно легко аппроксимировать с помощью равномерного ГСЧ. Просто выполните n испытаний и запишите количество успехов. Так что, если у вас n = 10 и p = 0.5, это все равно, что подбрасывать монету 10 раз подряд и считать количество голов. Для p = 0,25 просто сгенерируйте равномерно распределенные значения между 0 и 3 и считайте только нули как успехи.

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

3 голосов
/ 08 октября 2009

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

2 голосов
/ 08 октября 2009

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

// 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 голос
/ 08 октября 2009

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

1 голос
/ 08 октября 2009

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

Это еще не все, если вам нужны конкретные характеристики при распределении вашего нового, неоднородного PRNG. Это рассмотрено на странице Википедии по PRNG , и конкретно упоминается алгоритм Ziggurat .

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

0 голосов
/ 08 октября 2009
Assign all numbers equal probabilities,

, в то время как currentAverage не равно предназначенному Average (с возможным запасом)

 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)

конец пока

0 голосов
/ 08 октября 2009

Вам нужен распределенный / взвешенный генератор случайных чисел. Вот ссылка , с которой можно начать.

0 голосов
/ 08 октября 2009

Моя первая идея будет:

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

это должно дать вам числа в нужном вам диапазоне.

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