我的构造函数有什么问题?每当我调用一个应该生成随机数的函数(大约每五秒一次)时,它就会生成相同的数字。每个调用都会在下面实例化其中一个对象。我以为我随机播放了m_gen
m_rd
operator()
m_rd()
的输出。{/ p>
我可以将Shuffler(std::random device& rd)
的结果传递给构造函数吗?签名是什么? #include <random>
class Shuffler
{
private:
std::random_device m_rd;
std::mt19937 m_gen;
public:
//! The default constructor.
Shuffler();
};
?但那对用户来说会更难。
实际上,如果可能的话,我更喜欢一个解决方案,你不需要将任何东西传递给构造函数。
shuffler.h
#include "shuffler.h"
Shuffler::Shuffler() : m_gen(m_rd())
{
}
shuffler.cpp
"bundles": {
"dist/app-build": {
"includes": [
"[**/*.js]",
"**/*.html!text",
"**/*.css!text"
],
"options": {
"sourceMaps": 'inline'
"inject": true,
"minify": true,
"depCache": true,
"rev": true
}
},
答案 0 :(得分:3)
std::random_device
通常适用于此类事情,但它可能不适用于所有平台。而大多数平台&#39;标准库根据一些底层OS随机功能(即Linux上的/ dev / urandom或Windows上的CryptGenRandom
)实现它,C ++标准不要求这样做。在某些平台上,高质量的随机生成器可能无法使用,标准允许std::random_device
成为简单的静态种子PRNG。如果是,则每个std::random_device
对象将生成相同的数字序列。
出于这些原因,你可能想回到简单的时间播种。标准
提供std::chrono::high_resolution_clock
:
class Shuffler
{
private:
std::mt19937 m_gen;
public:
Shuffler()
: m_gen{static_cast<std::uint32_t>(
std::chrono::high_resolution_clock::now().time_since_epoch().count()
)}
{}
};
std::chrono::high_resolution_clock
通常具有纳秒或数百纳秒的分辨率。这足够高,通过调用high_resolution_clock
播种的两个PRNG不太可能最终使用相同的种子。但这也不能保证。例如,std::chrono::high_resolution_clock
在macOS上只有微秒级的分辨率,这可能会或可能不足以满足您的需要。
最后,这两种方法都不完美。您可能希望使用std::seed_seq
组合两者:
std::seed_seq make_seeds() {
thread_local std::random_device rd;
return {{
static_cast<std::uint32_t>(std::chrono::high_resolution_clock::now().time_since_epoch().count()),
rd()
}};
}
// Cast away rvalue-ness because the standard random generators need
// an lvalue reference to their seed_seq for some strange reason
template <typename T>
T& identity(T&& t) { return t; }
class Shuffler
{
private:
std::mt19937 m_gen;
public:
Shuffler()
: m_gen{identity(make_seeds())}
{}
};
答案 1 :(得分:0)
与此example一样,你必须播种它,random_device似乎没有做到这一点 * :
// do this once somewhere
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
class Shuffler
{
private:
std::mt19937 m_gen;
public:
Shuffler() : m_gen(seed) {}
};
*如上所述here,random_device
不是种子序列!