问题与种子一个伪随机数发生器不止一次? [英] Issues with seeding a pseudo-random number generator more than once?
问题描述
我已经看到了相当多的建议,不是每次执行一次以上的伪随机数生成器种子,但从来没有一个彻底的解释。当然,很容易看出为什么下面的(C / C ++)例子不是个好主意:
I've seen quite a few recommendations for not seeding pseudo-random number generators more than once per execution, but never accompanied by a thorough explanation. Of course, it is easy to see why the following (C/C++) example is not a good idea:
int get_rand() {
srand(time(NULL));
return rand();
}
<每秒数次产生重复结果。
since calling get_rand
several times per second produces repeated results.
但是,以下示例仍然是可接受的解决方案?
MyRand.h
#ifndef MY_RAND_H
#define MY_RAND_H
class MyRand
{
public:
MyRand();
int get_rand() const;
private:
static unsigned int seed_base;
};
#endif
MyRand.cpp / p>
MyRand.cpp
#include <ctime>
#include <cstdlib>
#include "MyRand.h"
unsigned int MyRand::seed_base = static_cast<unsigned int>(time(NULL));
MyRand::MyRand()
{
srand(seed_base++);
}
int MyRand::get_rand() const
{
return rand();
}
main.cpp
$ b
main.cpp
#include <iostream>
#include "MyRand.h"
int main(int argc, char *argv[])
{
for (int i = 0; i < 100; i++)
{
MyRand r;
std::cout << r.get_rand() << " ";
}
}
即使 MyRand
:s构造函数被快速连续调用几次,每次调用 srand
都有不同的参数。显然,这不是线程安全的,但是再次不是 rand
。
i.e. even though MyRand
:s constructor is called several times in rapid succession, each call to srand
has a different parameter. Obviously, this is not thread-safe, but then again neither is rand
.
推荐答案
每次调用伪随机数生成器函数时,生成器都会采用一些内部状态,并生成伪随机数和新的内部状态。仔细选择用于转换内部状态的算法,使得输出看起来是随机的。
Each time you call a pseudo-random number generator function, the generator takes some internal state and produces a pseudo-random number and a new internal state. The algorithm for transforming the internal state is carefully chosen so the output appears random.
当你播种随机数生成器时,你基本上设置这个内部状态。如果将内部状态重置为某个可预测的值,则会丢失随机性的外观。
When you seed the random number generator, you're basically setting this internal state. If you reset the internal state to some predictable value, you'll lose the appearance of randomness.
例如,一个流行的简单RNG是线性并发生成器。数字生成如下:
For example, a popular, simple RNG is a linear congruential generator. Numbers are generated like this:
X[n+1] = (a X[n] + c) mod m
在这种情况下,X [n + 1]是结果和新的内部状态。如果你按照上面的建议每次生成生成器,你会得到一个如下的序列:
In this case, X[n+1] is both the result and the new internal state. If you seed the generator every time as you suggest above, you'll get a sequence that looks like this:
{(ab + c) mod m, (a(b+1) + c) mod m, (a(b+2) + c) mod m, ...}
其中b是 seed_base
。这看起来不是随机的。
where b is your seed_base
. This doesn't look random at all.
这篇关于问题与种子一个伪随机数发生器不止一次?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!