Как правильно расширить интервал [0,1] до [a,b]?
Многие генераторы случайных чисел возвращают плавающие числа от 0 до 1.
Какой лучший и правильный способ получить целые числа между a и b?
5 ответов
Разделите интервал [0,1] на ячейки B-A+1
Пример А =2, В =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.
В реальном случайном распределении (не псевдо) 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"]
Ну, а почему бы просто не посмотреть, как 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
>>>
Другой способ взглянуть на это, где r - ваше случайное число в диапазоне от 0 до 1:
(1-r)a + rb
Что касается вашего дополнительного требования, чтобы результат был целым числом, возможно (кроме использования встроенного приведения) оператор модуля может вам помочь. Проверьте этот вопрос и ответ:
Если предположить, r_a_b
желаемое случайное число между a
а также b
а также r_0_1
это случайное число между 0
а также 1
следующее должно работать просто отлично:
r_a_b = (r_0_1 * (b-a)) + a