【问题标题】:implementing Poisson distribution in c++在 C++ 中实现泊松分布
【发布时间】:2015-07-21 07:35:03
【问题描述】:

我正在尝试编写一个程序来计算带有参数 lambda 的泊松分布的概率质量函数 P(x=n),使用以下公式:( (e^-lambda)*(lambda^n))/n!

当我使用小 lambda 和小数字时,这种方法效果很好,但如果我想用 lambda 20 计算例如 P(x=30),结果是 4.68903e+006,这是错误的。

我认为问题在于计算 n!。我实现了一个计算阶乘值的函数,并使用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++ 中计算这种概率?

数据类型

【问题讨论】:

  • 为什么投反对票?这个问题有什么问题?
  • @Cheiron:很难在我们看不到的代码中找到错误。 SO 指南在这一点上相当明确。
  • @MSalters 问题不必包含关于 SO 主题的代码。事实上,许多排名最高的问题都没有代码。
  • @isarandi:我知道,我关注 Meta.SO。但只要看看第三段的开头:我认为问题是......。这就是为什么我们确实需要代码(如果存在)。
  • SO 指南还具体说明了您应该在对帖子投反对票时评论错误之处。

标签: c++ distribution factorial poisson


【解决方案1】:

如果只需要从泊松分布生成随机值,否则不需要知道它的概率质量函数,最直接的方法是使用 C++11 中的predefined distribution。在 Boost 中也可以找到类似的实现。

【讨论】:

  • 我不知道有什么方法可以从std::poisson_distribution 中实际提取 pmf 的值。需要详细说明吗?
  • @T.C. :我认为您可能有一点 - 没有定义基础统一范围到泊松分布范围的映射。如果有人知道如何从给定的 C++ 发行版中提取 PMF,我将在此处留下答案。
  • 我认为在一般情况下这是不可能的。在许多情况下,您无需计算 PMF/PDF/CDF 即可生成数字。例如,normal_distribution 可能使用 Box-Muller 变换。
【解决方案2】:

尝试一些数学运算

 (lambda^n))/n!

不是吗

 (lambda/n) * (lambda/(n-1) * ...

这些数字将可以通过双精度来管理,而不是计算非常大的数字

【讨论】:

  • 这是一个糟糕的实现。评估 lambda^n 是 O(log N),评估这是 O(N)。实现这一点的正确方法(在 <random> 发行版之前的 C++98 中)是通过 Stirling's approximation 这也是 O(log N)。 (更好的方法首先计算log(( (e^-lambda)*(lambda^n))/n!),因为这很简单)
  • 它是准确的,不是近似值
  • 这将是三项内的近似值;计算机是二进制的,所以 lambda/nlambda/n-1lambda/n-2 试图除以三。
  • 在这种情况下,当 n=30 时 O(n) 真的那么糟糕吗?这个答案很简单。我可能做的唯一改变是这样做: double total = pow(lamda, n); for (int i = 2; i
【解决方案3】:

处理大 n 的一种解决方法是计算对数域中的分布:

X = ((e^-lambda)*(lambda^n))/n!
ln X = -lambda + n*ln(lambda) - Sum (ln(n))
return e^X

【讨论】:

  • ITYM n * ln(lambda)
  • ln(n!) = Sum(ln(n)) ?
  • 是的,Sum 中的n 实际上是作为索引而不是固定的n 工作的。可能是我把它简化了太多,而且我确实有点滥用了这个符号。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-13
  • 1970-01-01
相关资源
最近更新 更多