Я пытаюсь написать программу для вычисления вероятностной функции массы распределения Пуассона P (x = n) с параметром лямбда, используя эту формулу: ( (e^-lambda)*(lambda^n))/n!
Этот подход хорошо работает, когда я использую маленькую лямбду и маленькие числа, но если я хочу вычислить, например, P (x = 30) с лямбда 20, результат будет 4.68903e + 006, что неверно.
Я думаю, что проблема заключается в расчете п! Я реализовал функцию для расчета факториального значения и использовал unsigned long long
Тип данных для результата факториального расчета, но проблема в том, что сумма 30! равно 265,252,859,812,191,058,636,308,480,000,000, а максимальное число, доступное для unsigned long long, составляет 18,446,744,073,709,551,615, что меньше 30 !.
Что я должен сделать, чтобы решить эту проблему? Есть ли другой способ или любая функция для вычисления этой возможности в C ++?
тип данных
Одним из обходных путей для работы с большими n является вычисление распределения в домене журнала:
X = ((e^-lambda)*(lambda^n))/n!
ln X = -lambda + n*ln(lambda) - Sum (ln(n))
return e^X
Попробуйте немного математики
(lambda^n))/n!
Это не
(lambda/n) * (lambda/(n-1) * ...
и этими числами можно будет управлять с помощью двойных чисел вместо вычисления очень больших чисел
Если нужно только генерировать случайные значения из распределения Пуассона, и в противном случае делает не нужно знать его функция вероятности массы, самый прямой способ заключается в использовании предопределенное распределение который является частью C ++ 11. Аналогичная реализация также может быть найдена в Boost.