C++ 重新生成相同随机数的均匀实分布
在运行下面的代码时,C++ 重新生成相同随机数的均匀实分布,c++,c++11,random,uniform-distribution,C++,C++11,Random,Uniform Distribution,在运行下面的代码时,arr的前半部分等于后半部分。为什么?我甚至尝试了各种种子,例如std::chrono::system\u clock::now().time\u since\u epoch().count()。谢谢 #include <algorithm> #include <iostream> #include <random> template<typename DistributionType> class Rng { publi
arr
的前半部分等于后半部分。为什么?我甚至尝试了各种种子,例如std::chrono::system\u clock::now().time\u since\u 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";
}
#包括
#包括
#包括
模板
类Rng
{
公众:
模板
Rng(Args&&…Args):dist(Args…{}
typename DistributionType::结果类型运算符()
{
返回距离(gen);
}
私人:
std::默认随机引擎生成;
分布型分布;
};
类UniformRealRng:公共Rng
{
公众:
UniformRealRng(常数双a,常数双b):Rng(a,b){}
};
int main()
{
constexpr int sz=6;
constexpr int k=sz/2;
双arr[sz];
统一平均收益率(0.0,1.0);
std::generate(arr,arr+k,rng);
标准::生成(arr+k、arr+sz、rng);
对于(int i=0;i std::coutstd::generate
按值获取其第三个参数,因此正在复制rng
为了安全起见,可以删除复制:
Rng(Rng&) = delete;
Rng& operator=(Rng&) = delete;
你的答案事实上是正确的,但不能解决问题。
它只会在错误地复制随机数生成器时产生编译错误
事实证明,通过使用std::reference_包装器
库特性,可以使代码在语义上正确
std::generate(arr, arr + k, std::ref(rng));
std::generate(arr + k, arr + sz, std::ref(rng));
这样,您基本上是在强制通过引用传递参数。
幸运的是,引用包装器重载了操作符()
,因此无需任何额外代码即可用于生成器
完整代码:
#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";
}
#包括
#包括
#包括
#包括//ref
模板
类Rng
{
公众:
模板
Rng(Args&&…Args):dist(Args…{}
//Rng(Rng&)=delete;//这不需要它工作
//Rng&operator=(Rng&)=delete;//您可能需要复制生成器
typename DistributionType::结果类型运算符()
{
返回距离(gen);
}
私人:
std::默认随机引擎生成;
分布型分布;
};
类UniformRealRng:公共Rng
{
公众:
UniformRealRng(常数双a,常数双b):Rng(a,b){}
};
int main()
{
constexpr int sz=6;
constexpr int k=sz/2;
双arr[sz];
统一平均收益率(0.0,1.0);
std::generate(arr,arr+k,std::ref(rng));
std::generate(arr+k,arr+sz,std::ref(rng));
对于(int i=0;i