Big Fish

2009-06-05

概率问题(续)

昨天说的那个概率问题其实叫Monty Hall problem。昨天给的那个结果其实依赖于一个前提,就是主持人故意选择打开了有山羊的一个门。如果主持人只是随机/偶然/不小心打开了有山羊的一个门,这个问题叫做Monty Fall problem。在这种情况下,程序模拟的结果是这样的:

fishy@localhost:~/work/test$ ./test 100000
CHANGE
*** right on 22096 out of 44359, 49.81% ***
NO CHANGE
*** right on 22198 out of 44412, 49.98% ***
fishy@localhost:~/work/test$ ./test 1000000
CHANGE
*** right on 222412 out of 444576, 50.03% ***
NO CHANGE
*** right on 221543 out of 444252, 49.87% ***
fishy@localhost:~/work/test$ ./test 10000000
CHANGE
*** right on 2219600 out of 4441565, 49.97% ***
NO CHANGE
*** right on 2222900 out of 4446490, 49.99% ***

这种情况的结果是换不换都是1/2。

程序如下:

 1 #include <stdio.h>
 2 #include <time.h>
 3 #include <stdlib.h>
 4
 5 typedef int changefunc(int, int);
 6
 7 int change(int guess, int show) {
 8         return 0+1+2 - guess - show;
 9 }
10
11 int nochange(int guess, int show) {
12         return guess;
13 }
14
15 void loop(int times, changefunc func, int print) {
16         int i, n, t;
17         n = 0;
18         t = 0;
19         for(i=0;i<times;i++) {
20                 int target = rand() % 3;
21                 int guess = rand() % 3;
22                 int show = rand() % 3;
23                 int finalguess;
24                 if(show == target)
25                         continue;
26                 if(show == guess)
27                         continue;
28                 t++;
29                 finalguess = func(guess, show);
30                 if(print)
31                         printf("guess %d, show %d, changed to %d, result is %d\n", guess, show, finalguess, target);
32                 if(target == finalguess) n++;
33         }
34         printf(" *** right on %d out of %d, %.2f%% ***\n", n, t, ((double)n)/t*100);
35 }
36
37 int main(int argc, char **argv) {
38         if(argc <= 1)
39                 return -1;
40         int times = atoi(argv[1]);
41         int print = (argc >= 3);
42         srand(time(0));
43         // change
44         printf("CHANGE\n");
45         loop(times, change, print);
46         // no change
47         printf("NO CHANGE\n");
48         loop(times, nochange, print);
49         return 0;
50 }

为什么两种情况下会不一样呢?原因是两种情况下,主持人开门的概率是不一样的。这里有个详细的证明。

不过在这两种情况下,换的结果都不会差于不换的结果,所以总之还是应该换。

12:40:52 by fishy - Permanent Link

May the Force be with you. RAmen