Quien no ha visto ese concurso donde hay un solo premio detras de 3 puertas las otras 2 con Cabras u Ovejas...
(http://imgs.mx/i/OG)
La opción adecuada es siempre "cambiar" de puerta cuando te pregunten si te quieres cambiar de la misma..
El programa simula 10 Millones de Juegos 2 veces, en la primera ronda el jugador siempre cambia de puerta y en la segunda ronda el jugador nunca cambia de puerta.
Se demuestra que se tiene 66.6% de probabilidad de ganar si se cambia de puerta, contra 33.3% de probabilidad de ganar si no se cambia de puerta.
#include<stdio.h>
#include<stdint.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
#define GOAT 0 //CABRA 0
#define PRIZE 1 //PREMIO 1
#define MAX_SIMULATIONS 10000000
int main() {
/*unsigned char */
uint8_t position = 0; //Posicion del premio
uint8_t selected = 0; //Posicion seleccionada por el jugado
uint8_t doors[3]; //Puertas
uint8_t can_switch = 0; //La puerta a la cual se puede cambiar
register uint32_t count_win = 0;
register uint32_t simulations = 0;
memset(doors
,GOAT
,sizeof(uint8_t)*3); //Todas las puertas son Cabras //< 10000000
while(simulations < MAX_SIMULATIONS) {
position
= rand() % 3; //position del Premio Pseudo-Aleatoria doors[position] = PRIZE; //Guardamos el premio en la position antes seleccionada
selected
= rand() % 3; //position elejida por el Jugador
switch(selected) { //En base a lo elejido por el jugador
//El encargado del juego valida que puerta tiene otra Cabra y la destapa
//Dandole la oportunida al jugador de cambiar su puerta por la puerta restante
case 0: //Puerta 0 elejida por el Jugador
if(doors[1] == GOAT) { //Si otra puerta 1 Tiene cabra entonces
can_switch = 2; //Le damos la oportunidad de elegir entre la puerta 0 y la puerta 2
}
else { //Caso contrario
can_switch = 1; //Le damos la opotunidad de elegir entre la puerta 0 y la puerta 1
}
break;
case 1: //Repetimos en caso de que seleccione la puerta 1
if(doors[2] == GOAT) {
can_switch = 0;
}
else {
can_switch = 2;
}
break;
case 2: //Repetimos en caso de que seleccione la puerta 2
if(doors[0] == GOAT) {
can_switch = 1;
}
else {
can_switch = 0;
}
break;
}
if(doors[can_switch] == PRIZE) { //Evaluamos si la puerta elejida tiene el premio
count_win++; //Si es asi incrementamos el contador de premios
}
doors[position] = GOAT; //0 //Restablecemos la puerta con premio nuevamente a Cabra
simulations++; //Incrementamos el contador de Simulaciones
}
//Imprimimos totales
printf("Total simulations with change %u, win: %u rate: %f\n",simulations
,count_win
,(float)((float)count_win
/(float)simulations
));
count_win = 0; //Restablecemos contador de premios a 0
simulations = 0; //Restablecemos contador de simulaciones a 0
//Como en la siguiente similacion el jugador no cambiara de puerta no es necesario evaluar las otras puertas
while(simulations < MAX_SIMULATIONS) {
doors[position] = PRIZE;
if(doors[selected] == PRIZE) {
count_win++;
}
doors[position] = GOAT; //0
simulations++;
}
printf("Total simulations without change %u, win: %u rate: %f\n",simulations
,count_win
,(float)((float)count_win
/(float)simulations
)); return(0);
}
Descripción del problema:
https://en.m.wikipedia.org/wiki/Monty_Hall_problem
Salida del codigo arriba mostrado:
Total simulations with change 10000000, win: 6665613 rate: 0.666561
Total simulations without change 10000000, win: 3335076 rate: 0.333508
Saludos!