C ++ 11:如何使用< random>设置种子 [英] C++11: How to set seed using <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.
我的平台:
- Windows 7: TDM-GCC编译器
推荐答案
具有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
来解决此问题,方法是请求
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:如何使用< random>设置种子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!