找回密码
 FreeOZ用户注册
查看: 2128|回复: 3
打印 上一主题 下一主题

[论坛技术] 一道著名的概率问题的Java解法:电影《决胜21点》里的山羊问题

[复制链接]
跳转到指定楼层
1#
发表于 9-7-2009 11:12:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?FreeOZ用户注册

x
具体的问题可以看这里:
http://zh.wikipedia.org/w/index. ... }&variant=zh-cn
电影介绍看这里:
http://zh.wikipedia.org/wiki/決勝21點

我很早之前就听过这个问题。几年前,不知道何故,问过一个朋友,
那个朋友几秒钟后给我的答案是应该再选一次。虽然我的朋友是一个数学天才(被废了的那种),
但我一直不服气。前些时候,看了一个解释,看的时候觉得有点道理;今早起来,又觉是好象不对。
想了一下,为何我不写个程序去模拟一下呢?

于是我写了下面的程序,运行结果是:
  1. $ java LotoTest 99999999
  2. PickHit = 33322046, Other = 66677953, Total = 99999999
复制代码
其实,写程序的过程中我已经知道问题在哪里了。对照core同学那个“动手”转载,的确,又一次
证实我们的,至少是小弟本人的大脑并没有进化到思考现代问题的程度。

下面是程序,注释写得很烂,将就些看吧:
  1.   1 import java.util.*;
  2.   2 import static java.lang.System.out;
  3.   3
  4.   4 public class LotoTest {
  5.   5     private static final int PARAM_NUM = 1;
  6.   6
  7.   7     private static void usage(){
  8.   8         out.println("Usage: java -cp <classpath> LotoTest <num>\n");
  9.   9     }
  10. 10
  11. 11     /*
  12. 12      * Algorithm:
  13. 13      *   Giving an Array of 3 boolean, one and only one
  14. 14      *   of them are true. Randomly pick up a value A[x].
  15. 15      *   then the program unveal another one which is not
  16. 16      *   true. Run the program to determine the possibility
  17. 17      *   that A[x] is true and the possibility that A[rest]
  18. 18      *   is true.
  19. 19      */
  20. 20     public static void main(String [] args){
  21. 21         if(args.length != PARAM_NUM) {
  22. 22             usage();
  23. 23             return;
  24. 24         }
  25. 25
  26. 26         int runNum = Integer.valueOf(args[0]);
  27. 27
  28. 28         //Create three randomizer
  29. 29         //One for value setting
  30. 30         //One for picking up value
  31. 31         //The other for unveal
  32. 32         Random ran01 = new Random(new Date().getTime());
  33. 33         Random ran02 = new Random(
  34. 34             LotoTest.class.hashCode()
  35. 35             * ran01.nextLong() * new Date().getTime());
  36. 36         Random ran03 = new Random(
  37. 37             LotoTest.class.hashCode()
  38. 38             * ran02.nextLong()
  39. 39             * ran01.nextLong() * new Date().getTime());
  40. 40
  41. 41         int pickHit = 0;
  42. 42
  43. 43         for(int runc=0; runc<runNum; ++runc) {
  44. 44             //Generate the position to store the true value
  45. 45             int pos = (int)(ran01.nextDouble() * 3);
  46. 46             //declare and initialize the boolean array to false
  47. 47             boolean A[] = new boolean[3];
  48. 48
  49. 49             A[pos] = true;
  50. 50
  51. 51             //pick up one position for lucky
  52. 52             int pickup = (int)(ran02.nextDouble() * 3);
  53. 53
  54. 54             //unveal one of the false position
  55. 55             int unveal = 0;
  56. 56
  57. 57             do{
  58. 58                 unveal = (int)(ran03.nextDouble() * 3);
  59. 59                 if(unveal == pickup)
  60. 60                     continue;
  61. 61                 if(unveal == pos)
  62. 62                     continue;
  63. 63                 break;
  64. 64             }while(true);
  65. 65
  66. 66             if(pickup == pos)
  67. 67                 ++ pickHit;
  68. 68
  69. 69         }
  70. 70
  71. 71         out.printf("PickHit = %d, Other = %d, Total = %d\n",
  72. 72             pickHit, runNum - pickHit, runNum);
  73. 73     }
  74. 74 }
复制代码
最后,谨借本文,遥祝那位智商暴棚,但说话不大灵光的朋友一生幸福。
回复  

使用道具 举报

2#
发表于 9-7-2009 18:07:45 | 只看该作者
看这个英文的wiki讲的比较好。
http://en.wikipedia.org/wiki/Monty_Hall_problem

我也觉得这个问题很绕,不过我认为普通人会认为绕的原因,其实是因为不习惯用研究概率的方式来想问题。如果能够搞清楚起始和结束的条件,然后老老实实的列举出所有的情况,问题还是比较清楚的。
回复  

使用道具 举报

3#
 楼主| 发表于 9-7-2009 18:14:37 | 只看该作者
原帖由 someonehappy 于 9-7-2009 17:07 发表
看这个英文的wiki讲的比较好。
http://en.wikipedia.org/wiki/Monty_Hall_problem

我也觉得这个问题很绕,不过我认为普通人会认为绕的原因,其实是因为不习惯用研究概率的方式来想问题。如果能够搞清楚起始和结束 ...


说说我为什么突然之间又觉得不相信那个结果吧。
问题就在于,在一个为false的门被打开后,主持人让你决定是否重新选择。
如果把目光集中在这个地是,那怎样想都是50%的概率。
而我想到的是“刻舟求剑“的故事,因为舟已经动了,条件改变了,我是否应该重新考虑问题呢?
回复  

使用道具 举报

4#
发表于 10-7-2009 13:57:53 | 只看该作者
问题的关键就是在这里。你说的50%很对,不过那是建立在一扇门被打开以后的基础上的。而这个原始题目本身是严格的从一开始三扇门的时候开始的,初始条件完全不同,所以这其实是两个题目了。所以有两个答案。

另外我总感觉,概率的数字结果,和人的直观的对问题的感觉经常是不一样的,也许是因为人思考问题往往是从表面或者是比较明显的现状开始,而如果问题比较复杂,步骤比较多,脑子就开始不够使了,就需要一步步写下来分析。分析的多了,抽象总结出来,就成了概率论之类的东西了。
回复  

使用道具 举报

您需要登录后才可以回帖 登录 | FreeOZ用户注册

本版积分规则

小黑屋|手机版|Archiver|FreeOZ论坛

GMT+11, 15-12-2024 09:14 , Processed in 0.036988 second(s), 20 queries , Gzip On, Redis On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表