C ++随机数检查非常小的概率

时间:2015-02-21 11:05:41

标签: c++ random probability

我发生事件的概率非常小(1e-5阶)并且我试图使用统一的随机数来测试成功。当概率下降到大约1e-4时,成功的分数不再与下面的测试代码中的概率相匹配。

如何以如此小的概率准确检查成功?我尝试使用其他随机数生成器,但我找到的所有建议都是针对C ++ 11的,我没有使用。非常感谢提前!

#include <cstlib>
#include <iostream>
#include <cmath>

double Prob, rand_num, frac_success;
int num_success, num_tries;

Prob = 1e-4;
num_tries = 1e8;
num_success = 0;

for (int i=0; i<num_tries; i++) {
    rand_num = (double) rand() / RAND_MAX;    // random number between 0 and 1

    if (rand_num < Prob) {
        num_success ++;              // Record success
    }
}
frac_success = double(num_success) / double(num_tries);

cout << Prob << endl << frac_success << endl;

当Prob = 1e-3时,成功的比例大致等于Prob,但对于Prob = 1e-4,它总是大于1.2e-4。差异越大,概率越低,似乎不会通过增加尝试次数来解决。

编辑:

正如DiJuMx和Stefano Sanfilippo所说,似乎rand()根本不是一个足够好的发电机。我决定改用C ++ 11,所以我可以使用uniform_real_distribution来解决这个问题(这意味着对其他非C ++ 11代码进行了更改,但是很快就没有比我想象的更改了。)

4 个答案:

答案 0 :(得分:2)

这听起来像RAND_MAX的价值太小了。

考虑rand()返回0RAND_MAX之间的整数这一事实。如果您将此数字除以RAND_MAX,那么除了0之外,您可以获得的最小数字是1.0/RAND_MAX

RAND_MAX32767时,最小值为3e-5。在我的计算机上,RAND_MAX2147483647,因此最小值为4e-10

或者,看看Stefano关于使用C ++特定库的答案。

答案 1 :(得分:0)

rand()是一个非常糟糕的RNG,它只适用于实施tic-tac-toe,但不适用于任何严肃的业务。

如果你不能使用C + 11 random模块,你仍然可以利用Boost.Random,它也适用于C ++ 03。浏览generators page并寻找最佳套装。

答案 2 :(得分:0)

首先,您必须考虑您的估算工具有一定的错误。我没有找到一个好的链接,简而言之就是:

H = success / trials      // your estimator
E(H) = p                  // the expectation value is the real probability 
Var(H) = p(1-p)/n         // variance of your estimator

仅此一点就表明,对于较小的概率,您应该获得更好的结果。

但是,正如其他答案所示,您应该使用适当的随机数生成器。

rng应该以相同的概率产生每种可能的结果(如果它是均匀的)。让我们暂时说RAND_MAX=3。如果我们经常运行它,每个可能的值将以相同的频率发生,并且我们得到相同的结果,就好像我们仅使用每个值一次。现在考虑

for (int i=0;i<4;i++){std::cout << (double)i/3 << std::endl;}

这将产生

0
0.333333
0.666667
1

对于不太小的概率,这将给出合理的结果(例如,当试图找到p=0.5时,您可以找到确切的值)。但是,当你试图找到一个小概率时,结果会太大。

RAND_MAX=32767时效果相同,它只显示较小的概率(约p < 1/RAND_MAX附近)。实际上我不知道是否可以通过简单地除以RAND_MAX+1来解决这个问题,但是here是一个非常好地戏剧化的视频,并解释了rand()的问题。

答案 3 :(得分:-1)

如果您怀疑随机数生成器存在偏差,可以通过大量运行并生成频率分布来检查它。

尝试使用不同的种子,看看偏见是否成立。

如果它确实存在稳定偏差,请记录分布并使用它来克服偏差。