一道著名的概率问题的Java解法:电影《决胜21点》里的山羊问题
具体的问题可以看这里:http://zh.wikipedia.org/w/index.php?title=蒙提霍爾問題&variant=zh-cn
电影介绍看这里:
http://zh.wikipedia.org/wiki/決勝21點
我很早之前就听过这个问题。几年前,不知道何故,问过一个朋友,
那个朋友几秒钟后给我的答案是应该再选一次。虽然我的朋友是一个数学天才(被废了的那种),
但我一直不服气。前些时候,看了一个解释,看的时候觉得有点道理;今早起来,又觉是好象不对。
想了一下,为何我不写个程序去模拟一下呢?
于是我写了下面的程序,运行结果是:$ java LotoTest 99999999
PickHit = 33322046, Other = 66677953, Total = 99999999其实,写程序的过程中我已经知道问题在哪里了。对照core同学那个“动手”转载,的确,又一次
证实我们的,至少是小弟本人的大脑并没有进化到思考现代问题的程度。
下面是程序,注释写得很烂,将就些看吧:1 import java.util.*;
2 import static java.lang.System.out;
3
4 public class LotoTest {
5 private static final int PARAM_NUM = 1;
6
7 private static void usage(){
8 out.println("Usage: java -cp <classpath> LotoTest <num>\n");
9 }
10
11 /*
12 * Algorithm:
13 * Giving an Array of 3 boolean, one and only one
14 * of them are true. Randomly pick up a value A.
15 * then the program unveal another one which is not
16 * true. Run the program to determine the possibility
17 * that A is true and the possibility that A
18 * is true.
19 */
20 public static void main(String [] args){
21 if(args.length != PARAM_NUM) {
22 usage();
23 return;
24 }
25
26 int runNum = Integer.valueOf(args);
27
28 //Create three randomizer
29 //One for value setting
30 //One for picking up value
31 //The other for unveal
32 Random ran01 = new Random(new Date().getTime());
33 Random ran02 = new Random(
34 LotoTest.class.hashCode()
35 * ran01.nextLong() * new Date().getTime());
36 Random ran03 = new Random(
37 LotoTest.class.hashCode()
38 * ran02.nextLong()
39 * ran01.nextLong() * new Date().getTime());
40
41 int pickHit = 0;
42
43 for(int runc=0; runc<runNum; ++runc) {
44 //Generate the position to store the true value
45 int pos = (int)(ran01.nextDouble() * 3);
46 //declare and initialize the boolean array to false
47 boolean A[] = new boolean;
48
49 A = true;
50
51 //pick up one position for lucky
52 int pickup = (int)(ran02.nextDouble() * 3);
53
54 //unveal one of the false position
55 int unveal = 0;
56
57 do{
58 unveal = (int)(ran03.nextDouble() * 3);
59 if(unveal == pickup)
60 continue;
61 if(unveal == pos)
62 continue;
63 break;
64 }while(true);
65
66 if(pickup == pos)
67 ++ pickHit;
68
69 }
70
71 out.printf("PickHit = %d, Other = %d, Total = %d\n",
72 pickHit, runNum - pickHit, runNum);
73 }
74 }最后,谨借本文,遥祝那位智商暴棚,但说话不大灵光的朋友一生幸福。 看这个英文的wiki讲的比较好。
http://en.wikipedia.org/wiki/Monty_Hall_problem
我也觉得这个问题很绕,不过我认为普通人会认为绕的原因,其实是因为不习惯用研究概率的方式来想问题。如果能够搞清楚起始和结束的条件,然后老老实实的列举出所有的情况,问题还是比较清楚的。 原帖由 someonehappy 于 9-7-2009 17:07 发表 http://www.freeoz.org/forum/images/common/back.gif
看这个英文的wiki讲的比较好。
http://en.wikipedia.org/wiki/Monty_Hall_problem
我也觉得这个问题很绕,不过我认为普通人会认为绕的原因,其实是因为不习惯用研究概率的方式来想问题。如果能够搞清楚起始和结束 ...
说说我为什么突然之间又觉得不相信那个结果吧。
问题就在于,在一个为false的门被打开后,主持人让你决定是否重新选择。
如果把目光集中在这个地是,那怎样想都是50%的概率。
而我想到的是“刻舟求剑“的故事,因为舟已经动了,条件改变了,我是否应该重新考虑问题呢? 问题的关键就是在这里。你说的50%很对,不过那是建立在一扇门被打开以后的基础上的。而这个原始题目本身是严格的从一开始三扇门的时候开始的,初始条件完全不同,所以这其实是两个题目了。所以有两个答案。
另外我总感觉,概率的数字结果,和人的直观的对问题的感觉经常是不一样的,也许是因为人思考问题往往是从表面或者是比较明显的现状开始,而如果问题比较复杂,步骤比较多,脑子就开始不够使了,就需要一步步写下来分析。分析的多了,抽象总结出来,就成了概率论之类的东西了。
页:
[1]