Я пытаюсь смоделировать проблему Монти Холла в теории вероятностей, используя R. Если вы не знакомы, проблема выглядит следующим образом:
Участник на игровом шоу и ему говорят, чтоприз находится за одной из трех дверей.Их просят угадать дверь.Отгадав дверь, хозяин (он же Монти Холл) открывает дверь, в которой нет приза, чтобы помочь участнику.Затем участнику разрешается изменить свое предположение от своей первоначальной двери до другой двери, которая все еще закрыта.Хотя это и не интуитивно понятно, вероятность того, что участник выиграет приз, будет больше, если он изменит свое предположение.
Я выяснил, как смоделировать задачу, используя циклы for
в R, но код оченьмедленно, когда я использую миллионы итераций.Я пытался векторизовать код и столкнулся с проблемой при попытке векторизации функции %in%
в R. Мне было интересно, знает ли кто-нибудь как.Я только показываю свой код для основного раздела, который я не могу векторизовать.Он идентифицирует дверь, на которую участник может изменить свою догадку.
for (i in 1:f) {
change[i] <- doors[i, !(doors[i, ] %in% c(guess[i], open[i]))]
}
f
- это число итераций в симуляции (или число случайных участников). doors
- это матрица с f
строками, каждый из которых равен c(1, 2, 3)
, что соответствует трем дверям в игре. guess
- исходное предположение участника. open
- это дверь, которую открыл хозяин. change
- это дверь, на которую участник может изменить свое предположение.
Вот полный коддля тех, кому интересно:
# MONTY HALL PROBABILITY PROBLEM SIMULATION ####
montyHall <- function(f = 100, change = TRUE) {
# randoms
option <- matrix(data = rep.int(x = c(1, 2, 3), times = f),
nrow = f, ncol = 3, byrow = TRUE)
correct <- sample.int(n = 3, size = f, replace = TRUE)
guess <- sample.int(n = 3, size = f, replace = TRUE)
result <- data.frame("correct" = correct, "guess" = guess)
# door selection
temp <- vector(mode = "list", length = f)
result[, "door"] <- rep.int(x = -999, times = f)
for (i in 1:f) {
temp[[i]] <- option[i, !(option[i, ] %in% c(result[i, "correct"], result[i, "guess"]))]
if (length(temp[[i]]) == 1) {result[i, "door"] <- temp[[i]]}
if (length(temp[[i]]) == 2) {result[i, "door"] <- sample(x = temp[[i]], size = 1)}
}
# change door
result[, "change"] <- rep.int(x = NA, times = f)
for (i in 1:f) {
result[i, "change"] <- option[i, !(option[i, ] %in% c(result[i, "guess"], result[i, "door"]))]
}
# outcomes
if (change == FALSE) {
result[, "win"] <- ifelse(result[, "guess"] == result[, "correct"],
yes = 1, no = 0)
}
if (change == TRUE) {
result[, "win"] <- ifelse(result[, "change"] == result[, "correct"],
yes = 1, no = 0)
}
if (!is.logical(change)) {
stop("the change argument must be logical")
}
win <- sum(result[, "win"], na.rm = FALSE)
# if win = NA then something went wrong
# output
output <- round(x = win / i, digits = 2)
return(output)
}
montyHall(f = 1000000, change = FALSE)
montyHall(f = 1000000, change = TRUE)