AlexaShemetova
@AlexaShemetova
While I'm breathing - I love and believe

Как работает функция случайного числа от min до max?

Всем привет) объясните пожалуйста как именно работает данная функция, что значит выровнять интервалы и вероятности? Я нубик :)

Есть много правильных решений этой задачи. Одно из них – правильно указать границы интервала. Чтобы выровнять интервалы, мы можем генерировать числа от 0.5 до 3.5, это позволит добавить необходимые вероятности к min и max:
function randomInteger(min, max) {
  // получить случайное число от (min-0.5) до (max+0.5)
  let rand = min - 0.5 + Math.random() * (max - min + 1);
  return Math.round(rand);
}
alert( randomInteger(1, 3) );
  • Вопрос задан
  • 886 просмотров
Решения вопроса 1
sergiks
@sergiks Куратор тега JavaScript
♬♬
Math.random() возвращает псевдослучайное с равномерной вероятостью в диапазоне от 0 до 1. Включая 0, исключая 1. Такой интервал ещё можно записать как [0, 1) — квадратная скобка означает включение числа, круглая – «дырку», исключение.

Math.round() округляет дробные до «ближайшего» целого. От x - 0.5 (включая) до x + 0.5 (исключая) округлит до целого x. Можно записать так: [x-0.5, x+0.5)

Функция получения случайного целого в диапазоне от min до max в описанном варианте старается сгладить вероятности всех целых до равных.

Визуально это представить так: насыпается «дорожка» поваренной соли на диапазон от 0 до 1 – это равномерно распределённые вероятности из Math.random(). При этом сама "1" не участвует, но в данном случае это маловажно. Далее умножаем да диапазон, напр. на 4, и с помощью Math.round() делим отрезки этой дорожки в кучки для каждого целого. Кучки по краям получатся меньше остальных.

Если случайное [0, 1) просто умножить на 4 и округлить Math.round() – будет выдавать случайные целые [0, 4] (а не до 3). И как неравновероятно!
0                   1
[...................)

0    1    2    3    4
00011111222223333344o


Из-за того, что Math.round() разбивает пополам расстояние между двумя целыми, получится не 4 а 5 кучек. При чём в крайние, 0 и 4, попадёт всего по пол-интервала. Их вероятность будет 1/2 от полноценных вероятностей для 1, 2 и 3.

Поэтому, в данной реализации генерируют от min-0.5 до max+0.5, чтобы после Math.round() вероятности всех целых были одинаковы.

P. S. за эту размазанность Math.round() можно недолюбливать и вместо него округлять вниз, Math.floor() – так случайное целое, как в вашем вопросе, можно получить проще
const rand = (min, max) => min + Math.floor(Math.random() * (max - min + 1));
alert( rand(1, 3) );

Кстати, в программировании часто предпочитают иметь дело с интервалами [ .. ) – включающими начало, но исключающими конец. Например, randomInteger(min, max) никогда бы не вернула max. А это задание вышло такое себе, нетрадиционное, у них )
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы