【发布时间】:2011-06-11 19:28:01
【问题描述】:
srand(time(0))
在 C++ 中用于帮助生成随机数,方法是为 rand 播种一个起始值。
但是,你能解释一下它到底是做什么的吗?
谢谢。
【问题讨论】:
srand(time(0))
在 C++ 中用于帮助生成随机数,方法是为 rand 播种一个起始值。
但是,你能解释一下它到底是做什么的吗?
谢谢。
【问题讨论】:
srand() 给随机函数一个新的种子,一个起点(通常随机数是通过取前一个数(或种子)来计算的,然后对该数执行许多操作以生成下一个)。
time(0) 给出了自 Unix 纪元以来的时间,以秒为单位,这是一个非常好的“不可预测”的种子(你可以保证你的种子只会相同一次,除非你在同一秒内多次启动你的程序)。
【讨论】:
time(0) 返回从那一刻起经过的秒数。
据我所知,有一个方程式用于生成一系列值。下一个值在一定程度上受上一个值的影响。通过使用时间,您可以设置方程的初始值。请记住,这些值是伪随机的。
例如,如果你这样做:
srand(1);
srand(1);
将生成相同的数字序列。但是,如果你这样做:
srand(time(0));
srand(time(0) + 1);
由于种子值不同,会生成两个不同的数字序列。
【讨论】:
srand 调用之间的间隔超过 1 秒,否则并没有真正的不同。如果您在应用程序开始时有一次 srand(time(0)) 并且每秒运行多次(例如,某些脚本方法),则这种情况成立。有时可能会令人惊讶。
srand(1); srand(2);。 :P 你还应该提到,在一个程序中多次调用srand 通常是错误的;您的回答可能暗示语言新手他应该每秒srand。
C rand 函数使用种子生成随机数(就像大多数 -- 任何? -- 伪随机生成器一样)。
srand 用于设置随机生成算法使用的种子。 time 返回的值(即:当前秒)通常被传递给这样的函数,因为它是最容易获取的值,通常在应用程序的两次执行之间是不同的
【讨论】:
首先,srand & rand 用于/来自 C,而不是 C++,C++0x 正在引入自己的random number generator classes。
除了srand 和rand 是实现定义的之外,它们只需要传递0 到RAND_MAX 之间的随机数。在windows 上,它是一个基本的MWC16/32,使用TLS 存储种子,srand 设置该种子,然后rand 使用该种子来滚动伪随机数。
通过随机数生成器,它非常糟糕,尤其是 Windows 版本。
【讨论】:
有一个article at Wikipedia 提供了一些很好的历史和使用的算法示例。
简短的版本是rand() 及其同类是伪随机数生成器。事实上,它们实际上是确定性的——产生的数字序列总是相同的。但是,序列非常长,播种机制提供了一种从序列中(或多或少)任意位置开始的方法。
根据随机数的使用方式,有多种标准可用于评估伪随机生成器的质量。在非常简单的情况下,也许只需要从对rand() 的连续调用中重复值的概率很低。但是,您可能还希望这些数字符合特定的统计分布。 (据我所知,大多数 PRNG 会产生均匀分布的数字。但是存在各种函数或可以轻松编写以将其转换为高斯分布或您可能需要的任何其他函数。)
最后,当考虑到安全性时,您需要一种算法,就所有实际目的而言,它是不可预测的。如果攻击者知道之前生成的数字,那么她应该无法预测下一个数字。在非常高安全性的应用程序中,可能会使用真正的随机数生成器;这些将依赖于各种外部随机源,例如无线电静电、图像捕获设备中的热噪声(镜头盖打开)或其他此类源。此外,许多现代操作系统(包括 Linux)从各种来源(例如不可预测的用户交互)收集和存储“熵池”,并允许从中生成随机数。
不习惯使用伪随机生成器的人的一个常见编程错误是在每次调用 rand() 之前重新播种。当然,这是不必要的,而且可能是不可取的。每个生成器只播种一次。
【讨论】:
#include "stdio.h" //rmv coding for srand is pure
#include "conio.h"
#include "time.h"
void main()
{
time_t t;
srand(time(0));
for (i = 1; i <= 10; i++)
cout << (unsigned) rand() % 1000 - 90 << "\t";
for (i = 1; i <= 10; i++)
cout << (char) rand() % 100 - 90 << "\t";
getch();
}
【讨论】: