【问题标题】:Binomial random number generation二项式随机数生成
【发布时间】:2016-07-31 11:32:05
【问题描述】:

我正在努力在 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如何?

【问题讨论】:

  • 您可以为一定次数的生成函数调用生成介于 0 和 n/2 之间的随机数,然后切换回从 0 到 n 的生成;来回切换应该会给您更多的较低值。你可以概括一下。
  • @user2296177 这是一个有趣的想法。但是随机性的质量不够好
  • 你试过std::geometric_distribution吗?

标签: c++ math random distribution


【解决方案1】:

你可以生成exponential distribution

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

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

如果您的数学库中没有现成的指数分布 (std::exponential_distribution?),请使用 inverse transform sampling (Smirnov's) method

德尔福示例

 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;

【讨论】:

    【解决方案2】:

    我正在使用以下解决方法:

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

    这给出了正确的分布,但速度很慢,因为每个数字需要大约 0.9 次重试。

    【讨论】:

    • 为什么不int a = rand() % n, b = rand() % n; number = a &gt;= b? a - b : b - a;
    猜你喜欢
    • 1970-01-01
    • 2010-11-17
    • 1970-01-01
    • 1970-01-01
    • 2018-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多