首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用相同的种子在代码的不同部分生成C++-11中的随机数

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

Stack Overflow用户
提问于 2015-07-15 12:54:56
回答 2查看 1.4K关注 0票数 3

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

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

我的随机数生成器类:

代码语言:javascript
复制
    #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类的对象并打印随机值:

代码语言:javascript
复制
    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;
    }

我的主要职能是:

代码语言:javascript
复制
    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对象并打印随机值。如果一切都是正确的,这段代码应该在相同的范围内打印两个5个随机数的序列,但值不同。然而,它们是完全相同的序列。有人能帮我解决这个问题吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-07-15 13:40:04

因为你想使用相同的引擎,所以你必须使用相同的引擎。(这么多都是单身人士。)传递对RNG的引用,在RNG中存储和使用引用。对代码的小改动使其如此(其中一个注释已经指出了这一点):

代码语言:javascript
复制
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中,我更喜欢这样:

代码语言:javascript
复制
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;
}
票数 5
EN

Stack Overflow用户

发布于 2015-07-15 13:34:45

单例模式

在软件工程中,单例模式是一种将类的实例化限制为一个对象的设计模式。当需要一个对象来协调整个系统的操作时,这是非常有用的。这个概念有时被推广到只存在一个对象或将实例化限制在一定数量的对象时更有效地运行的系统。这个术语来自于独生子女的数学概念。

代码语言:javascript
复制
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;
};

交替

依赖注入

在软件工程中,依赖注入是一种软件设计模式,它实现控制反转以解决依赖关系。注入是将依赖项(服务或软件模块)传递给依赖对象(客户端)。服务成为客户端状态的一部分。将服务传递给客户端,而不是允许客户端构建或查找服务,是该模式的基本要求。

代码语言:javascript
复制
class MyClass
{
    public:
        void set_random_generator( const RandomGenerator& value );
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31431020

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档