背景
我正在构建一个离散的选择器,例如给定一个序列,它根据给定的权重随机选择一个具有概率的元素。您可以将其视为一对 PredefinedRandomGenerator
和 std::discrete_distribution
。我希望选择器是便携的,并提供合理的熵。它将不会用于密码上下文,我只是想要更好的随机性(抱歉,如果我搞砸了这里的术语)。
问题
Windows 上的 MinGW 上的std:random_device
总是产生相同的数字。作为解决方法,我使用
//assume using namespace std::chrono
std::seed_seq seq{std::random_device{}(),
duration_cast<nanoseconds>(system_clock::now().time_since_epoch()).count(),
42};
问题是 PredefinedRandomGenerator
的构造函数需要左值引用,所以我无法在成员初始化列表中初始化它,如下所示:
template <typename InputIterator>
discrete_selector(InputIterator weights_first,
InputIterator weights_last):
generator(std::seed_seq{/*...*/}),
distribution(weights_first, weights_last)
{}
所以现在至少有一个或多或少的随机数来源。
我尝试了什么
//somewhere in namespace details
std::seed_seq& get_new_sequence()
{
static std::unique_ptr<std::seed_seq> sequence;
sequence = std::make_unique<std::seed_seq>(std::random_device{}(),
duration_cast<nanoseconds>(system_clock::now().time_since_epoch()).count(),
42);
return *sequence;
}
以上应该可行,但我相信应该有更好的方法来做到这一点。
附带问题
为什么构造函数通过左值引用获取 std::seed_seq
?它至少可以使用右值引用。
最佳答案
我通常做的是使用 lambda。
generator([]() -> auto& {
static std::seed_seq seq(std::random_device()(),
duration_cast<nanoseconds>(system_clock::now().time_since_epoch()).count(),
42);
return seq;
}())
如果您愿意,您始终可以像以前那样将 lambda 放在另一个私有(private)函数中,这对于所有意图和目的来说也很好。
或者,像 tree with eyes说,你可以在构造函数中初始化种子。 :)
关于c++ - 如何在构造函数中构造预定义的随机数生成器和种子序列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48008489/