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

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

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

根据其他 post () 的建议,我实现了以下代码:

我的随机数生成器class:

    #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 对象的函数 class 并打印随机值:

    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 个随机数在相同范围内但具有不同的值。但是,它们是完全相同的序列。谁能帮我解决这个问题?

Singleton Pattern

In software engineering, the singleton pattern is a design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects. The term comes from the mathematical concept of a singleton.

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

或者

Dependency Injection

In software engineering, dependency injection is a software design pattern that implements inversion of control for resolving dependencies. An injection is the passing of a dependency (a service or software module) to a dependent object (a client). The service is made part of the client's state. Passing the service to the client, rather than allowing a client to build or find the service, is the fundamental requirement of the pattern.

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

既然要用同一个引擎,就得用同一个引擎。 (这是一个单身人士。)传递对 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;
}