我有一个类的成员函数,它应该在一个范围内生成一个随机数。为此,我使用rand()函数。该函数生成一个如下随机数:
unsigned seed;
seed = time(0);
srand(seed);
std::cout << "Random Number: "<< rand() << std::endl;
在两个不同的对象上调用该函数。结果是:
Random Number: 1321638448
Random Number: 1321638448
每次我称它为一致。我做错了什么?
答案 0 :(得分:3)
(将我的评论转换为答案)。
对于大多数应用程序,您只希望在运行程序的过程中对rand
种子进行一次。多次播种需要你获得不同的随机种子,这很容易搞砸。
在您的情况下,time
函数通常会返回具有秒数级别的分辨率(尽管this isn't actually required by the standard)。因此,如果您在同一秒内拨打time
两次,则可能会返回相同的值。这可以解释为什么你会得到重复的值:你将同一个值的随机发生器播种两次,然后立即查询它是否为随机数。
对此最好的解决方案是将随机化器播种一次。通常,您可以在main
中执行此操作。
如果您确实想多次为随机数发生器播种,请确保您使用的种子几乎是随机的。否则,你会冒这样的风险。
答案 1 :(得分:1)
伪随机数生成器基本上必须通过一组统计测试,以确保它们“足够随机”作为一组数字。但当然,它实际上并不是随机的。使用srand(seed)
调用seed
基本上会生成一组数字,如果通过这些测试,则会看起来“足够随机”。
通过多次srand(seed)
调用seed
,您可以一遍又一遍地生成相同的集合并获取其中的第一个值。
您呼叫srand(seed)
ONCE,然后致电rand()
以获取随机数集中的下一个值。或者您需要每次使用不同的(随机)种子调用srand(seed)
。
如果你使用的是Linux,你也可以使用/dev/urandom
来获取一个随机数 - 内核已经从环境中获取信号/噪声,为它生成“熵”,据说它比算法伪随机数生成器。
答案 2 :(得分:0)
srand
函数应该只在程序中调用一次(大多数情况下,并非所有情况)。如果要重新种植,则应使用不同的种子编号。因为rand()
函数是伪随机数生成器。换句话说,rand()
会为您提供一个计算出的数字。
在C ++ 11之后,你可以使用很多强大的随机数生成库。请参阅:http://en.cppreference.com/w/cpp/numeric/random