我需要生成在两个区间[a,b]之间均匀分布的X个随机双数,其中a和b也是双数.
那些X数字需要在类函数中生成,比如myclass :: doSomething(a,b).事实上,每次doSomething(a,b)函数被另一个类函数调用时,传递给doSomething(a,b)函数的区间[a,b]就会改变,比如doThat().
我想要一个允许我的解决方案:
1.拥有更高范围的发动机,理想情况下,每次应用程序只应播种一次.
2.每次调用doSomething()函数内部生成的X随机双数应均匀分布.
我的解决方案不允许更高的引擎范围,似乎生成的数字不一定均匀分布.
//file: utilities.h
template <typename Generator>
double randomDoubleEngine(Generator& engine, double low_bound, double high_bound )
{
if (low_bound > high_bound){
std::swap(low_bound, high_bound);
}
return std::uniform_real_distribution<>( low_bound, high_bound )( engine );
}
//file: myclass.h
void myclass::doThat(param1, param2){
for(int i=0; i < myclass.iter; i++){
...
...
doSomething(a,b);
...
}
}
void myclass::doSomething(double a, double b)
{
std::random_device rd;
static std::mt19937 engine(rd());
.....
double curThreshold = randomDoubleEngine(engine, a, b);
...
}
最佳答案 我想你希望引擎成为myclass的静态成员.除非你需要在其他方法中使用引擎,否则我不确定它会与你的产品产生任何真正的不同.我在下面粘贴了一个可能的解决方案.
另请注意,与标准相比,gcc看起来有些错误(请参阅代码注释中的链接),因此,如果您使用它,它可能会解释为什么您应用于这些数字的任何测试(检查均匀分布)都会失败.据我所知,gcc希望引擎返回[0,1]中的数字,而标准表示它应该是某个范围内的统一整数.
我担心我只能用gcc 4.4来测试它,因为我正在运行一个较旧的Ubuntu版本,而且ideone似乎不允许使用std :: random_device.
#include <random>
#include <iostream>
/* In GCC 4.4, uniform_real_distribution is called uniform_real; renamed in 4.5
*
* However, GCC's description here
*
* http://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-api-4.6/a00731.html
*
* doesn't match expectation here
*
* http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution
*
* which seems to match 26.5.8.2.2 of N3337
*
*/
#if defined(__GNUC_MINOR__) && (__GNUC_MINOR__ <= 4)
# define uniform_real_distribution uniform_real
#endif
template <typename Generator>
double randomDoubleEngine(Generator& engine, double low_bound, double high_bound)
{
if (low_bound > high_bound){
std::swap(low_bound, high_bound);
}
return std::uniform_real_distribution<double>(low_bound, high_bound)(engine);
}
class myclass
{
double curThreshold;
static std::mt19937 engine;
void doSomething(double a, double b)
{
curThreshold= randomDoubleEngine(engine, a, b);
}
public:
myclass(): curThreshold(0) {}
void doThat(){
doSomething(0,10);
std::cout << "threshold is " << curThreshold << std::endl;
}
};
std::mt19937 myclass::engine=std::mt19937(std::random_device()());
int
main()
{
myclass m;
m.doThat();
m.doThat();
return 0;
}