gpt4 book ai didi

C++ boost 随机数生成器为多个实例设置种子

转载 作者:行者123 更新时间:2023-11-30 01:04:05 24 4
gpt4 key购买 nike

我想创建一个类的多个实例,并希望它们使用 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

最佳答案

我已尝试提出一个示例来实现我认为您想要实现的目标。我希望你不介意我去掉了 boost,因为我看不出在这里使用它的理由。

希望对您有所帮助:

// C/C++ standard library
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <random>

// Class Individual
class Individual
{
public:
// an accessor to pass information back
void move_bias_random_walk( double mu, double sigma = 0.4 )
{
distance_ += std::normal_distribution<double>{mu, sigma}( myEngine );
}

// An accessor for the distance object
double get_distance() { return distance_; }

private:
// containers
double distance_ = 0.4;
static std::mt19937 myEngine;
};

// initialize static random engine to be shared by all instances of the Inidvidual class
auto Individual::myEngine = std::mt19937( std::time( 0 ) );

int main()
{
std::cout << "!!!Begin!!!" << std::endl;
// Initialise two individuals in this case but there could be thousands
Individual individual_a{};
Individual individual_b{};

std::cout << "starting values: individual a = " << individual_a.get_distance()
<< " individual b = " << individual_b.get_distance() << std::endl;
// Do 10 jumps with the same mean for each individual and see where they end up each time

std::cout << "A\tB" << std::endl;

// let's not use rand()
std::default_random_engine eng{1337};
std::uniform_real_distribution<double> uniformMean{-10,10};

for ( auto i = 1; i <= 10; ++i ) {
double mean = uniformMean(eng);
individual_a.move_bias_random_walk( mean );
individual_b.move_bias_random_walk( mean );
std::cout << individual_a.get_distance() << " " << individual_b.get_distance() << std::endl;
}

std::cout << "finished" << std::endl;
return 0;
}

它打印:

!!!Begin!!!
starting values: individual a = 0.4 individual b = 0.4
A B
8.01456 7.68829
2.53383 1.19675
7.06496 5.74414
9.60985 9.04333
12.4008 13.4647
11.2468 13.4128
6.02199 8.24547
0.361428 2.85905
-3.28938 -1.59109
-5.99163 -4.37436
finished

关于C++ boost 随机数生成器为多个实例设置种子,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50732980/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com