C++快速随机数生成器

Cha*_*oon 2 c++

我很抱歉,如果这是怎样的一个愚蠢的问题,但我是新来的C++和真的不能找到答案;

当我使用时rand(),我当然必须首先使用srand().

起初我只是导入<ctime>和做srand(time()),这有效.但如果我rand()不止一次打电话- 经常time()发生变化 - 那么我会得到同样的答案.所以例如;

#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;

int main()
{
    bool x = true;
    while(x == true)
    {
        int num = 1;
        srand(time(NULL));
        num = rand();
        cout<<num%10<<endl;
    }

}
Run Code Online (Sandbox Code Playgroud)

可能会产生类似的东西,如6666666666777777777700000000003333333333

哪个对我的目的没有好处 - 我更喜欢像163509284749301935766这样的东西.

shu*_*e87 7

您应该只为随机数生成器播种一次.现在你正在循环中播种它并且time(NULL)只是意味着种子每秒更改一次,这会给你所描述的糟糕输出.

请改为:

int main()
{
    bool x = true;
    int num = 1;
    srand(time(NULL));
    while(x == true)
    {
        num = rand();
        cout<<num%10<<endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果你真的关心产生的随机数,你可能想要使用其他东西rand().原因是rand()伪随机数生成的统计特性较差,它通常被实现为线性同余生成器.如果您需要高质量的随机性,那么您应该更喜欢其他内容,例如新的c ++随机数生成器http://en.cppreference.com/w/cpp/numeric/random.实际上甚至有一篇关于贬值旧的报告rand(),试图推动人们使用更新的c ++标准库随机函数.

在这种特殊情况下,你采用一个模数会导致一些微妙的问题:

num = rand();
cout<<num%10<<endl;
Run Code Online (Sandbox Code Playgroud)

即使rand()是完美的,如果这里的模数不返回的最大值的约数rand(),你会得到一个非均匀分布的结果.这是一个快速解释,比如说rand()[0,25]范围内的返回值,然后取模数将执行以下操作.

before    after modulus 
[0-9]         [0-9]
[10-19]       [0-9]
[20-25]       [0-5]
Run Code Online (Sandbox Code Playgroud)

你会发现你更有可能得到[0-5]而不是[6-9],这意味着你现在不再生成统一的数字了.请注意,这个小范围仅用于教育目的,rand()标准规定的最大值至少为32767.但是它说明了一个重点,最大生成数越大越好.

除了模数之外,这种分布问题的均匀性具有特别隐蔽的效果,即使对于某些实施方式甚至进一步降低伪随机性的质量.

使用std::uniform_int_distribution避免了许多问题,因此我建议您更改现有代码以使用新库.这样做会是这样的:

#include <iostream>
#include <random>
using namespace std;

int main()
{
    std::default_random_engine generator;
    generator.seed( /* your seed for the RNG goes here */ );
    std::uniform_int_distribution<int> distribution(0,9);//note the min and max parameters are inclusive here
    while(true)
    {
        cout << distribution(generator) << endl;
    }

}
Run Code Online (Sandbox Code Playgroud)