![](/img/trans.png)
[英]is boost::random::uniform_real_distribution supposed to be the same across processors?
[英]std::uniform_real_distribution regenerating same random number
在运行下面的代码时, arr
的前一半等于后一半。 为什么? 我什至尝试了各种种子,例如std::chrono::system_clock::now().time_since_epoch().count()
。 谢谢。
#include <algorithm>
#include <iostream>
#include <random>
template<typename DistributionType>
class Rng
{
public:
template<typename ...Args>
Rng(Args&&... args) : dist(args...) { }
typename DistributionType::result_type operator()()
{
return dist(gen);
}
private:
std::default_random_engine gen;
DistributionType dist;
};
class UniformRealRng : public Rng<std::uniform_real_distribution<double>>
{
public:
UniformRealRng(const double a, const double b) : Rng(a, b) { }
};
int main()
{
constexpr int sz = 6;
constexpr int k = sz / 2;
double arr[sz];
UniformRealRng rng(0.0, 1.0);
std::generate(arr, arr + k, rng);
std::generate(arr + k, arr + sz, rng);
for (int i = 0; i < sz; ++i)
{
std::cout << arr[i];
}
std::cout << "\n";
}
std::generate
通过值采用其第三个参数,因此已复制了rng
。
为了安全起见,可以删除以下副本:
Rng(Rng&) = delete;
Rng& operator=(Rng&) = delete;
您的回答实际上是正确的,但不能解决问题。 仅当错误地(?)尝试复制随机数生成器时,它才会产生编译错误。
事实证明,使用std::reference_wrapper
库功能可以使代码在语义上正确。
std::generate(arr, arr + k, std::ref(rng));
std::generate(arr + k, arr + sz, std::ref(rng));
这样,您基本上是在强制通过引用传递参数。 幸运的是 ,引用包装器使operator()
重载,因此可以用于生成器,而无需任何其他代码。
完整的代码:
#include <algorithm>
#include <iostream>
#include <random>
#include <functional> //ref
template<typename DistributionType>
class Rng
{
public:
template<typename ...Args>
Rng(Args&&... args) : dist(args...) { }
// Rng(Rng&) = delete; // this is not needed for it to work
// Rng& operator=(Rng&) = delete; // you MAY want to copy the generator
typename DistributionType::result_type operator()()
{
return dist(gen);
}
private:
std::default_random_engine gen;
DistributionType dist;
};
class UniformRealRng : public Rng<std::uniform_real_distribution<double>>
{
public:
UniformRealRng(const double a, const double b) : Rng(a, b) { }
};
int main()
{
constexpr int sz = 6;
constexpr int k = sz / 2;
double arr[sz];
UniformRealRng rng(0.0, 1.0);
std::generate(arr, arr + k, std::ref(rng));
std::generate(arr + k, arr + sz, std::ref(rng));
for (int i = 0; i < sz; ++i)
{
std::cout << arr[i];
}
std::cout << "\n";
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.