将f(g(x))一起或分开计算得到的结果不一致

34

最近的一次研究中,我遇到了一个奇怪的情况,涉及函数内部随机种子的设置。考虑函数fg,它们都设置了随机种子,然后执行了一个简单的随机操作:

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

因为每个函数都设置了随机种子,所以我期望每个函数在给定相同的输入时总是具有相同的返回值。这意味着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

这里发生了什么?

2个回答

37

这是双缝实验的一个例子。当观察到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

我只是在开玩笑。 print 强制执行了 x。你可以显式地这样做。

我只是跟你开个玩笑。使用 print 命令会强制执行 x,但你也可以通过显式命令来完成同样的操作。

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

但不是这个

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

6
LOL。R中的双缝实验。惰性求值作为量子力学。完美。 - IRTFM
1
很好地将 josliber 用作动词。 - Joseph Wood
@JosephWood 我喜欢认为所有的点赞都是为了那个。 - rawr

24

f()函数的x参数只有在函数内部实际使用时才被评估。这意味着当您尝试计算f(g(2))时,在执行g()函数之前就会评估set.seed(2)

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

基本上等同于:

> set.seed(2)
> set.seed(1)
> result <- runif(2)
> result*runif(length(result))
[1] 0.1520975 0.3379658

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接