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

Cha*_*ana 3 c++ random c++11 random-seed

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

按照其他帖子的建议(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_; }

    };
Run Code Online (Sandbox Code Playgroud)

创建 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;
    }
Run Code Online (Sandbox Code Playgroud)

我的主要功能:

    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;
    }
Run Code Online (Sandbox Code Playgroud)

如您所见,我的策略是在全局范围内(在主函数中)为我的随机数生成器设置种子,并将变量 eng_ 作为参数传递给函数 func,该函数将实例化 RNG 对象并打印随机值。如果一切都正确,此代码应打印 2 个序列,其中包含 5 个相同范围内但具有不同值的随机数。但是,它们的顺序完全相同。谁能帮我解决这个问题?

Ken*_*rom 5

既然要使用同一个引擎,就必须使用同一个引擎。(这是一个单例。)传递对 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)
Run Code Online (Sandbox Code Playgroud)

但如果引擎像这样隐藏在 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;
}
Run Code Online (Sandbox Code Playgroud)