a03*_*56f 5 c++ random seed srand prng
我已经看到了很多关于每次执行不多次伪随机数生成器的建议,但从未附带过彻底的解释.当然,很容易理解为什么以下(C/C++)示例不是一个好主意:
int get_rand() {
srand(time(NULL));
return rand();
}
Run Code Online (Sandbox Code Playgroud)
因为get_rand每秒调用几次会产生重复的结果.
但是下面的例子不是一个可以接受的解决方案吗?
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
Run Code Online (Sandbox Code Playgroud)
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();
}
Run Code Online (Sandbox Code Playgroud)
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() << " ";
}
}
Run Code Online (Sandbox Code Playgroud)
即使MyRand:s构造函数快速连续多次调用,每次调用srand都有不同的参数.显然,这不是线程安全的,但后来也不是rand.
每次调用伪随机数生成器函数时,生成器都会采用某种内部状态并生成伪随机数和新的内部状态.精心选择转换内部状态的算法,使输出看起来是随机的.
当您为随机数生成器播种时,您基本上就是设置此内部状态.如果将内部状态重置为某个可预测值,则会丢失随机性的外观.
例如,流行的简单RNG是线性同余生成器.数字生成如下:
X[n+1] = (a X[n] + c) mod m
Run Code Online (Sandbox Code Playgroud)
在这种情况下,X [n + 1]既是结果又是新的内部状态.如果您按照上面的建议每次播种生成器,您将获得如下所示的序列:
{(ab + c) mod m, (a(b+1) + c) mod m, (a(b+2) + c) mod m, ...}
Run Code Online (Sandbox Code Playgroud)
其中b是你的seed_base.这根本不是随机的.
| 归档时间: |
|
| 查看次数: |
2007 次 |
| 最近记录: |