随机数生成器比高数更频繁地生成低数 C++
Random number generator generating low numbers more frequently than high numbers C++
所以,我制作了一个模拟事物的程序,在其中我注意到 c++ 函数 运行d() 似乎过于频繁地生成低数字,所以我尝试对其进行测试。
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <vector>
#include <cstdlib>
#include <time.h>
#include <cfloat>
#include <iomanip>
using namespace std;
int main(){
srand(time(NULL));
int qwerty=0;
for(int i=0; i<10000000;i++){
if(rand()%10000<2800){
qwerty++;
}
}
cout << qwerty << endl;
return 0;
}
如果我 运行 文件中有这个“for tester”,我会得到一个接近 3400000 或 34% 的数字,这接近我在真实程序中看到的 34% ,问题是输出应该接近 2800000 或 28%。
然后我尝试 运行 在一个新项目(我在这里写的一样)上 运行 这个“测试人员”,其中只有库和 s运行d(time(NULL))现在,相同的输出。
然后我尝试将此文件复制到在线编译器中,这次我得到的不是 3400000,而是正确的数字 2800000。
我找不到为什么会这样,有人知道吗?
附加信息:
我将 dev-c++ 作为 IDE 与 TDM-GCC 4.9.2 64 位版本和 ISO C++11 一起使用,如果我将我的计算机生成的可执行文件和 运行 它放在另一台计算机中我得到相同的 34% 结果,Windows 10 是操作系统。如果我使用不同的数字,也会出现此问题。
这是 %
的一个众所周知的问题,并且在极少数情况下不是 rand
的错。
为了示例考虑 RAND_MAX == 2
。进一步假设 rand()
是完全均匀的。然后你得到数字 0
、1
和 2
。现在看看这个:
int x = rand() % 2;
如果兰特的分配是
rand() P
0 1/3 33.33333 %
1 1/3 33.33333 %
2 1/3 33.33333 %
那么x
的结果分布是:
x P
0 2/3 66.66666 %
1 1/3 33.33333 %
解决方案:使用<random>
中提供的工具。
对于开区间[0, 32767]内均匀分布的随机变量E
mod(E, 10000) < 2800 的概率约为 34%。直觉上,您可以将 mod(E, 10000) < 2800 视为支持 [30000, 32767] 范围内的数字桶:桶 modulo 10000 总是小于 2800。所以有将结果推到 28% 以上的效果。
这就是您在这里观察到的行为。
它不是随机生成器质量的函数,但如果您使用具有更大周期性的均匀生成器,您会得到更好的结果。从 C++ 标准库中使用 rand()
是 ill-advised,因为该标准对功能要求过于宽松,无法移植。来自 C++11 的 <random>
会给你带来的麻烦要少得多:你也可以避免显式 %
。
所以,我制作了一个模拟事物的程序,在其中我注意到 c++ 函数 运行d() 似乎过于频繁地生成低数字,所以我尝试对其进行测试。
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <vector>
#include <cstdlib>
#include <time.h>
#include <cfloat>
#include <iomanip>
using namespace std;
int main(){
srand(time(NULL));
int qwerty=0;
for(int i=0; i<10000000;i++){
if(rand()%10000<2800){
qwerty++;
}
}
cout << qwerty << endl;
return 0;
}
如果我 运行 文件中有这个“for tester”,我会得到一个接近 3400000 或 34% 的数字,这接近我在真实程序中看到的 34% ,问题是输出应该接近 2800000 或 28%。
然后我尝试 运行 在一个新项目(我在这里写的一样)上 运行 这个“测试人员”,其中只有库和 s运行d(time(NULL))现在,相同的输出。
然后我尝试将此文件复制到在线编译器中,这次我得到的不是 3400000,而是正确的数字 2800000。
我找不到为什么会这样,有人知道吗?
附加信息: 我将 dev-c++ 作为 IDE 与 TDM-GCC 4.9.2 64 位版本和 ISO C++11 一起使用,如果我将我的计算机生成的可执行文件和 运行 它放在另一台计算机中我得到相同的 34% 结果,Windows 10 是操作系统。如果我使用不同的数字,也会出现此问题。
这是 %
的一个众所周知的问题,并且在极少数情况下不是 rand
的错。
为了示例考虑 RAND_MAX == 2
。进一步假设 rand()
是完全均匀的。然后你得到数字 0
、1
和 2
。现在看看这个:
int x = rand() % 2;
如果兰特的分配是
rand() P
0 1/3 33.33333 %
1 1/3 33.33333 %
2 1/3 33.33333 %
那么x
的结果分布是:
x P
0 2/3 66.66666 %
1 1/3 33.33333 %
解决方案:使用<random>
中提供的工具。
对于开区间[0, 32767]内均匀分布的随机变量E mod(E, 10000) < 2800 的概率约为 34%。直觉上,您可以将 mod(E, 10000) < 2800 视为支持 [30000, 32767] 范围内的数字桶:桶 modulo 10000 总是小于 2800。所以有将结果推到 28% 以上的效果。
这就是您在这里观察到的行为。
它不是随机生成器质量的函数,但如果您使用具有更大周期性的均匀生成器,您会得到更好的结果。从 C++ 标准库中使用 rand()
是 ill-advised,因为该标准对功能要求过于宽松,无法移植。来自 C++11 的 <random>
会给你带来的麻烦要少得多:你也可以避免显式 %
。