Генерация случайного числа в диапазоне - PullRequest
7 голосов
/ 07 декабря 2009

Я делал это раньше, но теперь я снова борюсь с этим, и я думаю, что я не понимаю математику, лежащую в основе проблемы.

Я хочу установить случайное число в небольшом диапазоне по обе стороны от 1. Примерами могут быть .98, 1.02, .94, 1.1 и т. Д. Все примеры, которые я нахожу, описывают получение случайного числа между 0 и 100, но как я могу использовать это, чтобы попасть в диапазон, который я хочу?

Язык программирования здесь не имеет большого значения, хотя я использую Pure Data. Может кто-нибудь объяснить, пожалуйста, математику?

Ответы [ 15 ]

1 голос
/ 07 декабря 2009

Вы хотите диапазон от -1 до 1 в качестве вывода из вашего выражения rand ().

( rand(2) - 1 )

Затем масштабируйте этот диапазон от -1 до 1 по мере необходимости. Скажем, для варианта .1 с обеих сторон:

(( rand(2) - 1 ) / 10 )

Тогда просто добавьте один.

(( rand(2) - 1 ) / 10 ) + 1
1 голос
/ 07 декабря 2009

Разделите на 100 и добавьте 1. (Я полагаю, вы ищете диапазон от 0 до 2?)

0 голосов
/ 25 ноября 2012

Для чисел от 0,9 до 1,1

семя = 1

диапазон = 0,1

, если ваш случайный от 0..100

f_rand = random / 100

сгенерированный номер

gen_number = (seed + f_rand * range * 2) -range

Вы получите 1,04; 1,08; 1,01; 0,96; ...

с семенами 3, диапазон 2 => 1,95; 4,08; 2,70; 3,06; ...

0 голосов
/ 24 ноября 2012

Я не понял этого (извините):

Я пытаюсь установить случайное число по обе стороны от 1: .98, 1.02, .94, 1.1 и т. Д.

Итак, вместо этого я предоставлю общее решение проблемы.


Преобразование генератора случайных чисел

Если у вас есть генератор случайных чисел в заданном диапазоне [0, 1) * с равномерным распределением, вы можете преобразовать его в любое распределение, используя следующий метод:

1 - Опишите распределение как функцию, определенную в выходном диапазоне и имеющую общую площадь 1. Таким образом, эта функция равна f (x) = вероятность получения значения x.

2 - интегрировать ** функцию.

3 - приравнять его к "случайному" *.

4 - Решите уравнение для х. Таким образом, ti дает вам значение x в функции рандома.

*: Обобщение для любого входного распределения приведено ниже.

**: постоянный член интегрированной функции равен 0 (то есть вы просто отбрасываете его).

**: Это переменная, представляющая результат генерации случайного числа с равномерным распределением в диапазоне [0, 1). [Я не уверен, что это правильное имя на английском языке]

Пример

Допустим, вам нужно значение с распределением f(x)=x^2 from 0 to 100. Хорошо, эта функция не нормализована, потому что общая площадь ниже функции в диапазоне составляет 1000000/3, а не 1. Таким образом, вы нормализуете ее, масштабируя кривую по вертикальной оси (сохраняя относительные пропорции), то есть делите на общую площадь: f(x)=3*x^2 / 1000000 from 0 to 100.

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

Встроенная функция: F(x)=x^3/1000000+c. И приравнять его к случайному: r=x^3/1000000 (помните, что мы отбрасываем постоянный термин).

Теперь нам нужно решить уравнение для x, получив выражение: x=100*r^(1/3). Теперь вы можете использовать эту формулу для генерации чисел с желаемым распределением.

обобщение

Если у вас есть генератор случайных чисел с пользовательским распределением и вы хотите другое другое произвольное распределение, вам сначала понадобится функция исходного распределения, а затем используйте ее для выражения целевого произвольного генератора случайных чисел. Чтобы получить функцию распределения, выполните шаги до 3. Для цели выполните все шаги, а затем замените randomic на выражение, которое вы получили из исходного распределения.

Это лучше понять на примере ...

Пример

У вас есть генератор случайных чисел с равномерным распределением в диапазоне [0, 100), и вы хотите .. такое же распределение f(x)=3*x^2 / 1000000 from 0 to 100 для простоты [Поскольку для этого мы уже сделали все шаги, давая нам x=100*r^(1/3)] .

Поскольку распределение источника равномерно, функция постоянна: f(z)=1. Но нам нужно нормализовать диапазон, оставив нам: f(z)=1/100.

Теперь мы интегрируем его: F(z)=z/100. И приравниваем его к случайному: r=z/100, но на этот раз мы не решаем это для x, вместо этого мы используем его для замены r в цели:

x=100*r^(1/3) where r = z/100
=>
x=100*(z/100)^(1/3)
=>
x=z^(1/3)

И теперь вы можете использовать x=z^(1/3) для вычисления случайных чисел с распределением f(x)=3*x^2 / 1000000 from 0 to 100, начиная со случайного числа в распределении f(z)=1/100 from 0 to 100 [равномерное].

Примечание. Если у вас нормальное распределение, используйте функцию звонка. Тот же метод работает для любого другого дистрибутива. Позаботьтесь о возможной асимптоте некоторых дистрибутивов, которые могут быть созданы, вам может понадобиться попробовать разные способы решения уравнений.

На дискретных распределениях

Иногда вам нужно выразить дискретное распределение, например, вы хотите получить 0 с вероятностью 95% и 1 с вероятностью 5%. Так как ты это делаешь?

Ну, вы делите его на прямоугольные распределения таким образом, что диапазоны объединяются с [0, 1) и используете случайное распределение для оценки:

         0 if r is in [0, 0.95)
f(r) = {
         1 if r is in [0.95, 1)

Или вы можете выбрать сложный путь, то есть написать функцию распределения, подобную этой (делая каждый параметр точно равным диапазону длины 1):

         0.95 if x is in [0, 1)
f(x) = {
         0.5 if x is in [1, 2)

Поскольку каждый диапазон имеет длину 1, а назначенные значения суммируются до 1, мы знаем, что общая площадь равна 1. Теперь следующим шагом будет интеграция:

         0.95*x if x is in [0, 1)
F(x) = {
         (0.5*(x-1))+0.95 = 0.5*x + 0.45 if x is in [1, 2)

Приравнивает его к случайному:

         0.95*x if x is in [0, 1)
r = {
         0.5*x + 0.45 if x is in [1, 2)

И решить уравнение ...

Хорошо, чтобы решить уравнение такого рода, начните с вычисления выходных диапазонов, применяя функцию:

[0, 1) becomes [0, 0.95)
[1, 2) becomes [0.95, {(0.5*(x-1))+0.95 where x = 2} = 1)

Теперь это диапазоны для решения:

         ? if r is in [0, 0.95)
x = {
         ? if r is in [0.95, 1)

Теперь решите внутренние функции:

         r/0.95 if r is in [0, 0.95)
x = {
         2*(r-0.45) = 2*r-0.9 if r is in [0.95, 1)

Но, поскольку выходные данные являются дискретными, мы получим тот же результат после выполнения целочисленной части:

         0 if r is in [0, 0.95)
x = {
         1 if r is in [0.95, 1)

Примечание: использовать случайное значение для обозначения псевдослучайного.


Редактировать : Нашел это в Википедии (я знал, что не изобрел это).

0 голосов
/ 24 ноября 2012
var randomNumber = Math.random();
while(randomNumber<0.9 && randomNumber>0.1){
    randomNumber = Math.random();
}

if(randomNumber>=0.9){
    alert(randomNumber);
}
else if(randomNumber<=0.1){
    alert(1+randomNumber);
}
...