C++11:如何使用 <random> 设置种子 [英] C++11: How to set seed using <random>

查看:20
本文介绍了C++11:如何使用 <random> 设置种子的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在练习随机库,这是 C++11 的新手.我编写了以下最小程序:

I am exercising the random library, new to C++11. I wrote the following minimal program:

#include <iostream>
#include <random>
using namespace std;
int main() {
    default_random_engine eng;
    uniform_real_distribution<double> urd(0, 1);
    cout << "Uniform [0, 1): " << urd(eng);
}

当我重复运行它时,它每次都给出相同的输出:

When I run this repeatedly it gives the same output each time:

>a
Uniform [0, 1): 0.131538
>a
Uniform [0, 1): 0.131538
>a
Uniform [0, 1): 0.131538

我想让程序在每次调用时设置不同的种子,以便每次生成不同的随机数.我知道 random 提供了一个名为 seed_seq 的工具,但我发现它的解释(在 cplusplus.com 上)完全模糊:

I would like to have the program set the seed differently each time it is called, so that a different random number is generated each time. I am aware that random provides a facility called seed_seq, but I find the explanation of it (at cplusplus.com) totally obscure:

http://www.cplusplus.com/reference/random/seed_seq/

关于如何让程序在每次调用时生成新种子的建议:越简单越好.

I'd appreciate advice on how to have a program generate a new seed each time it is called: The simpler the better.

我的平台:

推荐答案

拥有 seed_seq 的目的是增加生成序列的熵.如果您的系统上有一个 random_device ,那么使用来自该随机设备的多个数字进行初始化可能会做到这一点.在具有伪随机数生成器的系统上,我认为随机性不会增加,即生成的序列熵.

The point of having a seed_seq is to increase the entropy of the generated sequence. If you have a random_device on your system, initializing with multiple numbers from that random device may arguably do that. On a system that has a pseudo-random number generator I don't think there is an increase in randomness, i.e. generated sequence entropy.

以您的方法为基础:

如果您的系统确实提供了随机设备,那么您可以像这样使用它:

If your system does provide a random device then you can use it like this:

  std::random_device r;
  // std::seed_seq ssq{r()};
  // and then passing it to the engine does the same
  default_random_engine eng{r()};
  uniform_real_distribution<double> urd(0, 1);
  cout << "Uniform [0, 1): " << urd(eng);

如果您的系统没有随机设备,那么您可以使用 time(0) 作为 random_engine 的种子

If your system does not have a random device then you can use time(0) as a seed to the random_engine

  default_random_engine eng{static_cast<long unsigned int>(time(0))};
  uniform_real_distribution<double> urd(0, 1);
  cout << "Uniform [0, 1): " << urd(eng);

如果您有多个随机源,您实际上可以这样做(例如 2)

If you have multiple sources of randomness you can actually do this (e.g. 2)

std::seed_seq seed{ r1(), r2() };
  default_random_engine eng{seed};
  uniform_real_distribution<double> urd(0, 1);
  cout << "Uniform [0, 1): " << urd(eng);

其中 r1 , r2 是不同的随机设备,例如热噪声量子源.

where r1 , r2 are different random devices , e.g. a thermal noise or quantum source .

当然可以混搭

std::seed_seq seed{ r1(), static_cast<long unsigned int>(time(0)) };
  default_random_engine eng{seed};
  uniform_real_distribution<double> urd(0, 1);
  cout << "Uniform [0, 1): " << urd(eng);

最后,我喜欢用单行初始化:

Finally, I like to initialize with an one liner:

  auto rand = std::bind(std::uniform_real_distribution<double>{0,1},
              std::default_random_engine{std::random_device()()});
  std::cout << "Uniform [0,1): " << rand();

<小时>

如果您担心 time(0) 具有第二个精度,您可以通过使用 high_resolution_clock 来克服这个问题,或者通过请求从第一个指定的纪元开始的时间 下面的bames23:


If you worry about the time(0) having second precision you can overcome this by playing with the high_resolution_clock either by requesting the time since epoch as designated firstly by bames23 below:

static_cast<long unsigned int>(std::chrono::high_resolution_clock::now().time_since_epoch().count()) 

或者可能只是玩 CPU 随机性

or maybe just play with CPU randomness

long unsigned int getseed(int const K)
{

    typedef std::chrono::high_resolution_clock hiclock;

    auto gett= [](std::chrono::time_point<hiclock> t0)
    {
        auto tn = hiclock::now();
        return static_cast<long unsigned int>(std::chrono::duration_cast<std::chrono::microseconds>(tn-t0).count());
    };

    long unsigned int diffs[10];
    diffs[0] = gett(hiclock::now());
    for(int i=1; i!=10; i++)
    {
        auto last = hiclock::now();
        for(int k=K; k!=0; k--)
        {
            diffs[i]= gett(last);
        }
    }

    return *std::max_element(&diffs[1],&diffs[9]);
}

这篇关于C++11:如何使用 &lt;random&gt; 设置种子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆