c ++ 11 — генерация случайных чисел в C ++ — 11 в разных частях кода с использованием одного и того же начального числа

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

Следующие предложения другого поста (Инкапсулированный генератор случайных чисел в C ++ — 11 с использованием наддува) Я реализовал следующий код:

Мой класс генератора случайных чисел:

    #include <random>
#include <iostream>

typedef std::mt19937                     ENG;    // Mersenne Twister
typedef std::uniform_int_distribution<> iDIST;   // Uniform Integer Distribution

class RNG {
private:
ENG eng;
iDIST idist;

public:
iDIST::result_type igen() { return idist(eng); }
RNG(ENG eng_,int imin,int imax)
: idist(imin,imax)
{eng = eng_; }

};

Функция для создания объекта класса RNG и печати случайных значений:

    void myfunc(ENG eng_,int imin, int imax, int N){
RNG myirn(eng_,imin,imax);
for (int i = 0; i < N; i++){
std::cout << myirn.igen() << std::endl;
}
return;
}

Моя основная функция:

    int main(int argc, char **argv){
int myseed = 1;
int N = 5;
int imin1 = 1;
int imax1 = 10;

//Seed globally
ENG eng_;
eng_.seed(myseed);

std::cout << "Range = [" << imin1 << "," << imax1 << "]" << std::endl;
myfunc(eng_,imin1,imax1,N);
std::cout << "Range = [" << imin1 << "," << imax1 << "]" << std::endl;
myfunc(eng_,imin1,imax1,N);return 0;
}

Как вы можете видеть, моя стратегия состояла в том, чтобы заполнить мой генератор случайных чисел глобально (в основной функции) и передать переменную eng_ в качестве параметра функции func, которая будет создавать экземпляр объекта RNG и печатать случайные значения. Если бы все было правильно, этот код должен печатать 2 последовательности из 5 случайных чисел в пределах одного диапазона, но с разными значениями. Однако они точно такой же последовательности. Может ли кто-нибудь помочь мне исправить это?

3

Решение

Поскольку вы хотите использовать один и тот же движок, вы должны использовать один и тот же движок. (Это очень много.) Передайте ссылку на ГСЧ, сохраните и используйте ссылку в ГСЧ. Незначительные изменения в вашем коде делают это так (один из комментариев уже указал на это):

ENG &eng;
RNG(ENG &eng_, int imin, int imax)
: idist(imin, imax), eng(eng_) {}

void myfunc(ENG &eng_, int imin, int imax, int N)

Но мне больше нравится, если двигатель спрятан в RNG вот так:

class RNG {
private:
static ENG eng;
iDIST idist;
public:
static void seed(int s) { eng.seed(s); }
RNG(int imin, int imax) : idist(imin, imax) {}
int generate() { return idist(eng); }
};

// the one generator, stored as RNG::eng
ENG RNG::eng;

// print some generated numbers from a range
void printRandomNumbers(int imin, int imax, int N){
std::cout << "Range = [" << imin << "," << imax << "]" << std::endl;
RNG myirn(imin, imax);
for (int i = 0; i < N; i++){
std::cout << myirn.generate() << std::endl;
}
return;
}

int main()
{
//Seed globally
int myseed = 1;
RNG::seed(myseed);
printRandomNumbers(1, 10, 5);
printRandomNumbers(11, 20, 5);
printRandomNumbers(21, 30, 5);
return 0;
}
4

Другие решения

Синглтон

В разработке программного обеспечения одноэлементный паттерн — это паттерн проектирования
это ограничивает создание экземпляра класса одним объектом. Это
полезно, когда для координации действий через
система. Эта концепция иногда обобщается на системы, которые
работать более эффективно, когда существует только один объект, или которые ограничивают
создание экземпляров для определенного количества объектов. Термин происходит от
математическая концепция синглтона.

class RandomGenerator
{
public:
static RandomGenerator& get_instance( void )
{
static RandomGenerator instance;
return instance;
}

private:
RandomGenerator() { /*seed generator*/ };

RandomGenerator( RandomGenerator const& ) = delete;
void operator=( RandomGenerator const& ) = delete;
};

альтернативно

Внедрение зависимости

В разработке программного обеспечения внедрение зависимости — это разработка программного обеспечения.
шаблон, который реализует инверсию управления для разрешения
зависимостей. Внедрение — это передача зависимости (услуга
или программный модуль) к зависимому объекту (клиенту). Служба
сделал часть состояния клиента. Передача услуги клиенту,
вместо того, чтобы позволить клиенту построить или найти услугу, является
Основное требование шаблона.

class MyClass
{
public:
void set_random_generator( const RandomGenerator& value );
}
2

По вопросам рекламы [email protected]