在c++ -11中使用相同的种子在代码的不同部分生成随机数

Generate random numbers in C++-11 in different parts of a code using the same seed

本文关键字:同部 随机数 代码 种子 c++      更新时间:2023-10-16

我试图封装一个类来生成由种子和随机值范围控制的随机数。我想从代码的不同部分调用这个类,具有不同的范围,但使用相同的种子。

根据其他帖子的建议(在c++ -11中使用boost封装随机数生成器),我实现了以下代码:

我的随机数生成器类:

    #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;
    }

My main function:

    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_作为参数传递给函数funcc,该函数将实例化RNG对象并打印随机值。如果一切都是正确的,这段代码应该在相同的范围内打印5个随机数字的2个序列,但具有不同的值。然而,它们是完全相同的序列。谁能帮我修一下这个?

既然想要使用相同的引擎,就必须使用相同的引擎。(这是一个单例。)传递一个引用给RNG,在RNG中存储和使用一个引用。对你的代码做一些小的修改(其中一个注释已经指出了这一点):

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;
}

单例模式

在软件工程中,单例模式是一种设计模式这将类的实例化限制为一个对象。这是当只需要一个对象来协调跨操作时非常有用这个系统。这个概念有时被推广到当只存在一个对象或该限制时,操作更有效实例化到一定数量的对象。这个词来源于单例的数学概念。
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 );
}