2009-03-05 67 views
0

我有以下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运行生成号码“3”多达〜3000倍。但 一些如何我的代码以上我的代码上面只生成多达900〜1000倍的数字“3”。

我该如何改进上面的代码?

回答

3

换句话说,您所检查的结果== 3,不在于结果是< = 3

3才会发生,一个在1000倍,但< = 3的速度会发生你要。

+0

你说得对。我没有实现他的+1。 – 2009-03-05 17:29:29

1

我觉得这里你的数学是取下一小...

根据你那里的代码,你会被均匀地1和1000之间

你的检查(toSub =生成随机数=(SubsRate * 1000))仅检查您生成的数字是否为3(因为速率* 1000 = 3)。因此,你只能得到3次约1000次,而不是3000次。

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

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

在这种情况下,如果你想每一个数目,以后每3000次出现一次,你将不得不随机1和3000之间的数字,否则,你是不是在谈论一个均匀分布。

+0

如前所述在另一个问题的答案http://stackoverflow.com/questions/614012/howto-restart-loop-in-c-finding-unique-sequence-over-random-runs/614029#614029它不是很好使用上述公式得到均匀分布。 – Paul 2009-03-05 09:39:48

2
  • 您将期望获得1000中的第3次1000次,即1M中的1000次。
  • 您预计在1000次中有一次获得9次数,即1M中的1000次。
  • 您预计在1000次中有一次是第7次,即1M中的1000次。
  • 您预计在1000次中有3次,7次或9次中的任意一次,即1M中的3000次。
1

正如其他人所提到的,您的原始内容是测试随机数是否等于您想要的分布的分数,而不是低于这个分数。

rand()生成介于0和RAND_MAX(含)之间的值。 RAND_MAX可能非常小 - 一个典型的值是32767.如果使用模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; 
}