Python使用random和tertools模块解一些经典概率问题


Posted in Python onJanuary 28, 2015

random 模块中的常用函数

random()

返回一个位于区间 [0,1] 内的实数;

uniform(a, b)

返回一个位于区间 [a,b] 内的实数;

randint(a, b)

返回一个位于区间 [a,b] 内的整数;

choice(sequence)

返回一个位于 sequence 中的元素,其中,sequence 为一个有序序列,如 list、string 或者 tuple 等类型;

randrange([start], stop[, step])

等效于 choice(range([start], stop[, step]));

shuffle(sequence [, random])

无返回值,用于打乱 sequence 中元素的排列顺序;

sample(sequence, n)

返回一个由 n 个 sequence 中的元素组成的分片,其中,sequence 也可以是 set 类型。

利用 itertools 得到排列、组合

permutations(sequence, k))

从序列 sequence 中得到包含 k 个元素的所有排列。
combinations(sequence, k))

从序列 sequence 中得到包含 k 个元素的所有组合。

羊车门问题

有一个抽奖节目,台上有三扇关闭的门,一扇门后面停着汽车,其余门后都是山羊,只有主持人知道每扇门后面是什么。参赛者可以选择一扇门,在开启它之前,主持人会开启另外一扇门,露出门后的山羊,然后允许参赛者更换自己的选择。问题是:参赛者更换选择后能否增加赢得汽车的机会?

有很多时候,我们并不知道自己的理论分析正确与否,但如果知道概率论中的 大数定律,又碰巧懂一点编程,无疑可以利用计算机重复模拟事件以求解问题。该问题的 Python 3.x 解答程序如下:

from random import *
def once(doors = 3):  # 一次事件的模拟

 car = randrange(doors) # 一扇门后面停着汽车

 man = randrange(doors) # 参赛者预先选择一扇门

 return car == man # 参赛者是否最初就选择到车
h = 0 # 坚持选择赢得汽车的次数                    

c = 0 # 改变选择赢得汽车的次数 

times = int(1e6) # 重复实验的次数
for i in range(times): 

 if once(): h += 1

 else:  c += 1
print("维持选择:",h/times*100,"%\n改变选择:",c/times*100,"%")

运行结果:

维持选择: 33.268 %
改变选择: 66.732 %

扑克牌问题

概率论给我们带来了很多匪夷所思的反常结果,条件概率尤其如此。譬如:

四个人打扑克,其中一个人说,我手上有一个 A。请问他手上有不止一个 A 的概率是多少?
四个人打扑克,其中一个人说,我手上有一个黑桃 A。请问他手上有不止一个 A 的概率又是多少?

from random import *
cards = [i for i in range(52)]

counter = [0, 0, 0, 0]
def once(): # 0 表示黑桃 A

 global cards

 ace = set(sample(cards, 13)) & {0,1,2,3}

 return len(ace), 0 in ace
for i in range(int(1e6)):

 a, s = once() # a 表示 A 的个数, s 表示是否有黑桃 A

 if a:

  counter[1] += 1

  if s: counter[3] += 1

 if a > 1:

  counter[0] += 1

  if s: counter[2] += 1
print('情况一:', counter[0]/counter[1], '\n情况二:', counter[2]/counter[3])

运行结果:

情况一: 0.3694922900321386
情况二: 0.5613778028656186

有趣的事情出来了:如果这个人宣布了手中 A 的花色,他手中持有多个 A 的概率竟然会大大增加。可这又该如何理解呢?

一个家庭中有两个小孩,已知其中一个是女孩,求另一个小孩也是女孩的概率

网络上每一次有人发帖提出与条件概率有关的悖论时,总会引来无数人的围观和争论,哪怕这些问题的实质都是相同的。本题目无疑是争论的最多的问题之一。

说起来网上的分析都像模像样,一些原本都迷糊的人被人讲的晕头转向,一会觉得这个对,一会又觉得那个对。现在我不给你分析那些道理,就用计算机来模拟问题,让你直接得到结论,而毋须明白个中缘由。

from random import * # 0 表示女孩,1 表示男孩
family = (lambda n :[{randrange(2),randrange(2)} for i in range(n)])(int(1e6))
both = family.count({0}) # 都是女孩的家庭数

exist = len(family) - family.count({1}) # 有女孩的家庭数
print(both/exist)

运行结果:
0.33332221770186543

没有那些深奥的分析过程,寥寥数行代码就得到了问题的答案,想必这也是计算机引入数学计算与证明的好处。

生日悖论

每个人都有生日,偶尔会遇到与自己同一天过生日的人,但在生活中这种缘分似乎并不常有。我们猜猜看:在 50 个人当中出现这种缘分的概率有多大,是 10%、20% 还是 50%?

from random import *
counter, times = 0, int(1e6)

for i in range(times):

 if len({randrange(365) for i in range(50)}) != 50: # 存在同一天生日的人

  counter += 1
print('在 50 个人中有相同生日的概率为:',counter/times)

运行结果:
在 50 个人中有相同生日的概率为: 0.970109

在 50 个人中有相同生日的概率高达 97%,这个数字恐怕高出了绝大多数人的意料。我们没有算错,是我们的直觉错了,科学与生活又开了个玩笑。正因为计算结果与日常经验产生了如此明显的矛盾,该问题被称为「生日悖论」,它体现的是理性计算与感性认识的矛盾,并不引起逻辑矛盾,所以倒也算不上严格意义上的悖论。
Python 相关文章推荐
python中学习K-Means和图片压缩
Nov 20 Python
Python学习之用pygal画世界地图实例
Dec 07 Python
python2.7读取文件夹下所有文件名称及内容的方法
Feb 24 Python
使用anaconda的pip安装第三方python包的操作步骤
Jun 11 Python
flask框架实现连接sqlite3数据库的方法分析
Jul 16 Python
​如何愉快地迁移到 Python 3
Apr 28 Python
django创建超级用户过程解析
Sep 18 Python
Python Collatz序列实现过程解析
Oct 12 Python
python实现ftp文件传输功能
Mar 20 Python
python实现图书馆抢座(自动预约)功能的示例代码
Sep 29 Python
详解python日志输出使用配置文件格式
Feb 10 Python
python ConfigParser库的使用及遇到的坑
Feb 12 Python
Python中的异常处理学习笔记
Jan 28 #Python
Python中集合类型(set)学习小结
Jan 28 #Python
Python中使用装饰器和元编程实现结构体类实例
Jan 28 #Python
Python实现Const详解
Jan 27 #Python
python映射列表实例分析
Jan 26 #Python
Python操作MySQL简单实现方法
Jan 26 #Python
Python中的is和id用法分析
Jan 26 #Python
You might like
PHP对表单提交特殊字符的过滤和处理方法汇总
2014/02/18 PHP
用javascript实现改变TEXTAREA滚动条和按钮的颜色,以及怎样让滚动条变得扁平
2007/04/20 Javascript
js各种验证文本框输入格式(正则表达式)
2010/10/22 Javascript
GridView中获取被点击行中的DropDownList和TextBox中的值
2013/07/18 Javascript
纯JS实现动态时间显示代码
2014/02/08 Javascript
JavaScript中伪协议 javascript:使用探讨
2014/07/18 Javascript
兼容最新firefox、chrome和IE的javascript图片预览实现代码
2014/08/08 Javascript
js实现精确到秒的倒计时效果
2016/05/29 Javascript
js判断某个字符出现的次数的简单实例
2016/06/03 Javascript
JavaScript中有关一个数组中最大值和最小值及它们的下表的输出的解决办法
2016/07/01 Javascript
Nodejs全局安装和本地安装的不同之处
2016/07/04 NodeJs
详解用原生JavaScript实现jQuery的某些简单功能
2016/12/19 Javascript
AngularJS实现的生成随机数与猜数字大小功能示例
2017/12/25 Javascript
bootstrap中日历范围选择插件daterangepicker的使用详解
2018/04/17 Javascript
浅析Vue.js 中的条件渲染指令
2018/11/19 Javascript
jQuery选择器之基本选择器用法实例分析
2019/02/19 jQuery
Laravel 如何在blade文件中使用Vue组件的示例代码
2020/06/28 Javascript
[01:01:52]DOTA2-DPC中国联赛正赛 iG vs LBZS BO3 第一场 3月4日
2021/03/11 DOTA
用Python制作简单的钢琴程序的教程
2015/04/01 Python
wxpython中自定义事件的实现与使用方法分析
2016/07/21 Python
Python中断言Assertion的一些改进方案
2016/10/27 Python
Tensorflow之Saver的用法详解
2018/04/23 Python
Python实现绘制双柱状图并显示数值功能示例
2018/06/23 Python
使用python脚本实现查询火车票工具
2018/07/19 Python
python实现简单http服务器功能
2018/09/17 Python
基于Python测试程序是否有错误
2020/05/16 Python
详解Python 中的容器 collections
2020/08/17 Python
Godiva巧克力英国官网:比利时歌帝梵巧克力
2018/08/28 全球购物
在C#中如何实现多态
2014/07/02 面试题
数控技术专业推荐信
2013/11/01 职场文书
董事长秘书工作职责
2014/06/10 职场文书
2014派出所所长群众路线对照检查材料思想汇报
2014/09/18 职场文书
离婚协议书范文2014(夫妻感情破裂)
2014/12/14 职场文书
班主任工作总结范文
2015/08/13 职场文书
2017元旦、春节期间廉洁自律承诺书
2016/03/25 职场文书
Java实现简单小画板
2022/06/10 Java/Android