像计算机这类完全按逻辑运行的机器是如何生成随机数的?
计算机有两种方式可以生成随机数:
- 您可以制造某种设备,用其监视完全随机的自然事件,然后将事件结果发送给计算机。例如,您可以在盖革计数器前放置一片放射性物质,并将盖革计数器连接到计算机。因为放射性衰变是随机的,所以盖革计数器将生成真正的随机数。这种方法的使用很罕见,因为并没有太多人在自己的计算机上连有盖革计数器。
- 您可以建立一个公式,用于生成伪随机数。设计公式时,其核心思想就是生成一串数,让任何不知道该公式的人都认为这些数是随机数。好的公式具有以下特点:
- 没有重复:序列不会循环出现和重复自己。
- 良好的数值分布区间:如果公式要生成0到9之间的随机数,那么在一段较长时间内,它生成的0、1、2等数字的个数应大致相等。
- 没有可预见性:除非知道公式和种子(初始数),否则无法预知下一个数。
以下是一个简单的随机数公式示例,摘自Kernighan与Ritchie合著的《C编程语言》一书:
int rand()
{
random_seed = random_seed * 1103515245 + 12345;
return (unsigned int)(random_seed / 65536) % 32768;
}
有关C编程语言的更多信息,请参见C语言入门教程。
这个公式假定存在一个称为random_seed的变量,它最初被设置为某个数值。将random_seed变量乘以1,103,515,245,再将乘积加上12,345;然后,random_seed被此新值取代。这确实是一个非常优秀的伪随机数生成程序。它具有良好的分布区间,且没有重复。如果用它来生成0到9之间的随机数,若种子为10,则它生成的前20个值如下:
4
4
6
0
7
4
2
3
5
0
5
6
6
4
5
6
7
6
7
4
如果让它生成10,000个0到9之间的值,则分布区间如下:
0-1015
1-1024
2-1048
3-996
4-988
5-1001
6-996
7-1006
8-965
9-961
任何伪随机数公式都依靠种子值来开始序列。如果以同一个种子开始,那将从公式中得到相同的值序列。所以,如果在一台计算机上赋予上面显示的rand()函数种子10,然后观察它生成的数列,此数列应与在另一台计算机上,以种子10运行此公式所生成的数列完全相同。在全球定位系统中,就是利用这种可再现性为每颗卫星赋予一个可预知但各自不同的值分布,以便GPS接收器进行跟踪。
要创建随机、不可预知的序列,种子必须是一个真正的随机数。为获得这种真正的随机数作为种子,大多数程序使用转换成整数值的当前日期和时间。例如,转换成自1970年1月1日以来所流逝的秒数。因为每次启动程序时这个数都不同,所以它能生成一个好种子。
[责任编辑:小敏]