用一定的速率生成随机数

时间:2009-03-05 02:06:07

标签: c++ algorithm random

我有以下试图生成的C ++代码 一个随机数。 idea我们给出了一些速率“x”和运行次数; 我们希望它能产生多达(x *运行次数)的数字。

#include <iostream>      
#include <vector>
#include <fstream>
#include <sstream>       
#include <time.h>        
using namespace std;     


int main  () {

    // Initialize Random Seed 
    srand (time(NULL));

    string line;
    double SubsRate = 0.003;  
    double nofRuns   = 1000000;

    for (unsigned i=0; i < nofRuns ; i++) {

        int toSub = rand() % 1000 + 1;

        if (toSub == (SubsRate * 1000)) {
         cout << toSub << " Sub"  << endl; 
        }

    }
    return 0;
}

因此,如果我们使用以下命令运行K次代码:

$ a=0 ; while test $a -lt 10 ; do ./MyCode | wc -l ; a=`expr $a + 1` ; done

我们预计它会在1M次运行中产生多达~3000次的数字“3”。但 一些我上面的代码上面的代码只生成数字“3”多达900~1000次。

如何改进上面的代码?

4 个答案:

答案 0 :(得分:3)

换句话说,您正在检查结果== 3,而不是结果是&lt; = 3。

3只会发生,一次1000次,但&lt; = 3将以你想要的速度发生。

答案 1 :(得分:2)

  • 您希望1000次中获得3次,即1M次中的1000次。
  • 您希望1000次中获得第9次,即1M次中的1000次。
  • 您希望1000次中获得7次,即1M次中的1000次。
  • 您可能希望在1000次中获得3次,7次或9次中的任何一次,即1M次中的3000次。

答案 2 :(得分:1)

我认为你的数学有点偏离...

根据你在那里的代码,你将统一生成1到1000之间的随机数。

您的支票(toSub ==(SubsRate * 1000))仅检查您生成的数字是否为3(因为费率* 1000 = 3)。因此,你只会获得3次约1000次,而不是3000次。

您没有提到数字的范围是什么,但一般来说,如果您想使用统一分布生成IMIN和IMAX之间范围内的数字(每个值都有相同的出现机会),那么你只需写:

int I = IMin + rand() % (IMax - IMin);

在这种情况下,如果您希望每个数字每3000次显示一次,则必须随机化1到3000之间的数字。否则,您不是在谈论统一分布。

答案 3 :(得分:1)

正如其他人所提到的那样,您的原始版本正在测试随机数是否等于您想要的分布的分数,而不是低于该分布。

rand()生成0到RAND_MAX(含)之间的值。 RAND_MAX可能非常小 - 典型值为32767.如果使用modulo 1000,那么有32个值rand()返回哪个值映射到768到999中的每个值,33个值映射到值0到767.所以这有点偏斜。

你好像已经把1000拉出来了。相反,如果您按照所需分布的比例缩放RAND_MAX本身,那么您不会得到偏斜效果,也不必处理rand()的输出来进行比较:

int main  () {
    srand (time(NULL));

    double subsRate = 0.003;  

    unsigned int nofRuns   = 1000000;

    int cutoff = (int) ( subsRate * ( (long) RAND_MAX + 1L ) );

    for (unsigned int i = 0; i < nofRuns ; i++) 
        if ( rand() < cutoff ) 
            cout << " Sub "  << endl; 

    return 0;
}