【发布时间】:2018-06-07 04:29:55
【问题描述】:
我想创建一个类的许多实例,并希望它们使用 boost 随机数生成器来进行具有用户定义平均值的正态分布跳转。我一直在阅读一些消息来源,他们说您不想像here 这样重新设置数字生成器的种子。理想情况下,我想要一个全局生成器,并且单个类的每个实例都能够更改平均值并生成一个对于所有实例都不相同的随机数。我正在努力实现这一点我有一个全局普通类,但是该类的每个实例的种子都是相同的。
// C/C++ standard library
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/variate_generator.hpp>
#include <boost/random/lognormal_distribution.hpp>
/**
* The mt11213b generator is fast and has a reasonable cycle length
* See http://www.boost.org/doc/libs/1_60_0/doc/html/boost_random/reference.html#boost_random.reference.generators
*/
struct random_generator : boost::mt11213b {
random_generator(void){
seed(static_cast<unsigned int>(std::time(0)));
}
} random_generator;
template<
class Type
> struct Distribution {
Type distribution;
boost::variate_generator<decltype(random_generator),Type> variate_generator;
template<class... Args>
Distribution(Args... args):
variate_generator(random_generator,Type(args...)) {}
double random(void) {
return variate_generator();
}
};
typedef Distribution< boost::normal_distribution<> > Normal;
using namespace std;
// global normal random number generator
Normal normal_random_generator;
// Class Individual
class Individual {
public:
Individual() { } // constructor initialise value
virtual~Individual() = default;
// an accessor to pass information back
void move_bias_random_walk(double mu) {
normal_random_generator = {mu, sigma_};
distance_ += normal_random_generator.random();
}
// An accessor for the distance object
double get_distance() {
return distance_;
}
private:
//containers
double distance_ = 0.4;
double sigma_ = 0.4;
};
int main() {
cout << "!!!Begin!!!" << endl;
// Initialise two individuals in this case but there could be thousands
Individual individual_a;
Individual individual_b;
cout << "starting values: individual a = " << individual_a.get_distance() << " individual b = " << individual_b.get_distance() << endl;
// Do 10 jumps with the same mean for each individual and see where they end up each time
cout << "A\tB" << endl;
for (auto i = 1; i <= 10; ++i) {
double mean = rand();
individual_a.move_bias_random_walk(mean);
individual_b.move_bias_random_walk(mean);
cout << individual_a.get_distance() << "\t" << individual_b.get_distance() << endl;
}
cout << "finished" << endl;
system("PAUSE");
return 0;
}
这是编译上述代码得到的输出。
!!!Begin!!!
starting values: individual a = 0.4 individual b = 0.4
A B
41.8024 41.8024
18509.2 18509.2
24843.6 24843.6
51344 51344
70513.4 70513.4
86237.8 86237.8
97716.2 97716.2
127075 127075
154037 154037
178501 178501
finished
【问题讨论】:
-
上面的代码无法编译,因为它在个人类中的
normal_random_generator上缺少下划线。此外,AFAIKvariate_generator将复制您的random_generator,这就是为什么这两个发行版提供相同的序列。 -
@Christoph 我已将 normal_random_generator 定义为 std:namespace 下面的全局变量,它至少允许我的系统编译。这就是为什么我使用全局变量以便只制作一个副本并且任何平局都会继续种子
-
@Cyrillm_44 和 Cristoph 正确地指出这不是实际发生的情况。我正在查看您的代码,还有很多问题,所以我现在删除了我的答案。 (直到我明白为止)
-
当我早些时候复制代码时,随机生成器被定义为
Normal normal_random_generator_;。我猜你现在修好了。然而,我评论中的重点是这个生成器被复制而不是被引用使用...... -
@Christoph 你可以看到编辑:stackoverflow.com/posts/50732980/revisions(你也可以制作它们,所以请随时修复类似的小错误)