Мне нужно генерировать случайные числа из биномиального (n, p) распределения.C#: числовой алгоритм для генерации чисел из биномиального распределения
Биномиальная (n, p) случайная величина представляет собой сумму n равномерных переменных, которые принимают 1 с вероятностью p. В псевдокоде x=0; for(i=0; i<n; ++i) x+=(rand()<p?1:0);
будет генерировать биномиальный (n, p).
Мне нужно сгенерировать это для малого и очень большого n, например n = 10^6 и p = 0,02. Есть ли какой-нибудь быстрый численный алгоритм для его создания?
EDIT -
Прямо сейчас это то, что я имею в приближении (наряду с функциями для точного Пуассона и нормальное распределение) -
public long Binomial(long n, double p) {
// As of now it is an approximation
if (n < 1000) {
long result = 0;
for (int i=0; i<n; ++i)
if (random.NextDouble() < p) result++;
return result;
}
if (n * p < 10) return Poisson(n * p);
else if (n * (1 - p) < 10) return n - Poisson(n * p);
else {
long v = (long)(0.5 + nextNormal(n * p, Math.Sqrt(n * p * (1 - p))));
if (v < 0) v = 0;
else if (v > n) v = n;
return v;
}
}
Хорошо ли работает распределение Пуассона для 'n * p <10' или для' n * (1 - p) <10'? Как вы выбираете этот дистрибутив? – HelloGoodbye
Да, для больших n. Биномиальное (n, lambda/n) сходится к Пуассону (лямбда), поскольку n переходит в бесконечность. – KalEl