12.4程序生成随机数的方法

接下来,让我们看一下随机数在程序中扮演的角色。在编写游戏程序时,以及在计算机模拟“等情况下,经常使用随机数。随机数也是用程序来表示人类的直觉及念头的一种方法。从代码清单 12-2 的运行结果中大家可以发现,“一直在出石头的时候突然出了一个剪刀”,这确实很像人类的行为方式。

随机数色子(随机数色子的各面上都标有 1~20(或110每两个面为同一个数值)的数值。晃动随机数色子后,就可以得到 1~20(或1~10)的一个随机数。是用来产生随机数的一种工具,每个色子有 20 面晃动随机数色子后,出现在正面的数字就是随机数。由于计算机没法晃动随机数色子,因此程序一般会通过生成类似于随机数的数值公式来得到随机数。在 C语言中,虽然该公式的实体是隐藏的,但只要调用rand0函数,就可以得到结果(随机数)。不过,由于借助公式产生的随机数具有一定的规律性,因此并不是真正的随机数,通常称为伪随机数。不过,虽然是伪随机数(除了线性同余法以外,还有其他获取伪随机数的方法。如可以获得更接近真实随机数”的“乘同余法”、“M系法”以及能够快速生成随机数的“Knuth 减算法”等。,仍然十分有用。

作为参考,这里向大家介绍一个获取伪随机数的公式。该公式称为线性同余法。如果把 Ri作为当前随机数的话,那么下一个出现的随机数 Ri+1,就可以用下面的公式来获取.

公式中出现的 mod,是整除后取余的意思。同 C 语言的 % 运算符的功能是一样的。对a、b、c 各参数设定合适的整数后,可以从该公式获得的随机数的范围就是0到c(不包含)。因为是用c来进行取余所以得到这个范围也是理所当然的。我们不妨做一下尝试,把 a 设定为 5,b设定为3,c设定为 8,获得的随机数就如表 12-3 所示。这里把 Ri的初始值定为了 1。可以看出,这些随机数确实很像是无规则随机出现的数值。不过,产生 8 次随机数后,下8 次产生的随机数就和前面的数值相同了。这种周期性是伪随机数的特征,也是为什么不是真随机数的原因。

C 语言的 rund0 函数中,也肯定通过某些公式生成了伪随机数。假如使用的是线性同余法的话,就需要提前设定 Ri、a、b、c 的数值,为此就要用到代码清单 12-1 及代码清单 12-2中的 srand(time(NULL));srand0 函数中的参数 time(NULL),是用来获取当前时间的参数。以time(NULL)的值为基础,来设定 Ri、a、b、c 的数值。由于每次启动程序时的当前时间都是变化的,因此 Ri、a、b、c 的数值也会随之发生变化。Ri、a、b、c的数值就称为随机数的种子,这一点大家要有个印象。而假如在不运行 srandtime(NULL));的情况下重复调用 rand0 函数的话,会出现什么情况呢?因为 Ri、a、b、c 的数值都有默认值,因此每次都会生成以相同方式出现的随机数。这样一来,游戏以及计算机模拟就都无法成立了。当然也就无法表示人类的思考了。

 

posted @ 2023-02-08 09:20  嘎嘎鸭~  阅读(157)  评论(0)    收藏  举报