我有以下试图生成的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次。
如何改进上面的代码?
答案 0 :(得分:3)
换句话说,您正在检查结果== 3,而不是结果是&lt; = 3。
3只会发生,一次1000次,但&lt; = 3将以你想要的速度发生。
答案 1 :(得分:2)
答案 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;
}