Генерация случайного числа с максимальным, минимальным и средним (средним) в Java - PullRequest
20 голосов
/ 15 марта 2011

Мне нужно сгенерировать случайные числа со следующими свойствами.

Минимальное значение должно составлять 200

Максимальное значение должно составлять 20000

Среднее (среднее) равно 500.

Необязательно: 75-й процентиль равен 5000

Определенно, это не равномерное распределение и не гауссово.Мне нужно дать немного левой асимметрии.

Ответы [ 5 ]

12 голосов
/ 15 марта 2011

Java Random, вероятно, не будет работать, потому что он дает вам только нормальные (гауссовские) дистрибутивы.

Вероятно, вы ищете дистрибутив f (см. Ниже).Вероятно, вы можете использовать библиотеку distlib здесь и выбрать f дистрибутив .Вы можете использовать метод random , чтобы получить ваше случайное число.

enter image description here

8 голосов
/ 09 июня 2011

Скажите 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 или посмотреть здесь .

4 голосов
/ 10 июня 2011

Возможно, это не тот ответ, который вы ищете, а конкретный случай с 3 равномерными распределениями:

Uniform distributions (Игнорируйте числа слева, но это в масштабе!)

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.

Престижность @Stas - я использую его «включающую случайную» функцию.

И да, я понимаю, что мои числа неверны, так как этот метод работает с дискретными числами, и мои вычисления были непрерывными. Было бы хорошо, если бы кто-то мог исправить мои пограничные случаи.

3 голосов
/ 16 марта 2011

У вас может быть функция 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)) и вот вы!

0 голосов
/ 23 июля 2017

Распределение PERT (или бета-PERT распределение ) предназначено для принятия минимального, максимального и расчетного режима. Это «сглаженная» версия треугольного распределения, и генерация случайного числа из этого распределения может быть реализована следующим образом:

startpt + (endpt - startpt) * 
     BetaDist(1.0 + (midpt - startpt) * shape / (endpt - startpt), 
          1.0 + (endpt - midpt) * shape / (endpt - startpt))

, где & mdash;

  • startpt это минимум,
  • midpt - режим (не обязательно средний или средний),
  • endpt это максимум,
  • shape - это число 0 или больше, но обычно 4 и
  • BetaDist(X, Y) возвращает случайное число из бета-распределения с параметрами X и Y.

Учитывая известное среднее (mean), midpt можно рассчитать по:

3 * mean / 2 - (startpt + endpt) / 4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...