概率问题(续)
昨天说的那个概率问题其实叫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 }
为什么两种情况下会不一样呢?原因是两种情况下,主持人开门的概率是不一样的。这里有个详细的证明。
不过在这两种情况下,换的结果都不会差于不换的结果,所以总之还是应该换。