f(g(x))在一起或分裂的结果不一致

jos*_*ber 34 random r random-seed

最近调查函数中设置随机种子时,我遇到了一个奇怪的情况.考虑功能fg,其中的每一个设置的随机种子,然后执行一个简单的随机操作:

g <- function(size) { set.seed(1) ; runif(size) }
f <- function(x) { set.seed(2) ; x*runif(length(x)) }
Run Code Online (Sandbox Code Playgroud)

因为每个函数都设置了随机种子,所以我希望每个函数在给定相同输入的情况下始终具有相同的返回值.这意味着f(g(2))应该返回相同的东西x <- g(2) ; f(x).令我惊讶的是,事实并非如此:

f(g(2))
# [1] 0.1520975 0.3379658

x <- g(2)
f(x)
# [1] 0.04908784 0.26137017
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?

raw*_*awr 37

这是双缝R实验的一个例子.当观察到x时,它充当粒子; 当没有观察到它时,它就像一个波浪.看哪

g <- function(size) { set.seed(1) ; runif(size) }
f <- function(x) {set.seed(2) ; x*runif(length(x)) }
f2 <- function(x) {print(x); set.seed(2) ; x*runif(length(x)) }

f(g(2))
# [1] 0.1520975 0.3379658

x <- g(2)
f(x)
# [1] 0.04908784 0.26137017


f2(g(2))
# [1] 0.2655087 0.3721239
# [1] 0.04908784 0.26137017

x <- g(2)
f2(x)
# [1] 0.2655087 0.3721239
# [1] 0.04908784 0.26137017
Run Code Online (Sandbox Code Playgroud)

我只是在嘲笑你.print迫使x.你可以明确地做到这一点

f <- function(x) {force(x); set.seed(2) ; x*runif(length(x)) }
x <- g(2)
f(x)
# [1] 0.04908784 0.26137017
Run Code Online (Sandbox Code Playgroud)

但不是这个

f(force(g(2)))
# [1] 0.1520975 0.3379658
Run Code Online (Sandbox Code Playgroud)

  • 大声笑.R中的双缝实验!作为QM的懒惰评估.完善. (6认同)

Jel*_*eir 23

函数的x参数f()仅在函数内部实际使用时进行评估.这意味着在您尝试计算时,在执行函数之前set.seed(2)会对其进行求值.g()f(g(2))

> f(g(2))
[1] 0.1520975 0.3379658
Run Code Online (Sandbox Code Playgroud)

基本上相当于:

> set.seed(2)
> set.seed(1)
> result <- runif(2)
> result*runif(length(result))
[1] 0.1520975 0.3379658
Run Code Online (Sandbox Code Playgroud)