Можно ли получить случайное число от 1 до 100 и сохранить результаты в основном в диапазоне 40–60? Я имею в виду, что из этого диапазона он будет выходить редко, но я хочу, чтобы он был в основном в этом диапазоне ... Возможно ли это с помощью JavaScript / jQuery?
Прямо сейчас я просто использую основное Math.random() * 100 + 1
.
javascript
algorithm
random
numbers
Даррил хаффман
источник
источник
Ответы:
Самый простой способ - сгенерировать два случайных числа от 0 до 50 и сложить их вместе.
Это дает распределение, смещенное к 50, таким же образом, кидая два смещения костей к 7.
Фактически, используя большее количество «кубиков» (как предлагает @Falco) , вы можете приблизить приближение к кривой колокола:
JSFiddle: http://jsfiddle.net/797qhcza/1/
источник
У вас есть несколько хороших ответов, которые дают конкретные решения; позвольте мне описать для вас общее решение. Проблема в:
Общее решение этой проблемы заключается в разработке функции квантиля желаемого распределения, а затем применить квантильную функцию к выходу вашего единого источника.
Функция квантиля является обратной к интегралу желаемой функции распределения . Функция распределения - это функция, в которой площадь под частью кривой равна вероятности того, что случайно выбранный элемент будет в этой части.
Я приведу пример того, как это сделать здесь:
http://ericlippert.com/2012/02/21/generating-random-non-uniform-data/
Код есть в C #, но принципы применимы к любому языку; Это должно быть просто адаптировать решение для JavaScript.
источник
Взятие массивов чисел и т. Д. Неэффективно. Вы должны взять отображение, которое принимает случайное число от 0 до 100 и отображает в нужное вам распределение. Таким образом, в вашем случае вы можете получить распределение с наибольшим количеством значений в середине вашего диапазона.
f(x)=-(1/25)x2+4x
источник
x
от 0 до 100 (взято из этого вопроса ):y = (Math.sin(2 * Math.PI * (x/100 - 1/4)) + 1) / 2
Я мог бы сделать что-то вроде установки «шанса» для того, чтобы число могло выйти «за пределы». В этом примере с вероятностью 20% число будет 1-100, в противном случае 40-60:
скрипка: http://jsfiddle.net/kbv39s9w/
источник
Мне нужно было решить эту проблему несколько лет назад, и мое решение было проще, чем любой другой ответ.
Я создал 3 случайных числа между границами и усреднил их. Это тянет результат к центру, но делает возможным достижение конечностей.
источник
BellFactor
3Это выглядит глупо, но вы можете использовать rand дважды:
источник
Конечно, это возможно. Сделать случайный 1-100. Если число <30, генерируйте число в диапазоне 1-100, если не генерируйте в диапазоне 40-60.
источник
Существует много разных способов генерации таких случайных чисел. Один из способов сделать это - вычислить сумму нескольких равномерно случайных чисел. Сколько случайных чисел вы суммируете и каков их диапазон, будет определять, как будет выглядеть окончательное распределение.
Чем больше чисел вы подведете, тем больше будет смещение в сторону центра. Использование суммы 1 случайного числа уже было предложено в вашем вопросе, но, как вы заметили, не смещено к центру диапазона. Другие ответы предлагают использовать сумму 2 случайных чисел или сумму 3 случайных чисел .
Вы можете получить еще больший уклон к центру диапазона, взяв сумму более случайных чисел. В крайнем случае вы можете взять сумму из 99 случайных чисел, каждое из которых было 0 или 1. Это было бы биномиальным распределением. (Биномиальные распределения в некотором смысле можно рассматривать как дискретную версию нормальных распределений). Теоретически это может охватывать весь диапазон, но он имеет такой большой уклон к центру, что вы никогда не должны ожидать, что он достигнет конечных точек.
Этот подход означает, что вы можете настроить, насколько вы хотите смещения.
источник
Как насчет использования что-то вроде этого:
Способ, который я кодировал, позволяет вам установить пару переменных:
loops = количество результатов
попытки = количество раз, которое функция будет пытаться получить число в диапазоне 40-60, прежде чем она прекратит работу в цикле while
Дополнительный бонус: использует do while !!! Awesomeness в лучшем виде
источник
Вы можете написать функцию, которая отображает случайные значения между
[0, 1)
в[1, 100]
соответствии с весом. Рассмотрим этот пример:Здесь значение
0.95
отображается в значение между[61, 100]
.На самом деле мы имеем
.05 / .1 = 0.5
, что при сопоставлении[61, 100]
дает81
.Вот функция:
источник
Вот взвешенное решение на 3/4 40-60 и 1/4 вне этого диапазона.
источник
Итак, я решил добавить еще один ответ, потому что я чувствовал, что мой последний ответ, а также большинство ответов здесь, используют какой-то полустатистический способ получения возврата типа колокольчика. Код, который я приведу ниже, работает так же, как и при броске костей. Следовательно, сложнее всего получить 1 или 99, но проще всего получить 50.
источник
Я бы порекомендовал использовать бета-дистрибутив для генерации числа от 0 до 1, а затем увеличить его. Он довольно гибкий и может создавать различные формы распределения.
Вот быстрый и грязный сэмплер:
источник
источник
Лучшее решение, предназначенное именно для этой проблемы, - это решение, предложенное BlueRaja - Дэнни Пфлюгофт, но я думаю, что стоит упомянуть и более быстрое и более общее решение.
Когда мне нужно генерировать случайные числа (строки, пары координат и т. Д.), Удовлетворяющие двум требованиям:
Я обычно начинаю с создания массива чисел (строки, пары координат и т. Д.), Удовлетворяющего требованию (в вашем случае: массив чисел, содержащий более вероятные несколько раз). Затем выбираю случайный элемент этого массива. Таким образом, вам нужно вызывать дорогую случайную функцию только один раз для каждого элемента.
источник
распределение
Решение
Общее решение
источник
Вы можете использовать вспомогательное случайное число, чтобы генерировать случайные числа в 40-60 или 1-100:
источник
Если вы можете использовать
gaussian
функцию, используйте ее. Эта функция возвращает нормальное число сaverage 0
иsigma 1
.95% этого числа находятся в пределах
average +/- 2*sigma
. Вашaverage = 50
иsigma = 5
такисточник
Лучший способ сделать это - сгенерировать случайное число, которое распределено поровну по определенному набору чисел, а затем применить функцию проекции к набору от 0 до 100, где проекция с большей вероятностью достигнет нужных вам чисел.
Обычно математическим способом достижения этого является построение функции вероятности нужных вам чисел. Мы могли бы использовать кривую колокольчика, но давайте для простоты вычислений просто поработаем с перевернутой параболой.
Давайте сделаем параболу такой, чтобы ее корни были равны 0 и 100, не наклоняя ее. Мы получаем следующее уравнение:
Теперь вся область под кривой между 0 и 100 представляет наш первый набор, в котором мы хотим получить числа. Там поколение совершенно случайно. Итак, все, что нам нужно сделать, это найти границы нашего первого набора.
Нижняя граница, конечно, равна 0. Верхняя граница - это интеграл нашей функции в 100, который
Итак, мы знаем, что нам нужно сгенерировать число где-то между 0 и 166 666. Затем нам просто нужно взять это число и спроецировать его на наш второй набор, который находится между 0 и 100.
Мы знаем, что случайное число, которое мы сгенерировали, является некоторым интегралом нашей параболы с входным значением x между 0 и 100. Это означает, что мы просто должны предположить, что случайное число является результатом F (x), и решить для x.
В этом случае F (x) является кубическим уравнением, и в форме
F(x) = ax^3 + bx^2 + cx + d = 0
следующие утверждения верны:Решив это для х, вы получите фактическое случайное число, которое вы ищете, которое гарантированно будет в диапазоне [0, 100] и гораздо более высокую вероятность быть ближе к центру, чем края.
источник
Этот ответ действительно хорош . Но я хотел бы опубликовать инструкции по реализации (я не в JavaScript, так что я надеюсь, что вы поймете) для другой ситуации.
Предположим, у вас есть диапазоны и веса для каждого диапазона:
Исходная статическая информация, может быть кэширована:
Boundary[n] = Boundary[n - 1] + weigh[n - 1]
аBoundary[0] = 0
. Образец имеетBoundary = {0, 1, 3, 103, 108}
Генерация номера:
N
из диапазона [0, сумма всех весов).for (i = 0; i < size(Boundary) && N > Boundary[i + 1]; ++i)
i
th-й диапазон и сгенерируйте случайное число в этом диапазоне.Дополнительное примечание для оптимизации производительности. Диапазоны не должны быть упорядочены ни по возрастанию, ни по убыванию, поэтому для более быстрого поиска диапазона, который имеет наибольший вес, должен идти в первую очередь, а тот, который имеет наименьший вес, должен идти последним.
источник