每次运行都获得相同的随机数集(同时使用int和实数均匀分布)

时间:2019-05-16 11:29:51

标签: c++ c++11 random

每次运行都会生成相同的数字集。我不确定为什么会这样。还有什么其他方法可以使用随机库来生成随机数,以防止出现此错误?还是我的编译器或程序有问题?

是否需要将std :: default_random_engine声明为静态?因为当不将其声明为静态时,您将在每次迭代中获得相同的数字。 其背后的原因是什么?

#include <iostream>
#include <random>

float get_random() {
    static std::default_random_engine random;
    std::uniform_real_distribution<> distribution{0, 1};

    return distribution(random);
}

int main() {
    for (size_t i = 0; i < 10; i++) {
        std::cout<<get_random()<<std::endl;
    }

    return 0;
}

2 个答案:

答案 0 :(得分:0)

std::default_random_engine是一个伪随机数生成器,PRNG只是算法,其输出类似于随机数,但并不是真正的随机数。他们在某些内部状态上执行确定的操作,并根据该状态输出下一个数字,从而给出可预测的顺序。如果您希望在每次使用PRNG的运行中使用不同的序列,则需要以不同的方式“播种”(即使用不同的值初始化内部状态)。

或者,您可以改用真实的随机数生成器,如果实现,则在C ++中由std::random_device给出。如果为std::random_device::entropy() > 0,则可以使用它代替std::default_random_engine以获得不确定的结果。

如果不确定,它也可以用来植入PRNG:

#include <chrono>

uint32_t generate_seed() {
    // The most portable way to generate non-deterministic number
    // is via std::random_device, provided entropy is > 0.
    {
        std::random_device rd;
        if(rd.entropy() > 0.0) {
            return rd();
        }
    }

    // Random device is deterministic, you need some other
    // platform specific entropy source.
    // Good alternatives are:
    //  - /dev/urandom, on Linux;
    //  - BCryptGenRandom() function, on Windows;
    //  - RDRAND or RDSEED instruction, on
    //    recent enough Intel processors.
    // Bad alternatives are:
    //  - time() function, which is predictable if
    //    you know when the program was executed,
    //    and is repeatead if you run the program
    //    more than once per second.
    //  - std::chrono::high_resolution_clock::now(), which
    //    is a little better than time() because it
    //    changes faster, thus is less likely to be repeated.
    return std::chrono::high_resolution_clock::now()
        .time_since_epoch().count();
}

float get_random() {
    static std::default_random_engine random{generate_seed()};
    std::uniform_real_distribution<> distribution{0, 1};

    return distribution(random);
}

答案 1 :(得分:0)

取六张纸,并在上面写下数字1-6。把它们放在一个袋子里,混合在一起。现在,将它们从书包中倒出,然后在桌子上随机散布。

第一个怎么说?也许3!一个不错的随机结果!很棒。

第二个人怎么说?也许5!太棒了,似乎还很随意。

第三个人怎么说?也许2!亲爱的。


现在,如果您只想要三个随机数,那么您就完成了。

下次您要三个随机数时,您会怎么做?

您:

  1. 再次查看书桌上的前三张纸,或者
  2. 将纸片放回包中,然后重新洗吗?

第二个,当然!否则,您将得到相同的结果。


PRNG是确定性的。它们并不是真正随机的。他们只是按顺序给您提供了预定的序列。序列本身看起来像随机性,但是对于给定的种子,构建生成器时系统已经做出了实际的序列选择。

因此,当您构造另一个具有相同种子(或没有种子,因此使用默认值)的生成器时,您将再次获得相同的三张纸

使用PRNG的方法是构造一个 one 生成器,然后不断向其询问序列中的下一个“随机”数字。这就是为什么要创建该对象static:使其实例化一次,然后在该函数的后续调用中重新使用它的原因。