我一直在环顾四周,但我不确定该怎么做。

我找到了 这一页 在最后一段中说:

使用此简单食谱获得了从泊松分布中获取的随机数的简单发电机:如果x1, , X2, ,...是一系列随机数,在零和一个之间,k是乘积x的第一个整数1 · X2 · ... · XK+1 <e

我找到了 另一页 描述如何生成二项式数字,但我认为它正在使用泊松生成的近似值,这对我没有帮助。

例如,考虑二项式随机数。二项式随机数是在任何单个掷骰上具有头部概率p的n折扣中的头部数量。如果您在间隔(0,1)上生成n均匀的随机数,并且计数小于p的数字,则计数是带有参数n和p的二项式随机数。

我知道有库可以做,但是我不能使用它们,只有该语言提供的标准统一发电机(在这种情况下为Java)。

有帮助吗?

解决方案

泊松分布

这是 维基百科是如何做的:

init:
     Let L ← e^(−λ), k ← 0 and p ← 1.
do:
     k ← k + 1.
     Generate uniform random number u in [0,1] and let p ← p × u.
while p > L.
return k − 1.

在Java,那将是:

public static int getPoisson(double lambda) {
  double L = Math.exp(-lambda);
  double p = 1.0;
  int k = 0;

  do {
    k++;
    p *= Math.random();
  } while (p > L);

  return k - 1;
}

二项分布

按照第10章 非均匀随机变异产生 (PDF) 卢克·德文(Luc Devroye) Wikipedia文章)给出:

public static int getBinomial(int n, double p) {
  int x = 0;
  for(int i = 0; i < n; i++) {
    if(Math.random() < p)
      x++;
  }
  return x;
}

请注意

这些算法都不是最佳的。第一个是o(λ),第二个是o(n)。根据这些值通常的大小以及需要调用发电机的频率,您可能需要更好的算法。我链接到上面的论文具有恒定时间运行的更复杂的算法,但是我将这些实现作为读者的练习。 :)

其他提示

对于这个和其他数值问题,圣经是数值食谱书。

这里有一个免费版本: http://www.nrbook.com/a/bookcpdf.php (需要插件)

或者您可以在Google书籍上看到它: http://books.google.co.uk/books?id=4t-sybvuoqoc&lpg=pp1&ots=5ihminlHo&dq = numerical%20Recipes%20Recipes%20IN%20CC&pg = pp1pp1#v = v = nopage&q =&q = f = false

C代码应该很容易传输到Java。

对于许多数值问题,这本书值得它的黄金重量。在上面的网站上,您还可以购买该书的最新版本。

尽管KIP发布的答案对于以较小的到达率(Lambda)生成泊松RV非常有效,但第二个算法在Wikipedia中发布 生成泊松随机变量 由于数值稳定性,对于较大的到达率更好。

在实施其中一个项目中,我面临问题,要求生成托有托管RV,因此lambda非常高。所以我建议另一种方式。

以下库(Java代码)中的CERN有几个实现:

http://acs.lbl.gov/~hoschek/colt/

关于二项式随机数,它基于1988年的“二项式随机变量生成”的论文,我建议您使用优化的算法。

问候

您可以将其添加到build.gradle

implementation 'org.kie.modules:org-apache-commons-math:6.5.0.Final'

并使用课程 Poissondistribution 班级分配的更多详细信息

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top