现实程序中来自c ++ <random>库的随机数生成器

时间:2015-10-29 17:22:11

标签: c++ c++11 random

我正在了解这个图书馆,它在很多方面改进了旧兰特和品牌。但是对于rand来说,很明显只有一个随机数生成器在使用rand时被调用和更新,无论你的程序在哪里。通过新的方式,我不确定如何有效地模仿这种行为并且具有良好的风格。例如,如果我想要一个骰子滚动,并在主程序中编写一个在线示例,我用这样的方法写一个对象:

class foo{
    public:
    float getDiceRoll(){
        std::random_device rd;
        std::default_random_engine e1(rd());
        std::uniform_int_distribution<int> uniform_dist(1, 6);
        return uniform_dist(e1);
   }
}

这看起来很糟糕,因为每次你想要掷骰子时都会重新创建引擎。这是一个有点人为的案例,但在一个大型程序中,你将不得不将随机数生成器的声明放在某个地方。作为第一次尝试使用我只想让所有随机数都有一个生成器,就像过去一样。实现这一目标的最好方法是什么?在线简单可用的示例都直接写入主程序,因此他们不回答这个基本问题。   我想不出任何看起来像用大锤敲打坚果的东西。任何帮助都会很棒。

3 个答案:

答案 0 :(得分:4)

对于这样一个微不足道的案例,我会把它们全部static并且不要太担心它。肯定会返回int

int getDiceRoll() {
    static std::random_device rd;
    static std::default_random_engine gen(rd());
    static std::uniform_int_distribution<int> dis(1, 6);

    return dis(gen);
}

答案 1 :(得分:3)

你可以将它全部包装在这样的class中:

#include <random>
#include <iostream>

/**
 * (P)seudo (R)andom (N)umber (G)enerator
 */
template<typename Type = int>
class PRNG
{
    // easier to use param_type
    using param_type = typename std::uniform_int_distribution<Type>::param_type;

    // store an instance of the generator/distribution in the class object
    std::mt19937 gen;
    std::uniform_int_distribution<Type> dis;

public:
    // seed generator when creating
    PRNG(): gen(std::random_device()()) {}

    Type get(Type from, Type to)
    {
        // only need to create a light weigt param_type each time
        return dis(gen, param_type{from, to});
    }
};

int main()
{
    PRNG<int> prng;

    for(auto i = 0U; i < 10; ++i)
        std::cout << "die roll " << i << ": " << prng.get(1, 6) << '\n';
}

示例输出:

die roll 0: 2
die roll 1: 6
die roll 2: 1
die roll 3: 5
die roll 4: 6
die roll 5: 3
die roll 6: 3
die roll 7: 6
die roll 8: 3
die roll 9: 2

答案 2 :(得分:2)

我没有编译,所以可能会出现一些语法错误......但你明白了这个想法。

class foo
{
public:
    foo()
    {
        e1 = std::default_random_engine(rd());
        uniform_dist = std::uniform_int_distribution<int>(1, 6);
    }

    int getDiceRoll()
    {
        return uniform_dist(e1);
    }

private:
    std::random_device rd;
    std::default_random_engine e1;
    std::uniform_int_distribution<int> uniform_dist;
};