我尝试了这个简单的代码,它“随机”生成1或-1百万次并总结它们:
#include<iostream>
#include<stdlib.h>
#include<time.h>
int pos_or_neg()
{
if (rand()%2==1) return 1;
else return -1;
}
int main()
{
int i,s=0;
srand (time(NULL));
for (i=0;i<1000000;i++)
s+=pos_or_neg();
std::cout << s;
}
如果rand()实例是独立的,那么结果应该正常分布,标准偏差为1000,但我得到的结果最多为数百。如果我产生更多的数字 - 例如1亿 - 那么这就更加引人注目,甚至的数量也会减少!
rand()真的那么糟糕还是我做错了什么?在第一种情况下,有哪些好的选择?
答案 0 :(得分:3)
rand()
通常用线性同余生成器实现,并且线性同余生成器在其低位中是众所周知的非随机的。所以要么使用不同的发电机,要么选择其他一些;例如,rand() & 0x10
。
答案 1 :(得分:2)
使用以下代码,我获得了大约1000的标准差。
#include <random>
#include <iostream>
constexpr int N = 1000000;
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(0, 1);
int frequencyOfOnes = 0;
for (int n=0; n<N; ++n)
frequencyOfOnes += dis(gen);
std::cout << "Out of " << N << " events, " << frequencyOfOnes << " had 1 as a result " << std::endl;
}
正如@ zett42所指出的,关于这个话题已经有了一个问题。 您可以去那里了解有关该主题的更多信息。
Generate random numbers using C++11 random library
你一定要查看这个话题,以便了解为什么使用rand with modulo可能不是一个好主意。
https://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful
因此,如果您想要统一分发,我强烈建议您使用 http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution
答案 2 :(得分:0)
要考虑的一件事是,在rand()
上使用mod
假设RAND_MAX+1
可以被你的mod函数整除。如果不是,你将至少有一个不平衡,因为你不会选择“偶数”你选择“奇数”的次数相同。
如果您只想尝试提供随机值的“硬币翻转”,请改用bernoulli_distribution
。