¿Cómo programar una simulación de Monte Carlo de la paradoja de la caja de Bertrand?

12

El siguiente problema ha sido publicado en la página de Facebook de Mensa International:

ingrese la descripción de la imagen aquí

La publicación en sí recibió más de 1000 comentarios, pero no entraré en detalles sobre el debate allí, ya que sé que esta es la paradoja de Bertrand y la respuesta es . Lo que me interesa aquí es cómo se responde a este problema utilizando un enfoque de Monte Carlo. ¿Cómo es el algoritmo para resolver este problema?23

Aquí está mi intento:

  1. Genere números aleatorios distribuidos uniformemente entre y .0 1N01
  2. Deje que el evento de la caja contenga 2 bolas de oro (casilla 1) seleccionadas, sea menos de la mitad.
  3. Contar los números que menos de y llame el resultado como .0.5S
  4. Dado que es seguro obtener una bola de oro si se selecciona la casilla 1 y solo hay un 50% de posibilidades de obtener una bola de oro si se selecciona la casilla 2, por lo tanto, la probabilidad de obtener una secuencia GG es
    P(B2=G|B1=G)=SS+0.5(NS)

Implementando el algoritmo anterior en R:

N <- 10000
S <- sum(runif(N)<0.5)
S/(S+0.5*(N-S))

La salida del programa anterior es de alrededor de que casi coincide con la respuesta correcta, pero no estoy seguro de que esta sea la forma correcta. ¿Hay una manera adecuada de resolver este problema mediante programación?0.67

Anastasiya-Romanova 秀
fuente

Respuestas:

14

Al igual que @Henry , realmente no creo que tu solución sea un Monte Carlo. Seguramente, muestra de la distribución, pero no tiene mucho que ver con imitar el proceso de generación de datos. Si desea usar Monte Carlo para convencer a alguien de que la solución teórica es correcta, necesitaría usar una solución que imite el proceso de generación de datos. Me imagino que es algo como a continuación:

boxes <- list(
  c(0, 0),
  c(0, 1),
  c(1, 1)
)

count_successes = 0
count_valid_samples = 0

for (i in 1:5000) {
  sampled_box <- unlist(sample(boxes, 1)) # sample box
  sampled_balls <- sample(sampled_box)    # shuffle balls in the box

  if (sampled_balls[1] == 1) {            # if first ball is golden
    if (sampled_balls[2] == 1) {          # if second ball is golden
      count_successes = count_successes + 1
    }
    count_valid_samples = count_valid_samples + 1
  }
}
count_successes / count_valid_samples

o usando el código "vectorizado":

mean(replicate(5000, {       # repeat 5000 times, next calculate empirical probability
  x <- boxes[[sample(3, 1)]] # pick a box
  if (x[sample(2, 1)] == 1)  # pick a ball, check if it is golden
    return(sum(x) == 2)      # check if you have two golden balls in the box
  else
    return(NA)               # ignore if sampled ball is silver
  }), na.rm = TRUE)          # not count if silver

Tenga en cuenta que, dado que condiciona el hecho de que la primera bola ya estaba dibujada y es dorada, el código anterior simplemente podría usar dos cuadros boxes <- list(c(0, 1), c(1, 1))y luego x <- boxes[[sample(2, 1)]]tomar muestras de ellos , por lo que el código sería más rápido ya que no haría el 1/3 carreras vacías que descontamos. Sin embargo, dado que el problema es simple y el código se ejecuta rápidamente, podríamos permitirnos simular explícitamente todo el proceso de generación de datos "para estar seguros" de que el resultado es correcto. Además de eso, este paso no es necesario ya que produciría los mismos resultados en ambos casos.

Tim
fuente
¿ x <- boxes[[sample(3, 1)]]Significa que tomas una caja de 3 cajas? Si es así, ¿por qué es necesario ya que sabemos que ya elegiste una bola de oro?
Anastasiya-Romanova 秀
77
@ Anastasiya-Romanova 秀 en su lugar, puede tomar muestras de dos cuadros boxes <- list(c(0, 1), c(1, 1))y luego x <- boxes[[sample(2, 1)]], pero dado que este es casi el mismo tiempo de cálculo, ¿por qué no usar el paso adicional que se asemeja exactamente al proceso de muestreo? No cambia nada sobre el resultado, pero hace que la simulación sea explícita.
Tim
Muy bien Tim, gracias por tu respuesta. Dame tiempo para entender tu respuesta primero, ya que soy bastante nuevo en R. Por ahora, +1 para ti y @Henry.
Anastasiya-Romanova 秀
1
@ Anastasiya-Romanova 秀 sí, exactamente. El código muestra una caja, luego muestra una bola de la caja, si es dorada (= 1) luego verifica si la otra bola de la caja también es dorada (1 + 1 = 2), en caso afirmativo, la cuenta y al final divide la suma entre el recuento total (es decir, los usos mean).
Tim
1
@ Anastasiya-Romanova 秀return(NA)devuelve el valor perdido y luego mean(, na.rm = TRUE)se usa, donde el na.rm = TRUEargumento le dice a la función que ignore los valores faltantes. En otros lenguajes de programación, esto podría hacerse de manera diferente, por ejemplo, usando continueo passpalabras clave.
Tim
4

Siento que tu S/(S+0.5*(N-S))cálculo no es realmente simulación

Intenta algo como esto

N <- 10^6
ballsinboxes <- c("G","G", "G","S", "S","S")
selectedbox <- sample(c(1,2,3), N, replace=TRUE)
selectedball <- sample(c(1,2), N, replace=TRUE)
selectedcolour <- ballsinboxes[(selectedbox-1)*2 + selectedball ]
othercolour <- ballsinboxes[(selectedbox-1)*2 + 3 - selectedball ]
sum(selectedcolour == "G" & othercolour == "G") / sum(selectedcolour == "G")
Enrique
fuente
-2

¿Por qué no simplemente enumerar los casos?

Aquí: G es para "oro", S es para "plata", el capital es para la extracción inicial:

Gg

gG

Gs

... todos los demás casos invocan una extracción inicial de plata (S) y no satisfacen el condicional (extracción inicial G).

Tal, P (g | G) = 2/3.

ghuezt
fuente
77
La pregunta se refiere a la solución de Monte Carlo.
Tim
Bueno, enumerar TODAS las posibilidades es un caso extremo de Monte Carlo.
ghuezt
44
No, no lo es, Monte Carlo se trata de simulación / aleatorización.
Tim
Tim, haz las matemáticas bien. Con infinitos sorteos, obtienes exactamente una lista de todos los casos con iguales probabilidades. Triste "caso extremo" y significa límite.
ghuezt
1
Claro, pero enumerar todos los casos no es Monte Carlo. El cuadrado es un rectángulo, pero el rectángulo no es un cuadrado.
Tim