半随机数生成C++

Semi-Random Number Generation C++

本文关键字:C++ 随机数      更新时间:2023-10-16

我正在运行蒙特卡罗模拟,其中我生成了 100,000 条随机路径。我的问题是我想找到一种方法来将相同的 100,000 条随机路径保留在其他变量的循环中。从本质上讲,我希望我的随机数生成器在每次运行 100,000 次迭代时重置。目前,我的代码看起来像这样:

vector<double>Rand_Var(double time)
{
static mt19937 generator;
normal_distribution<>ND(0., 1.);
ND(generator);
double phi;
vector<double> rand(time + 1);
for (int i = 1; i <= time; i++)
{
phi = ND(generator);
rand[i] = phi;        
}
return rand;
}

然后在测试main()中,我有:

for (int l = 0; l < 5; l++)
{   
for (int i = 0; i <= 1; i++)
{   
vector<double>rand_val = Rand_Var(time_opt);            
cout << rand_val[4] << endl;
}
}

我得到以下输出:

-0.214253
1.25608
-1.82735
0.919376
1.45366
-0.791957
0.530696
0.0751259
-0.559636
-0.709074

然而,我想得到的是这样的:

-0.214253
1.25608
-0.214253
1.25608
-0.214253
1.25608
-0.214253
1.25608
-0.214253
1.25608

这可能吗?

如果您想再次获得相同的随机数集,只需将生成器重新设定为同一种子即可!

例如:

vector<double>Rand_Var(double time, bool should_reset) {
static time_t my_seed = time(0);
static mt19937 generator(my_seed);
if(should_reset) { generator.seed(my_seed); } //reseed and reset!
...

然后在您的循环中:

for (...){
bool should_reset = true;
for (...) {
vector<double>rand_val = Rand_Var(time_opt, should_reset);
should_reset = false;
...
}
}

如果使用静态变量,那么它将被初始化一次并一直生成新数字。

只需删除静态,它将被初始化并在每次调用函数时使用相同的种子。

如果你需要多个数字(不清楚时间是什么,它是索引还是随机性值?(,将 rng 作为参数传递:

vector<double>Rand_Var(mt19937& rng, double time);

并在您的第一个 for 循环中创建一个新的。

for (int l = 0; l < 5; l++)
{
mt19937 generator;
for (int i = 0; i <= 1; i++)
{
auto rand_val = Rand_Var(generator , time_opt);

如果您希望每 100,000 个随机数相同,请将生成器包装在一个函数中并保留一个计数器。那会给你一个随机函数,比如

double random()
{
static std::mt19937 generator;
static int counter = 0;
if (counter % 100000 == 0) // reset every 100000 times.
generator.seed();
normal_distribution<> dis(0., 1.);
counter++;
return dis(generator);
}

如果您希望每 100,000 个呼叫Rand_Var始终返回,那么您只需要做同样的事情

std::vector<double> Rand_Var(std::size_t time)
{
static std::mt19937 generator;
static int counter = 0;
if (counter % 100000 == 0) // reset every 100000 times.
generator.seed();
normal_distribution<> dis(0., 1.);
counter++;
std::vector<double> data;
data.reserve(time);
std::generate_n(std::back_inserter(data), time, [&](){ return dis(generator); });       
return data;
}