8

C++中产生随机数的基础是什么?

这背后有什么逻辑或原则吗?

生成的数字是完全随机的吗?

假设我正在运行这个程序:

#include <iostream.h>
#include <stdlib.h>
#include <time.h>

int main()
{
    /*
    Declare variable to hold seconds on clock.
    */
    time_t seconds;
    /*
    Get value from system clock and
    place in seconds variable.
    */
    time(&seconds);
    /*
    Convert seconds to a unsigned
    integer.
    */
    srand((unsigned int) seconds);
    /*
    Output random values.
    */
    cout<< rand() << endl;
    cout<< rand() << endl;
    cout<< rand() << endl;
    return 0;
}

它显示了什么:http: //img14.imageshack.us/img14/1538/98271820.png

它显示 205 两次。

4

2 回答 2

6

这个问题基本上在评论和另一个答案中得到了回答,但我会把它收集在一个地方。

C++rand()函数产生的不是真正随机的数字序列,而是伪随机序列。这意味着它基本上是一个预定义的“随机”数字序列,但固定在某个地方(实际上,它比这更复杂,但这是为了更好地理解而进行的简化)。把它想象成一长串整数。

每次调用rand()函数都会提取当前数字并将指向“当前“随机”数字”的指针移动到下一个。

srand()函数所做的基本上是将指针设置为列表中的某个位置。如果您不在srand()每次启动时调用该函数,或者使用固定参数(种子)调用它,那么每次程序启动时您将拥有相同的数字序列。

当您从几秒钟开始设置种子时,如果您在那一秒内启动程序两次,您的种子将是相同的 - 因此会产生相同的结果。

试试下面的代码:

#include <windows.h>
// << other code >>
for (int i=0; i<50; i++) {
    time(&seconds);
    srand(seconds);
    cout<< seconds<<" "<<rand()<<endl;
    Sleep(100);
}

您会注意到,每个“秒”值对应于rand()函数的某个固定“第一”值。

于 2013-03-03T17:32:28.373 回答
2

从第二个问题开始:

生成的数字是完全随机的吗?

不,这在计算机中不太可能发生。它们是“伪随机”数字,它是一些数字序列,随着时间的推移以类似随机的方式变化。但是如果你从同一个“种子”开始,你每次都会得到相同的序列。这种可预测性有时非常有用,因为它允许多次重复相同的实验并获得相同的结果——改变种子,将允许类似的运行产生不同的结果。

该函数srand设置种子。有些系统确实有一个名为 的函数randomize,但它不是标准的一部分。如果它确实存在,它将种子设置为代码未知的东西 - 例如以毫秒为单位的当前时间。

这背后有什么逻辑或原则吗?

是的。有几种方法可以生成伪随机数。简单的可以使用常规intlong类型用一两行 C 代码编写,只包括取“当前值”+某个常数,乘以某个大数并取模另一个大数。

更复杂的涉及数十行相当复杂的大量数学 - 例如,Mersenne Twister 是最近的一项工作,如果你稍微搜索一下,它可以作为源代码获得。

于 2013-03-03T17:18:09.477 回答