Генерация полуслучайных чисел C ++ - PullRequest
0 голосов
/ 25 октября 2018

Я запускаю симуляцию Монте-Карло, где генерирую 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

Возможно ли это?

Ответы [ 3 ]

0 голосов
/ 26 октября 2018

Если вы хотите снова получить тот же набор случайных чисел, просто повторно отправьте ваш генератор в то же семя!

Например:

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;
        ...
    }
}
0 голосов
/ 26 октября 2018

Если вы хотите, чтобы каждые 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;
}
0 голосов
/ 26 октября 2018

Если вы используете статическую переменную, то она будет инициализирована один раз и будет постоянно генерировать новые числа.

Просто удалите статическую переменную, и она будет инициализироваться и использовать одно и то же начальное число каждый раз, когда функцияПозвонил.

Если вам нужно более одного числа (неясно, во сколько это время, это индекс или значение для случайности?), передайте 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...