用随机数发生器来验证一个有趣的概率问题

有一道流传颇广的有趣的概率题,说的是某直播节目现场,嘉宾面对三扇门,其中一扇门后有大奖,另两个是空的,主持人让嘉宾选一个。选了之后,主持人在剩下的俩个门中打开一扇,后面是空的(他知道哪个是空的),然后问嘉宾要不要换选择?那么换好还是不换好呢?凭直觉的话,虽然打开了一扇空门,但你面对剩下的两扇门仍然不知道哪个有奖品,所以概率一样,在此情况下人们往往会坚持自己的最初选择,即不换。但实际上选择换的话中奖率会大一倍。这题看上去违反直觉,很难理解,所以我决定自己写一段代码试试。

事实证明——在地铁上用手机写代码挺费劲儿的。不过还是验证了这个结论,事实上代码写出来就已经能看出结果来了。代码用js, 我们假设Math.random函数可以生成平均分布的结果,即能模拟三个盒子哪个盒子有奖是完全随机地,概率一样。
先看看代码清单一

let c=0;
const n=1000;
for(let i=0;i<n;i++){
  const h = Math.floor(Math.random()*3);
  h==1 && c++;
}
console.log(c/n);

首先我们可以用这段代码来验证Math.random函数产生的随机结果的分布情况是不是符合近似平均分布的要求:Math.random()将随机产生0~1之间的值,再乘以3就是0~3的值,如果平均分布,那么落在1~2之间的概率应该是三分之一。来看看我的几次运行结果:0.328, 0.335, 0.342。基本在0.333附件可算作符合要求。
同时这段代码也可以用来模拟嘉宾不换选择的情况下中奖的概率:假设有0,1,2三个门,由“Math.floor(Math.random()*3)”这个函数来随机生成哪个门后有奖品。而嘉宾选择的是1号门。我们可以看到基本上选一千次的话确实有大约三分之一的概率中奖。

那么如何模拟嘉宾看到空门后改变主意的情况呢?再来看看代码清单二:
代码清单二

let c=0;
const n=1000;
for(let i=0;i<n;i++){
  const h = Math.floor(Math.random()*3);
  if(h==0) c++;
  if(h==1) ;//fail
  if(h==2) c++;
}
console.log(c/n);

我们还是假设最初嘉宾选的1号门(因为哪个门后有奖都是随机的,所以选几号门不影响结果)。然后因为主持人打开一扇空门,这里分三种情况:

  1. 大奖在0号门后,嘉宾初选1号门,主持人打开的空门是2号,然后嘉宾改变主意的话只能选0号门,中奖!
  2. 大奖在1号门后,嘉宾初选也是1号门,主持人随便打开哪个门,嘉宾改主意的话必败。
  3. 大奖在2号门后,类似第一种情况,嘉宾初选1号门,主持人打开的空门是0号,然后嘉宾改变主意的话只能选2号门,中奖!
    讲到这里大家其实已经可以看出,因为大奖在0,1,2号门后的概率相同,都是三分之一,所以嘉宾改变主意的话,除非他一开始就选中了有奖的门,其他两种情况他都会中奖。所以嘉宾改主意的话中奖概率是三分之二,比起不改主意正好大了一倍。
    来看看实验结果,三次实验结果是:0.664,0.648, 0.676 符合预期。

从上面的例子我们可以看到,利用随机数发生器是可以验算某些概率问题的。甚至可以在我们本身没想明白的时候来试探出一个接近正确的概率答案来。本文中的实验结果和真实概率略有差别,这是因为我们实验的次数不够大,只有1000,所以最大一次有1.6%的误差。想要精确一点也容易,概率论告诉我们,如果试验的次数多,结果就会逐渐逼近计算出来的概率。比如我们把次数提高100倍到十万次。那么结果是0.33441, 0.33473,0.33475。误差小了一个数量级。

发布了20 篇原创文章 · 获赞 9 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/time1812/article/details/99195529