2

我创建了以下函数来为骰子游戏创建随机数

#include <iostream>
#include <ctime>
#include <cstdlib>
#include "dice.h"
#include "display.h"
using namespace std;
int die[6][10];
void dice(int times, int dice){
    int r;
    for(int x=0;x<times;x++){
        for(int x=0;x<dice;x++){
            srand(time(0));
            r=(rand() % 5);
            die[r][x]+=1;
            cout<<"Die #"<<x+1<<" rolled a "<<r<<endl;
        }
    }

}

但它不会重新播种。它只是为每个骰子输出相同的数字。有谁知道我该如何解决?

4

4 回答 4

3

您没有正确使用 srand 和 rand 函数。您应该“播种”一次随机数生成器,然后用于rand()从 RNG 中检索连续值。每个种子产生符合特定随机性标准的特定数字序列。

相反,您每次都为随机数生成器播种,然后检索随机序列中的第一个值。由于time()调用如此之快以至于它返回相同的种子,因此您实际上将随机数生成器重置回相同序列的开头,因此您得到的数字与之前相同。

即使返回的值time()更新得足够快以至于你每次都得到一个新的种子,你仍然不能保证好的随机数。随机数生成器旨在生成一个数字序列,其中该序列具有某些统计属性。但是,不能保证相同的属性适用于从不同序列中选择的值。

因此,要使用确定性随机数生成器,您应该只为生成器播种一次,然后使用该种子生成的值序列。


还有一点;用于实现的随机数生成器在rand()历史上并不是很好,rand()不是可重入的或线程安全的,并且将产生的值转换rand()为具有所需分布的值并不总是那么简单。

在 C++ 中,您应该更喜欢<random>提供更好功能的库。这是一个使用<random>.

#include <random>
#include <iostream>

int main() {
    const int sides = 6;
    int groups = 10, dice_per_group = 3;

    std::uniform_int_distribution<> distribution(1,sides); // create an object that uses randomness from an external source (provided later) to produces random values in the given (inclusive) range

    // create and seed the source of randomness
    std::random_device r;
    std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
    std::mt19937 engine(seed);

    for (int i=0; i<groups; ++i) {
        for (int j=0; j<dice_per_group; ++j) {
            // use the distribution with the source of randomness
            int r = distribution(engine);
            std::cout << "Die #" << j+1 << " rolled a " << r << '\n';
        }
        std::cout << '\n';
    }
}
于 2012-09-05T23:18:58.963 回答
1

您只想为正在进行的任何模拟调用一次 srand() 。这样做的原因是每次调用都会重新设置 rand() 的种子,这会对 rand() 值施加偏差。如果您假设 iid,这一点尤其重要

在上述情况下,您希望将 srand() 移出循环。

于 2012-09-05T22:55:00.140 回答
1

srand() 在重复调用的函数中,或者循环不好。

在 main 中调用 srand()。每个程序只调用一次。

于 2012-09-05T22:16:53.263 回答
0

您只想调用 srand() 一次。时间太短了, time() 返回相同的值。所以随机数生成器从同一个地方开始。

如果可能,在函数之前调用 srand,或者在函数的开头。

于 2012-09-05T22:16:28.267 回答