Python使用random和tertools模块解一些经典概率问题
作者:junjie 发布时间:2023-03-08 13:11:37
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%,这个数字恐怕高出了绝大多数人的意料。我们没有算错,是我们的直觉错了,科学与生活又开了个玩笑。正因为计算结果与日常经验产生了如此明显的矛盾,该问题被称为「生日悖论」,它体现的是理性计算与感性认识的矛盾,并不引起逻辑矛盾,所以倒也算不上严格意义上的悖论。


猜你喜欢
- 大家做网站,特别是自己写的代码,常常担心被一些黑客入侵服务器,从而导致网站代码被盗,给自己带来一些损失。那么我们怎么样做,就算黑客盗了你的代
- 事务隔离级别设置set global transaction isolation level read committed; //全局的se
- join用来连接字符串,split恰好相反,拆分字符串的。不用多解释,看完代码,其意自现了。>>>li = ['m
- Celery文档参考:http://docs.jinkan.org/docs/celery/参考文章:https://www.jb51.ne
- 自动扫雷一般分为两种,一种是读取内存数据,而另一种是通过分析图片获得数据,并通过模拟鼠标操作,这里我用的是第二种方式。一、准备工作1.扫雷游
- 目的:python能使用xlrd模块实现对Excel数据的读取,且按照想要的输出形式。总体思路:(1)要想实现对Excel数据的读取,需要用
- 在进行ASP网站开发时,有时需在客户端调用MSSQL数据库的数据进行打印,若调用数据量小,可以通过在客户端运用FileSystemObjec
- 简述Motivation一般来说,每个部分的内容数量是较为容易获取的,但比例(百分数)这样的数据是二次数据,这样的操作很常见比例的信息相比于
- 封装为dll会带来很多的好处,主要包括只是产权的保护,以及效率和安全性能的提升。这个例子中被封装的dll文件可以隐藏access数据库的实际
- 首先,FSO是FileSystemObject的简称。当然也就是我们的俗称FSO组件了,该组件可以用来处理驱动器、文件夹以及文件。它可以检测
- 前言今天在使用 8.0.12 版的 mysql 驱动时遇到了各种各样的坑,在使用 JDBC 连接上遇到的问题可以参考我的上一篇博客。我在使用
- 两大类索引使用的存储引擎:MySQL5.7 InnoDB聚簇索引* 如果表设置了主键,则主键就是聚簇索引* 如果表没有主键,则会默认第一个N
- 为大家提供了两种有效PyCharm激活方法,第一种PyCharm激活方法是直接输入激活码,一般PyCharm激活使用的人多了会被官方封,所以
- 介绍Silk是Django框架的实时分析和检查工具。源代码名称:django-silk源代码网址: http://www.git
- 一、merge(合并)的语法:pd.merge(left, right, how='inner', on=None, lef
- 目录循环语句单分支如何使用双分支结构多分支的使用While 循环拳击游戏循环:总结循环语句多分支选择流程 If-else语句单分支如何使用#
- 今天下载wordcloud的时候出现了很多问题,在此总结总结1.问题一:You are using pip version 19.0.3,
- 1. 新建.py文件# pip install kafka-pythonfrom kafka import KafkaConsumerimp
- 本文实例讲述了js实现随屏幕滚动的带缓冲效果的右下角广告代码。分享给大家供大家参考。具体如下:一个随屏幕自动滚动的右下角广告代码,这里请注意
- 1.快捷键 ctrl(cmd) + shift + A或者Help—>Find Action2.输入Registry,输完记得回车3.