在C ++中使用rand()函数的替代方法

时间:2017-06-18 13:52:11

标签: c++

我尝试了这个简单的代码,它“随机”生成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()真的那么糟糕还是我做错了什么?在第一种情况下,有哪些好的选择?

3 个答案:

答案 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