首页 > 解决方案 > 当我正确地播种生成器时,为什么我会得到相同的随机数?

问题描述

我正在尝试制作一个迷你彩票模拟器。我想生成 8 个随机数,最小为 1,最大为 20。我将这些生成的数字存储在Lottery对象中。我有一个LotteryManager类,我可以在其中决定要生成这些彩票的次数。但我总是得到相同的随机数。我为生成器播种,所以我不明白它有什么问题。任何帮助表示赞赏!

这是我的彩票课:

class Lottery
{
private:
    vector<int> lotteryA;
    int lotteryB;
public:
    Lottery();

    vector<int> getLotteryA() const;
    int getLotteryB() const;

    void generateLotteryA();
    void generateLotteryB();
    void printLottery() const;
};

这是管理它的类:

class LotteryManager
{
private:
    unsigned int quanity = 0;
    map<unsigned int, Lottery> lotteries;
public:
    LotteryManager();
    LotteryManager(unsigned int q);

    unsigned int getQuanity() const;
    void setQuanity(unsigned int value);

    void generateLotteries();
    void printLotteries() const;
};

这是我的主要代码:

LotteryManager* lm = new LotteryManager(100);
    lm->generateLotteries();
    lm->printLotteries();

LotteryManager类中的生成和打印函数:

void LotteryManager::generateLotteries()
{
    for(unsigned int i = 0; i < getQuanity(); ++i)
    {
        Lottery l;
        l.generateLotteryA();
        l.generateLotteryB();
        lotteries.insert(make_pair(i, l));
        l.printLottery();
    }
}

void LotteryManager::printLotteries() const
{
    cout << "Lotteries:" << endl;
    for(auto current : lotteries)
    {
        cout << current.first << ".: ";
        current.second.printLottery();
    }
}

Lottery类中的生成函数:(生成A和B只是不同的字段,因为游戏旨在模仿名为Putto的游戏,您需要从字段A的20中猜测8个数字,从4中的4中猜测1字段 B)

void Lottery::generateLotteryA()
{
    random_device rn_d;
    mt19937 rng(rn_d());
    uniform_int_distribution<int> dist(1, 20);
    for(unsigned int i = 0; i < 8; ++i)
    {
        lotteryA.push_back(dist(rng));
    }
}

void Lottery::generateLotteryB()
{
    srand(time(0));
    lotteryB = (rand() % 20) + 1;
}

提前致谢!

标签: c++randomrandom-seed

解决方案


Lottery::generateLotteryA您声明一个随机引擎和随机设备。每次调用此函数时,引擎都会使用相同的随机设备播种,因此您可以获得相同的结果。


rn_d()每次使用不同random_device的 s 调用会产生不同的值似乎是合理的。但是,这不是必需的,并且如参考中所述:

...每个 std::random_device 对象可以生成相同的数字序列。

在实践中,大多数实现产生不同的值,所以这不是一个真正的问题。你甚至可以认为它是标准库中的一个缺陷,因为它没有做出这个保证。但是,正如当前指定的那样,您可以看到生成的值相同。


最简单的解决方法是制作引擎static,所以它只会在第一次调用函数时被播种:

void Lottery::generateLotteryA()
{
    // ...
    static mt19937 rng(rn_d());
    // ...
}

推荐阅读