二项式随机数生成

Binomial random number generation

本文关键字:随机数 二项式      更新时间:2023-10-16

我很难在C++中获得一个随机数生成器。

  • 生成器应仅返回介于0n之间的整数
  • 返回低数字的概率应该高于返回高数字的概率

示例分布:

1:  ************************
2:  ******************
3:  **************
4:  ************
5:  ********
6:  *****
7:  ****
8:  ***
9:  **
10: *

分发类型对我来说并不重要。我所尝试的是使用值为[0..2*n]的二项式分布。然后,我将得到的随机数转换为[0..n],以获得零处的峰值。

size_t n = 20;
std::default_random_engine generator;
std::binomial_distribution<int> distribution(n*2, 0.5f);
int number = fabs(distribution(generator)-n);

结果编号:

0: *************************
1: ***********************************************
2: *****************************************
3: ********************************
4: **********************
5: **************
6: ********
7: ****
8: **
9:
10-20: none. The numbers are very rare.

我的问题是:你如何正确地实现这样的算法?如何增加较高值的概率,使分布保持不变,而不考虑使用的n

您可以生成指数分布

P(x) = lambda * Exp(-lambda * x)

具有影响衰减速度的适当参数lambda。

如果您的数学库中没有现成的指数分布(std::exponential_distribution?),请使用逆变换采样(Smirnov)方法。

Delphi示例

 for i := 0 to 1000000 do begin
    V := Trunc(-ln(Random()) / lambda); 
    //Random function gives random value uniformly distributed on [0,1) 
    if V <= N then begin
      Inc(H[V]); //histogram entry
    end;
  end;

我使用以下解决方法:

do {
        number = (rand() % n) - (rand() % n);
} while(number < 0 || number > n);

这提供了一个正确的分布,但速度非常慢,因为每个数字大约需要0.9次重试。