我正试图理解C++11中的随机数生成功能应该如何使用。我的关注点是性能。
假设我们需要生成一系列介于0..k
之间的随机整数,但k
在每一步都会发生变化。最佳操作方式是什么?
例如:
for (int i=0; i < n; ++i) {
int k = i; // of course this is more complicated in practice
std::uniform_int_distribution<> dist(0, k);
int random_number = dist(engine);
// do something with random number
}
std::vector
to explicitly construct the distribution myself. While this is more verbose, it gives me complete control and insight into the underlying implementation.
std::uniform_real_distribution<> dist(0.0, 1.0);
for (int i=0; i < n; ++i) {
int k = i; // of course this is more complicated in practice
int random_number = std::floor( (k+1)*dist(engine) );
// do something with random number
}
避免在每次迭代中构造新对象的方法。随机数经常用于重要性能的数字模拟中。在这些情况下,使用 <random>
的最佳方法是什么?请不要回答“分析它”。分析是有效优化的一部分,但了解库的使用方式和该库的性能特征也同样重要。如果答案是依赖于标准库的实现,或者唯一知道的方法是分析它,那么我宁愿根本不使用
<random>
中的分布。相反,我可以使用自己的实现,这对我来说更加透明,并且在必要时更容易进行优化。
std::mt19937
这样的生成器非常方便,它们是可移植的,并且其实现是标准规定的。在任何符合规范的实现中,使用给定种子的生成器必须产生相同的uint32_t
随机序列。然而,分布适配器std::uniform_int_distribution
没有这个保证,所以如果你使用它们,在改变编译器或其他因素的情况下,可能会得到不同的整数序列。这对于数值模拟可能是一个需要考虑的因素。 - Chris Beck