R语言seed问题

来源:互联网 发布:计算机java编程入门 编辑:程序博客网 时间:2024/05/17 02:56

此文源自网上http://cos.name/cn/topic/15925,未经验证,请慎用!

set.seed(3000),不是运行3000次,而是把种子设置为3000。


计算机的程序,都是通过确定的算法,根据确定的输入,算出确定的输出。想要得到真正的随机,需要通过外接物理随机数发生器,通过把随机的物理过程转变为随机值,才能实现。因此我们平常使用的计算机的随机数,其实都只是通过算法模拟得到,也就是伪随机。一般采用的办法是线性同余(参见http://en.wikipedia.org/wiki/Linear_congruential_generator)。

X[n+1] = (a * X[n] + c) mod m
为简单起见,我取简单的参数(a = 1, c = 3, m = 5),得到一个简单的算式:
X[n+1] = (X[n] + 3) mod 5
这时,把X[0]视为种子,于是:
若种子为0,得到数列:0, 3, 1, 4, 2, 0, ...
若种子为1,得到数列:1, 4, 2, 0, 3, 1, ...
若种子为2,得到数列:2, 0, 3, 1, 4, 2, ...
若种子为3,得到数列:3, 1, 4, 2, 0, 3, ...
若种子为4,得到数列:4, 2, 0, 3, 1, 4, ...

对于每个种子,所得到的数列看起来都是随机的(每个数值出现的频率都是相同的)。而一旦种子给定,每次调用随机数函数,函数都会根据上次得到的数列的某个值,计算出数列的下一个值并返回回来。而对于随机浮点数,一般是用随机产生的整数除以最大整数得到。

所以,随机数的种子一般只需要在调用随机函数之前设置一次,不建议设置多次。

另外,我一直没有搞明白一件事:设置多次种子,在算法上会不会对最终生成的随机数的分布造成影响?不知道有人了解么?


这恰恰就是种子最重要的作用。比如说你写了一段程序发给别人看,程序中要生成一系列随机数,如果你不设置随机数种子,那么别人运行你的程序时,生成的随机数就会与你的不同,得到的结果也就可能与你不同,这样就没有办法重复及验证你的结果。在这种情况下就必须设置随机数种子,从而可以重复你的程序结果。


# x: the random vector;
# FUN: the function that generates random numbers with the first argument
#      being the length of random numbers
# seed: candidate seeds to be tried one by one
# ...: other arguments to be passed to FUN
find.seed = function(xFUN = rnormseed = 0:10000...) {
    res = NULL
    for (i in seed) {
        set.seed(i)
        rx = FUN(length(x), ...)
        # all() can be changed to all.equal() to obtain a rough solution
        #     allowing a little bit numeric errors
        if (all(x == rx)) {
            res = i
            break
        }
    }
    res
}


set.seed(1)
test = rnorm(30)
find.seed(test)
[11
set.seed(1234)
test = rnorm(30)
find.seed(test)
[11234
set.seed(987)
test = runif(30min = -1max = 2)
find.seed(testrunifmin = -1max = 2)
[1987

0 0