Создайте случайное число с max, min и mean (average) в Java
Мне нужно генерировать случайные числа со следующими свойствами.
Мин должен быть 200
Макс должен быть 20000
Среднее (среднее) - 500.
Дополнительно: 75-й процентиль будет 5000
Определенно это не равномерное распределение, а не гауссово. Мне нужно дать некоторую левую асимметрию.
Ответы
Ответ 1
Java Random, вероятно, не будет работать, потому что он дает только нормальные (гауссовские) дистрибутивы.
То, что вы, вероятно, ищете, - это f-дистрибутив (см. ниже). Возможно, вы можете использовать библиотеку distlib здесь и выбрать f distribution. Вы можете использовать метод random для получения вашего случайного числа.
![enter image description here]()
Ответ 2
Скажите X
- ваша целевая переменная, позволяющая нормализовать диапазон, выполнив Y=(X-200)/(20000-200)
. Итак, теперь вам нужна какая-то случайная переменная Y
, которая принимает значения в [0,1]
со средним значением (500-200)/(20000-200)=1/66
.
У вас много вариантов, самый естественный мне кажется бета-дистрибутив, Y ~ Beta(a,b)
с a/(a+b) = 1/66
- у вас есть дополнительную степень свободы, которую вы можете выбрать либо для соответствия последнему требованию квартили.
После этого вы просто возвращаете X как Y*(20000-200)+200
Чтобы сгенерировать бета-случайную переменную, вы можете использовать Apache Commons или посмотреть здесь.
Ответ 3
Это не может быть ответ, который вы ищете, но конкретный случай с 3 равномерными распределениями:
(Игнорируйте числа слева, но они будут масштабироваться!)
public int generate() {
if(random(0, 65) == 0) {
// 50-100 percentile
if(random(1, 13) > 3) {
// 50-75 percentile
return random(500, 5000);
} else {
// 75-100 percentile
return random(5000, 20000);
}
} else {
// 0-50 percentile
return random(200, 500);
}
}
Как я получил числа
Во-первых, площадь под кривой равна 200-500 и 500-20000. Это означает, что отношение высоты 300 * leftHeight == 19500 * rightHeight
делает leftHeight == 65 * rightHeight
Это дает нам шанс на выбор 1/66, а шанс 65/66 выбрать левый.
Затем я сделал тот же расчет для 75-го процентиля, за исключением того, что отношение было 500-5000 chance == 5000-20000 chance * 10 / 3
. Опять же, это означает, что у нас есть шанс 10/13 находиться в 50-75 процентилях, а шанс 3/13 - 75-100.
Kudos to @Stas - я использую его функцию "inclusive random".
И да, я понимаю, что мои цифры ошибочны, поскольку этот метод работает с дискретными числами, и мои вычисления были непрерывными. Было бы хорошо, если бы кто-то мог исправить мои пограничные случаи.
Ответ 4
У вас может быть функция f, работающая с [0; 1], например
Integral(f(x)dx) on [0;1] = 500
f(0) = 200
f(0.75) = 5000
f(1) = 20000
Я предполагаю, что функция вида
f(x) = a*exp(x) + b*x + c
может быть решением, вам просто нужно решить соответствующую систему.
Затем вы делаете f(uniform_random(0,1))
и там вы!
Ответ 5
Распределение PERT (или распространение бета-PERT) рассчитано на минимальный и максимальный и оценочный режимы. Это "сглаженная" версия треугольного распределения, и генерация случайного числа из этого распределения может быть реализована следующим образом:
startpt + (endpt - startpt) *
BetaDist(1.0 + (midpt - startpt) * shape / (endpt - startpt),
1.0 + (endpt - midpt) * shape / (endpt - startpt))
где —
-
startpt
является минимальным,
-
midpt
- это режим (не обязательно средний или средний),
-
endpt
- максимум,
-
shape
- это число 0 или больше, но обычно 4 и
-
BetaDist(X, Y)
возвращает случайное число из бета-распределения с параметрами X
и Y
.
Учитывая известное среднее (mean
), midpt
можно вычислить:
3 * mean / 2 - (startpt + endpt) / 4