Как правильно расширить интервал [0,1] до [a, b]? - PullRequest
3 голосов
/ 14 июня 2010

Многие генераторы случайных чисел возвращают плавающие числа от 0 до 1.

Какой самый лучший и правильный способ получить целых чисел между a и b ?

Ответы [ 5 ]

5 голосов
/ 14 июня 2010

Разделите интервал [0,1] на B-A + 1 бункер

Пример A = 2, B = 5

        [----+----+----+----]
        0    1/4  1/2  3/4  1
Maps to    2    3    4    5

Проблема с формулой

 Int (Rnd() * (B-A+1)) + A

означает, что ваш интервал генерации Rnd () закрыт с обеих сторон, поэтому 0 и 1 являются возможными выходами, и формула дает 6, когда Rnd () точно равно 1.

Inреальное случайное распределение (не псевдо), вероятность 1 равна нулю.Я думаю, что достаточно безопасно программировать что-то вроде:

 r=Rnd()
 if r equal 1
     MyInt = B
 else
     MyInt = Int(r * (B-A+1)) + A
 endif

Редактировать

Просто быстрый тест в Mathematica :

Определите нашу функцию:

f[a_, b_] :=  If[(r = RandomReal[]) == 1, b, IntegerPart[r (b - a + 1)] + a]

Создайте таблицу из 3 10 ^ 5 чисел в [1100]:

table = SortBy[Tally[Table[f[1, 100], {300000}]], First]

Проверьте минимальное и максимальное:

In[137]:= {Max[First /@ table], Min[First /@ table]}

Out[137]= {100, 1}  

Давайте посмотрим распределение:

BarChart[Last /@ SortBy[Tally[Table[f[1, 100], {300000}]], First],
        ChartStyle -> "DarkRainbow"]  

alt text

1 голос
/ 14 июня 2010

Ну, а почему бы просто не посмотреть, как Python делает это сам?Прочитайте random.py в каталоге lib вашей установки.

После того, как его потрошили, чтобы поддерживать только поведение random.randint() (что вам нужно) и удалите все проверки ошибок для нецелых или не целыхаргументы, вы получите:

import random
def randint(start, stop):
    width = stop+1 - start
    return start + int(random.random()*width)

Тестирование:

>>> l = []
>>> for i in range(2000000):
...     l.append(randint(3,6))
...
>>> l.count(3)
499593
>>> l.count(4)
499359
>>> l.count(5)
501432
>>> l.count(6)
499616
>>>
1 голос
/ 14 июня 2010

Другой способ взглянуть на это, где r - ваше случайное число в диапазоне от 0 до 1:

(1-r)a + rb

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

Расширьте случайный диапазон от 1–5 до 1–7

0 голосов
/ 14 июня 2010

Предполагая, что r_a_b - это желаемое случайное число от a до b, а r_0_1 - это случайное число от 0 до 1, следующее должно работать нормально:

r_a_b = (r_0_1 * (b-a)) + a
0 голосов
/ 14 июня 2010
X = (Rand() * (B - A)) + A
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...