0

我正在编写蒙蒂霍尔问题的变体,建立在另一个人的代码之上。不同之处在于,我有“n”个门,而不是 3 个门。n = 4就这个问题来说吧。门上有标签A, B, C and D

代码如下:

n <- 4
doors <- LETTERS[seq( from = 1, to = n )]
xdata = c()
for(i in 1:10000) {
    prize <- sample(doors)[1]
    pick  <- sample(doors)[1]
    open1 <- doors[which(doors != pick & doors != prize)]
    open  <- sample(open1,n-2)

    # the line with the problem
    switchyes <- doors[which( doors != open & doors != pick)]

    if(pick==prize) {
        xdata <- c(xdata, "noswitchwin")
    }
    if(switchyes==prize) {
        xdata=c(xdata, "switchwin")
    }
}

当我运行代码时,我收到警告:

There were 50 or more warnings (use warnings() to see the first 50)

问题似乎是由于该行:

switchyes <- doors[which( doors != open & doors != pick)]

这应该只返回 1 个项目 ( C),因为声明doors != opendoors != pick消除了门ABD。但是,我得到的不止一个,B而且C. 有人看到发生了什么吗?

length(which(xdata == "switchwin"))
# [1] 4728
length(which(xdata == "noswitchwin"))
# [1] 2424
switchyes
# [1] "B" "C"
open
# [1] "B" "D"
open1
# [1] "B" "D"
pick
# [1] "A"
prize
# [1] "C"
4

1 回答 1

2

!=您遇到的问题是LHS 和 RHS 大小不同时的用法:

p <- letters[1:4] 
# [1] "a" "b" "c" "d"

q <- c("a", "e", "d", "d")
# [1] "a" "e" "d" "d"

p == q
# [1]  TRUE FALSE FALSE  TRUE

p != q
# [1] FALSE  TRUE  TRUE FALSE

怎么了?因为pq大小相等,所以将 的每个元素p与 的对应索引处的值进行比较q。现在,如果我们改成q这样:

q <- c("b", "d")

p == q
# [1] FALSE FALSE FALSE  TRUE

这里发生了什么事?由于q(RHS)的长度不等于 p(LHS),q因此被回收以达到 的长度p。那是,

# p    q  p    q
  a == b, b == d # first two comparisons
  c == b, d == d # recycled comparisons

相反,您应该使用

!(doors %in% open) & !(doors %in% pick). 

此外,通过注意到!A AND !B = !(A OR B). 因此,您可以将其重写为

!(doors %in% open | doors %in% pick)

反过来,这可以简化为仅使用一个%in%

!(doors %in% c(open, pick))

此外,您可以使用Negate, 说%nin%(对应于)创建一个函数,并将上述语句中的!(x %in% yand 替换为如下:!%in%

`%nin%` <- Negate(`%in%`)
doors %nin% c(open, pick) # note the %nin% here

所以基本上你的声明分配给switchyes可以只是:

# using %bin% after defining the function
switchyes <- doors[doors %nin% c(open, pick)]

你不需要在which这里使用,因为你不是在寻找索引。你可以直接使用这里的逻辑来得到结果。希望这可以帮助。

于 2013-03-31T11:03:59.573 回答