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 动态获取当前运行的类名和函数名的方法
Apr 15 Python
跟老齐学Python之有容乃大的list(2)
Sep 15 Python
python中map()与zip()操作方法
Feb 27 Python
利用Python循环(包括while&for)各种打印九九乘法表的实例
Nov 06 Python
python实现学生信息管理系统
Apr 05 Python
Python实现求解一元二次方程的方法示例
Jun 20 Python
python3 反射的四种基本方法解析
Aug 26 Python
Pytorch maxpool的ceil_mode用法
Feb 18 Python
Python *args和**kwargs用法实例解析
Mar 02 Python
pycharm中导入模块错误时提示Try to run this command from the system terminal
Mar 26 Python
Pytorch 使用不同版本的cuda的方法步骤
Apr 02 Python
python+selenium+chromedriver实现爬虫示例代码
Apr 10 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根据日期或时间戳获取星座信息和生肖等信息
2015/10/20 PHP
PHP判断JSON对象是否存在的方法(推荐)
2016/07/06 PHP
Laravel最佳分割路由文件(routes.php)的方式
2016/08/04 PHP
PHP使用PDO操作sqlite数据库应用案例
2019/03/07 PHP
laravel 修改.htaccess文件 重定向public的解决方法
2019/10/12 PHP
php生成短网址/短链接原理和用法实例分析
2020/05/29 PHP
js资料toString 方法
2007/03/13 Javascript
dojo 之基础篇(三)之向服务器发送数据
2007/03/24 Javascript
javascript 写类方式之八
2009/07/05 Javascript
jQuery 相关控件的事件操作分解
2009/08/03 Javascript
jquery下jstree简单应用 - v1.0
2011/04/14 Javascript
怎么清空javascript数组
2013/05/11 Javascript
jquery动态更换设置背景图的方法
2014/03/25 Javascript
jQuery实现Div拖动+键盘控制综合效果的方法
2015/03/10 Javascript
javascript函数式编程实例分析
2015/04/25 Javascript
jQuery 全选 全部选 反选 实现代码
2016/08/17 Javascript
JS获取checkbox的个数简单实例
2016/08/19 Javascript
详谈js遍历集合(Array,Map,Set)
2017/04/06 Javascript
利用angular自动编译andriod APK的绕坑经历分享
2019/03/08 Javascript
浅谈VUE防抖与节流的最佳解决方案(函数式组件)
2019/05/22 Javascript
使用jquery-easyui的布局layout写后台管理页面的代码详解
2019/06/19 jQuery
JavaScript碰撞检测原理及其实现代码
2020/03/12 Javascript
Vue中watch、computed、updated三者的区别及用法
2020/07/27 Javascript
Python数据类型详解(四)字典:dict
2016/05/12 Python
Python实现并行抓取整站40万条房价数据(可更换抓取城市)
2016/12/14 Python
Python写的一个定时重跑获取数据库数据
2016/12/28 Python
Python 专题一 函数的基础知识
2017/03/16 Python
将string类型的数据类型转换为spark rdd时报错的解决方法
2019/02/18 Python
Python 多线程共享变量的实现示例
2020/04/17 Python
python 实现控制鼠标键盘
2020/11/27 Python
python 操作excel表格的方法
2020/12/05 Python
普通PHP程序员笔试题
2016/01/01 面试题
Linux Interview Questions For software testers
2013/05/17 面试题
大学生两会学习心得体会
2014/03/10 职场文书
Python实现老照片修复之上色小技巧
2021/10/16 Python
使用Django框架创建项目
2022/06/10 Python