Генерация случайных чисел с учетом равномерного генератора случайных чисел - PullRequest
3 голосов
/ 19 июня 2011

Меня попросили сгенерировать случайное число от a до b включительно, используя random(0,1). random(0,1) генерирует равномерное случайное число от 0 до 1.

Я ответил

(a+(((1+random(0,1))*b))%(b-a))

Мой интервьюер не был удовлетворен моим использованием b в этом фрагменте выражения:

(((1+random(0,1))*b))

Затем я попытался изменить свой ответ на:

int*z=(int*)malloc(sizeof(int));
(a+(((1+random(0,1))*(*z)))%(b-a));

Позже вопрос изменился, чтобы сгенерировать random(1,7) из random(1,5). Я ответил:

A = rand(1,5)%3
B = (rand(1,5)+1)%3
C = (rand(1,5)+2)%3

rand(1,7) = rand(1,5)+ (A+B+C)%3

Были ли мои ответы правильными?

Ответы [ 7 ]

8 голосов
/ 19 июня 2011

Я думаю, вы запутались между генератором случайных целых чисел и генератором случайных чисел с плавающей точкой. В C ++ rand () генерирует случайное целое число от 0 до 32K. Таким образом, чтобы сгенерировать случайное число от 1 до 10, мы пишем rand ()% 10 + 1. Таким образом, чтобы сгенерировать случайное число из целого числа a в целое число b, пишем rand ()% (b - a + 1) + а.

Интервьюер сказал вам, что у вас есть генератор случайных чисел от 0 до 1. Это означает генератор чисел с плавающей точкой.

Как получить математический ответ:

  1. Переведите вопрос в простую форму, чтобы нижняя граница была равна 0.
  2. Масштабирование диапазона умножением
  3. Повторно перейти к требуемому диапазону.

Например: сгенерировать R такой, что

a <= R <= b.  
Apply rule 1, we get a-a <= R - a <= b-a 
                       0 <= R - a <= b - a.  

Думайте, что R - a как R1. Как сгенерировать R1 так, чтобы R1 имел диапазон от 0 до (b-a)?

R1 = rand(0, 1) * (b-a)   // by apply rule 2.

Теперь замените R1 на R - a

R - a = rand(0,1) * (b-a)    ==>   R = a + rand(0,1) * (b-a)

==== 2-й вопрос - без объяснения причин ====

У нас есть 1 <= R1 <= 5 </p>

==>   0 <= R1 - 1             <= 4
==>   0 <= (R1 - 1)/4         <= 1
==>   0 <= 6 * (R1 - 1)/4     <= 6
==>   1 <= 1 + 6 * (R1 - 1)/4 <= 7

Таким образом, Rand (1,7) = 1 + 6 * (rand (1,5) - 1) / 4

4 голосов
/ 19 июня 2011

случайно (a, b) из случайных (0,1):

random(0,1)*(b-a)+a

случайный (c, d) из случайного (a, b):

(random(a,b)-a)/(b-a)*(d-c)+c

или, упрощенно для вашего случая (a = 1, b = 5, c = 1, d = 7):

random(1,5) * 1.5 - 0.5

(примечание: я предполагаю, что мы говорим о значениях с плавающей точкой и ошибки округления незначительны)

2 голосов
/ 19 июня 2011
random(a,b) from random(c,d) = a + (b-a)*((random(c,d) - c)/(d-c))

Нет?

1 голос
/ 19 июня 2011

[random (0,1) * (b-a)] + a, я думаю, что даст случайные числа b / w a & b. ([random (1,5) -1] / 4) * 6 + 1 должен давать случайные числа в диапазоне (1,7) Я не уверен, что вышесказанное разрушит равномерное распределение ..

0 голосов
/ 30 июня 2019

Я думаю, что есть более хороший ответ на это.Есть одно значение (вероятность -> ноль), что это переполнение и, следовательно, модуль есть.

  1. Взять случайное число x в интервале [0,1].

  2. Увеличьте значение upper_bound, которое может быть параметром, на единицу.

  3. Вычислить (int(random() / (1.0 / upper_bound)) % upper_bound) + 1 + lower_bound .

Это должно вернуть число в желаемом интервале.

0 голосов
/ 19 июня 2011

с учетом случайного (0,5) вы можете сгенерировать случайное (0,7) следующим образом

A = случайный (0,5) * случайный (0,5) теперь диапазон А составляет 0-25

если мы просто возьмем модуль 7 из A, мы можем получить случайные числа, но они не будут действительно случайными, так как для значений A от 22-25 вы получите 1-4 значения после операции по модулю, следовательно, по модулю 7 из диапазона (0,25) смещение выхода в сторону 1-4. Это связано с тем, что 7 не делит поровну на 25: наибольшее значение, кратное 7, меньше или равное 25, равно 7 * 3 = 21, и именно числа в неполном диапазоне от 21 до 25 вызовут смещение.

Самый простой способ решить эту проблему - сбросить эти числа (с 22-25) и продолжать связывать снова, пока не появится число в подходящем диапазоне.

Очевидно, это верно, когда мы предполагаем, что нам нужны случайные целые числа.

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

0 голосов
/ 19 июня 2011

Были ли мои ответы правильными?

Я думаю, что есть некоторые проблемы.

Прежде всего, я предполагаю, что random() возвращает значение с плавающей запятой - в противном случае для генерации любого полезного распределения большего диапазона чисел с использованием random(0,1) потребуются повторные вызовы для создания пула битов для работы.

Я также собираюсь предположить, что C / C ++ является предполагаемой платформой, поскольку вопрос помечен как таковой.

Учитывая эти предположения, одна проблема с вашими ответами заключается в том, что C / C ++ не позволяет использовать оператор % для типов с плавающей запятой.

Но даже если мы представим, что оператор % был заменен функцией, которая выполняла операцию по модулю с аргументами с плавающей запятой разумным образом, все еще есть некоторые проблемы. В вашем первоначальном ответе, если b (или неинициализированный *z, выделенный во второй попытке - я предполагаю, что это своего рода причудливый способ получить произвольное значение или что-то еще предназначено?) Равен нулю (скажем, диапазон, заданный для a и b, равен (-5, 0)), тогда ваш результат будет явно неоднородным. Результат всегда будет b.

Наконец, я, конечно, не статистик, но в вашем окончательном ответе (чтобы сгенерировать random(1,7) из random(1.5)) я почти уверен, что A+B+C будет неравномерным и, следовательно, приведет к смещению в результат.

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