применить обратную распределенную функцию распределения для преобразования в целевой диапазон
, как вы можете это выглядит как # 2 Применить нелинейную функцию ... , но вместо "некоторой" нелинейной функции вы используете непосредственное распределение. Так что если p(x)
- это вероятность x
в диапазоне <0..1>
, где 1
означает 100%
, то нам нужна функция, которая накапливает все вероятности вплоть до x
(извините, не знаю точного математического термина в английском языке) sh). Для целых чисел:
f(x) = p(0)+p(1)+...+p(x)
Теперь нам нужна обратная функция g()
для этого так:
y = f(x)
x = g(y)
Теперь, если моя память хорошо мне служит, тогда поколение должно выглядеть так:
y = random(); // <0..1>
x = g(y); // probability -> value
Во многих дистрибутивах есть функция g()
, но для тех, кто не (или нам лень ее выводить), вы можете использовать бинарный поиск в p(x)
. Лень его кодировать, поэтому здесь медленнее линейного поиска версии:
for (x=0;x<max;x++) if (f(x)>=y) break;
Итак, когда все сложено (и только с использованием p(x)
), я получил (C ++):
y=random(); // uniform distribution pseudo random value in range <0..1>
for (f=0.0,x=0;x<max;x++) // loop x through all values
{
f+=p(x); // f(x) cumulative distribution function
if (f>=y) break;
}
// here x is your pseudo random value following p(x) distribution