Создайте вектор определенного пользователем типа, который имеет равномерное случайное распределение в качестве частного члена с воспроизводимыми результатами - PullRequest
0 голосов
/ 22 апреля 2020

Трудно возобновить в названии. У меня следующая ситуация:

#include <random>

class classRng{

public:

    classRng(){
    }
    classRng(int aSeed){
        Rng.seed(aSeed);
    }

    void setSeed(int seed){
        Rng.seed(seed);
    }

    std::vector<int>& getResults(){
        return extractedNum;
    }

    void run(int low, int up);

private:

    std::vector<int> extractedNum;

    mutable std::mt19937 Rng;

    std::uniform_int_distribution<> randomUniformGenerator;


};

void classRng::run(int low,int up){

    decltype(randomUniformGenerator.param()) range(low, up);
    randomUniformGenerator.param(range);
    extractedNum.clear();

    for(int i=0;i<10;i++){
        extractedNum.push_back(randomUniformGenerator(Rng));
    }

}

Этот класс извлекает числа из дистрибутива, инициализированного начальным числом, для воспроизводимости. Я хочу подчеркнуть, что подача RNG с фиксированным и stati c seed в моем случае обязательна для воспроизведения результатов.

Другой класс, скажем, targetClass параметризован с помощью classRng таким образом :

template<class stochaticClass>
class targetClass{

public:

    targetClass(){}
    targetClass(stochaticClass _extr){
        extr=_extr;
    }

    void foo();

    stochaticClass& stochasticClassAccess(){
        return extr;
    }

private:

    stochaticClass extr;
    std::vector<int> storedResults;

};

template<class stochasticClass>
void targetClass<stochasticClass>::foo(){

    extr.run(1,30);
    storedResults = extr.getResults();

}

Я хочу создать вектор из targetClass объектов, чей метод класса foo() дает разные результаты. В функции main () я действую следующим образом:

#include "classRng.cpp"
#include "targetClass.cpp"

int main(int argc, char *argv[])
{

    int N=10;

    typedef targetClass<classRng> targetType;

    std::vector<targetType> objects(N);
    int seed=0;
    classRng instatiatedObj(seed);

    for(int i=0;i < N; i++){
        targetType thisObject(instatiatedObj);
        objects[i]=thisObject;
        objects[i].foo();
    }

}

Я хотел бы добиться ситуации, когда каждый объект в векторе дает разные результаты (хранит разные результаты в storedResults), но производит то же самое результаты с другим запуском исполняемого файла. Я показываю свой последний подход после попытки сначала установить с помощью функции-установщика classRng, а позже я попытался просто построить каждый targetClass с помощью конструктора по умолчанию без явного использования пользовательского конструктора с classRng instatiatedObj в качестве аргумента.

Обновление

Я справился с проблемой, используя указатели:

main(){
...
    classRng* pointer2clrng=nullptr;
    pointer2clrng=&instatiatedObj;
...
}

class targetClass{

...

public:
    targetClass(){}
    targetClass(stochaticClass* _extr){
       extr=&_extr;
       }

...

private:
    stochaticClass* extr;

...

}

Это нормально, но мне интересно, стоит ли использовать умный указатель или даже искать методы, избегающие указателей.

1 Ответ

0 голосов
/ 22 апреля 2020

Нет смысла хранить std ::iform_int_distribution в classRng. Также Rng не должен быть изменчивым. Таким образом, classRng может быть

#include <random>

class classRng{
public:
    classRng(){
    }

    classRng(int aSeed) :
        Rng{ aSeed }
    {}

    void setSeed(int seed){
        Rng.seed(seed);
    }

    std::vector<int>& getResults(){
        return extractedNum;
    }

    void run(int low, int up);

private:

    std::vector<int> extractedNum;

    std::mt19937 Rng;
};

void classRng::run(int low,int up){
    std::uniform_int_distribution<> randomUniformGenerator{ low, up };
    extractedNum.clear();

    for(int i=0; i<10; i++){
        extractedNum.push_back(randomUniformGenerator(Rng));
    }
}

Проблема в том, что вам нужно передать classRng, засеянное с другим значением, для каждого объекта в вашем векторе.

#include "classRng.h"
#include "targetClass.h"
#include <random>

int main(int argc, char *argv[])
{
    int N=10;
    typedef targetClass<classRng> targetType;

    std::vector<targetType> objects(N);
    std::minstd_rand seedGenerator{0};
    std::uniform_int_distribution<> distribution;

    for(int i=0;i < N; i++){
        objects[i] = targetType{classRng{ distribution(seedGenerator) }};
        objects[i].foo();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...