返回顶部
首页 > 资讯 > 后端开发 > Python >Python 概率生成问题案例详解
  • 456
分享到

Python 概率生成问题案例详解

2024-04-02 19:04:59 456人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

概率生成问题 有一枚不均匀的硬币,要求产生均匀的概率分布 有一枚均匀的硬币,要求产生不均匀的概率分布,如 0.25 和 0.75 利用 Rand7() 实现 Rand10()

概率生成问题


有一枚不均匀的硬币,要求产生均匀的概率分布
有一枚均匀的硬币,要求产生不均匀的概率分布,如 0.25 和 0.75
利用 Rand7() 实现 Rand10()

不均匀硬币 产生等概率

现有一枚不均匀的硬币 coin(),能够返回 0、1 两个值,其概率分别为 0.6、0.4。要求使用这枚硬币,产生均匀的概率分布。即编写一个函数 coin_new() 使得它返回 0、1 的概率均为 0.5。


# 不均匀硬币,返回 0、1 的概率分别为 0.6、0.4
def coin():
    return 0 if random.randint(1,10) > 4 else 1

统计抛两次硬币的结果的概率分布:

结果 0 1
0 0.60.6=0.36 0.60.4=0.24
1 0.40.6=0.24 0.40.4=0.16

连续抛两枚硬币得到 0 1 和 1 0 的概率分布是相同的。因此这道题的解法就是连续抛两次硬币,如果得到 0 1,返回 0;如果得到 1 0,返回 1;如果两次结果相同,则重新抛。

以此类推,无论这枚不均匀硬币的概率是多少,都可以用这种方法得到等概率的结果。


ddef coin_new():
    while True:
        a = coin()
        if coin() != a:  
            return a

完整测试代码:


def coin():
    return 0 if random.randint(1,10) > 4 else 1

def coin_new():
    while True:
        a = coin()
        if coin() != a:  
            return a
if __name__ == '__main__':
    a = 0
    b = 0
    n = 100000
    for _ in range(n):
        if coin_new():a += 1
        if coin():b += 1

    print(f"1:{a/n},1:{b/n}")

均匀硬币 产生不等概率

现有一枚均匀的硬币 coin(),能够返回 0、1 两个值,其概率均为 0.5。要求编写一个函数 coin_new(),使得它返回指定的 0、1 概率分布。


# 均匀硬币 
def coin():
    return random.randint(0,1)  

P(0) = 1/4,P(1) = 3/4

对于均匀硬币而言,连续抛两次,得到 0 0、0 1、1 0、1 1 的概率均为 1/4。显然,只需要连续抛两次硬币,如果得到 0 0,返回 0,其他情况返回 1。


def coin_new():
    return coin() or coin()

P(0) = 1/3,P(1) = 2/3

连续抛两次硬币。如果得到 1 1,返回 0;如果得到 1 0 或 0 1,返回 1;如果得到 0 0,继续抛硬币。


def coin_new():
    while True:
        a, b = coin(), coin()
        if a & b: return 0
        if a | b: return 1

P(0) = 0.3,P(1) = 0.7

每抛一次硬币,会得到二进制数的一位,连续抛 4 次硬币,可以等概率生成 [0, 15] 的每个数,记为 x。去掉 [10, 15],剩下 [0, 9] 的每个数依然是等概率的。如果 x ∈ [ 0 , 2 ] x \in [0, 2] x∈[0,2],返回 0; x ∈ [ 4 , 9 ] x \in [4, 9] x∈[4,9],返回 1; x ≥ 10 x ≥ 10 x≥10,重复上述过程。


def coin_new():
    while True:
        x = 0
        for _ in range(4):
            x = (x << 1) + coin()
        if x <= 2: return 0
        if x <= 9: return 1

总结

每抛一次硬币,会得到二进制数的一位,连续抛 k 次硬币,可以等概率生成 [ 0 , 2 k − 1 ] [0, 2^k-1] [0,2k−1] 的每个数在 [ 0 , 2 k − 1 ] [0, 2^k-1] [0,2k−1][ 中,选取 m 个数返回 0,n 个数返回 1,则 0、1 的概率分别为 m m + n \frac{m}{m+n} m+nm​ 、 n m + n \frac{n}{m+n} m+nn​。

关于 k 的选择,最少需要满足 N < = 2 k − 1 N <= 2^k-1 N<=2k−1,N 是生成对应概率分布至少需要多少个不同数字。比如要生成 1/3、2/3 的分布,至少需要 3 个不同数字,则 N = 3, k = 2;要生成 3/10、7/10 的分布,至少需要 10 个数字,则 N = 10, k = 4。

k 最多则没有限制,我们总可以通过抛更多次硬币来解决问题,只需要把无用的数字舍弃即可。但我们的目的是尽可能减少无用数字的比例,因为每次遇到无用数字时,都需要重新生成新的数字。

Rand7 生成 Rand10

已有方法 Rand7() 可生成 1 到 7 范围内的均匀随机整数,试写一个方法 Rand10() 生成 1 到 10 范围内的均匀随机整数。

抛硬币可以看作是 Rand2(),均匀生成 0、1 两个整数。如何根据 Rand2() 生成 Rand10()?将每次抛硬币的结果,看作二进制的每一位,就可以得到 [ 0 , 2 k − 1 ] [0, 2^k-1] [0,2k−1] 范围内的均匀随机整数。只需要抛 4 次硬币,就能得到 [0, 15] 范围的整数。返回 [1, 10] 范围的整数,其他情况则重新抛硬币。


def rand10():
    while True:
        x = 0
        for _ in range(4):
            x = x << 1 + rand2()
            
        if 1 <= x <= 10: return x

取 Rand7() - 1 作为对应的 7 进制位。每执行 k 次 Rand7(),将得到一个 k 位的 7 进制整数,在 [ 0 , 7 k − 1 ] [0, 7^k-1] [0,7k−1] 范围内均匀分布。

只需执行 k = 2 次 Rand7(),就可以得到范围为 [0, 48] 的均匀整数:

当 x ∈ [ 1 , 10 ] x \in [1, 10] x∈[1,10] 时返回 x,否则重新计算:


def rand10():
    while True:
        x = (rand7() - 1) * 7 + (rand7() - 1);
        if 1 <= x <= 10: return x

进一步优化

选择 [1, 40] 范围里的数,通过取余运算来得到 [1, 10] 范围的数:


def rand10():
    while True:
        x = (rand7() - 1) * 7 + (rand7() - 1)
        if 1 <= x <= 40:
            return x % 10 + 1

对于上面这 9 个无用数字,计算 x % 40 可以得到 [0, 8] 范围的均匀随机整数。此时再调用一次 Rand7(),计算 (x % 40) * 7 + Rand7(),这相当于 Rand9() * 7 + Rand7()。显然,可以得到 [1, 63] 范围的均匀随机整数。这时 [1, 60] 范围里的数都可以用来作取余运算,只有 61、62、63 共 3 个无用数字:


def rand10():
    while True:
        x = (rand7() - 1) * 7 + (rand7() - 1)
        if 1 <= x <= 40:
            return x % 10 + 1   
            
    	x = (x % 40) * 7 + rand7() # 1~63
    	if x <= 60: return x % 10 + 1

对于 61、62、63,再调用一次 Rand7(),计算 (x - 61) * 7 + Rand7(),相当于 Rand3() * 7 + Rand7(),可以得到 [1, 21] 范围的均匀随机整数,这时再作取余运算,只有 1 个无用数字(21):


def rand10():
    while True:
        x = (rand7() - 1) * 7 + (rand7() - 1)
        if 1 <= x <= 40:
            return x % 10 + 1   
            
    	x = (x % 40) * 7 + rand7() # 1~63
    	if x <= 60: return x % 10 + 1

        x = (x - 61) * 7 + 7 # 1~21
        if x <= 20: return x % 10 + 1

每次 while 执行的时候,只有 1 个无用数字(21)会被舍弃,重新执行的概率很低。

RandM 生成 RandN

已知 RandM() 可以等概率的生成 [0, M-1] 范围的随机整数,那么执行 k 次,每次都得到 M 进制的一位,可以等概率生成 [ 0 , M k − 1 ] [0, M^k-1] [0,Mk−1] 范围的随机整数,记为 x。

RandN 至少需要 N 个均匀随机整数,因此只需要取 k,使得 M k − 1 > = N M^k-1 >= N Mk−1>=N 即可,此时有多种方式得到 RandN:
一种是只在 x ∈ [ 0 , N − 1 ] x \in [0, N-1] x∈[0,N−1] 时返回 x,另一种是利用取余运算,在保证等概率的前提下,尽可能多的利用生成的数字,从而减少舍弃的数字比例,降低 while 重复执行的概率。

到此这篇关于python 概率生成问题案例详解的文章就介绍到这了,更多相关Python 概率生成问题内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Python 概率生成问题案例详解

本文链接: https://lsjlt.com/news/135274.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Python 概率生成问题案例详解
    概率生成问题 有一枚不均匀的硬币,要求产生均匀的概率分布 有一枚均匀的硬币,要求产生不均匀的概率分布,如 0.25 和 0.75 利用 Rand7() 实现 Rand10() ...
    99+
    2024-04-02
  • python怎么按概率生成随机数
    在Python中,你可以使用`random`模块来按概率生成随机数。下面是一个简单的例子,展示了如何按概率生成随机数:```pyth...
    99+
    2023-09-04
    python
  • Python元类与迭代器生成器案例详解
    1.__getattr__和__getattribute__魔法函数 __getattr__是当类调用一个不存在的属性时才会调用getattr魔法函数,他传入的值item就是你这个调...
    99+
    2024-04-02
  • python怎么按概率生成指定数字
    要按概率生成指定数字,可以使用numpy库中的random.choice函数。这个函数可以根据给定的概率分布从指定的数字列表中选择一...
    99+
    2024-02-29
    python
  • Python 二叉树的概念案例详解
    二叉树简介 关于树的介绍,请参考:https://www.jb51.net/article/222488.htm 一、二叉树简介 二叉树是每个节点最多有两个子树的树结构,是一种特殊的...
    99+
    2024-04-02
  • Java dom4j生成与解析XML案例详解
    一)dom4j介绍 使用方式:在pom.xml中导入dom4j对应的jar <dependency> <groupId>dom4j</gro...
    99+
    2024-04-02
  • python怎么实现按概率生成随机数
    可以使用Python中的random模块来生成随机数。如果要按照给定的概率分布生成随机数,可以使用random.choices()方...
    99+
    2023-10-24
    python
  • 怎么解决均等概率问题
    本篇内容介绍了“怎么解决均等概率问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在解决算法问题中我们会经...
    99+
    2024-04-02
  • JavaScript实现动态生成表格案例详解
    目录前言实现思路实现代码 实现效果前言 在这里实现一个动态添加表格的案例,当点击添加按钮时,可以弹出一个表单,然后将输入的内容添加到表格中,也可以将表格中的整行内容清除。 实现思路 ...
    99+
    2024-04-02
  • JAVA 生成随机数并根据后台概率灵活生成的实例代码
    最近碰到一个大转盘的业务,奖品可根据数据后台灵活设置中奖概率,看起来挺简单的业务功能,但实现起来对我这个毫无经验的人来说并不容易,后面又碰到一个根据后台概率随机获取不同概率的档位积分,前面是两个实际中业务要用到的话不多说吧,直接上我写概率工...
    99+
    2023-05-31
    java 概率 随机数
  • Python真题案例之小学算术 阶乘精确值 孪生素数 6174问题详解
    目录前言小学生算术问题描述问题分析代码实现阶乘精确值问题描述问题分析代码实现孪生素数问题描述问题分析代码实现6174问题问题描述问题分析代码实现前言 今天给大家分享一下刷到的关于数值...
    99+
    2024-04-02
  • python生成二维码的实例详解
    python生成二维码的实例详解 版本相关 操作系统:Mac OS X EI Caption Python版本:2.7 IDE:Sublime Text 3 依赖库 Python生成二维码需要的...
    99+
    2022-06-05
    详解 实例 二维码
  • Python异步之生成器示例详解
    目录正文1. 什么是异步生成器1.1. Generators1.2. Asynchronous Generators2. 如何使用异步生成器2.1. 定义2.2. 创建2.3. 一步...
    99+
    2023-03-22
    Python 异步生成器 Python 异步
  • C++ 约瑟夫环问题案例详解
    在牛客网上做到一道题,是约瑟夫环的变型,所以借此学习一下新知识,并且巩固一下对题目意思的理解,这一篇仅作约瑟夫环问题的解释,下一篇再写题目: ##1.首先,我们先来了解一下什么是约瑟...
    99+
    2024-04-02
  • JavaScript 中this指向问题案例详解
    总结 全局环境 ➡️ window 普通函数 ➡️ window 或 undefined 构造函数 ...
    99+
    2024-04-02
  • Java 括号匹配问题案例详解
    目录前言例题算法思想算法举例代码栈类括号匹配核心算法完整代码运行结果前言 括号匹配问题算是栈应用中比较经典的问题了,在数据结构的书中还有各种考试中会出现。最近刷题的时候也遇到了,就想...
    99+
    2024-04-02
  • 详解Python中生成随机数据的示例详解
    目录随机性有多随机加密安全性PRNGrandom 模块数组 numpy.random相关数据的生成random模块与NumPy对照表CSPRNG尽可能随机 os.urandom()s...
    99+
    2024-04-02
  • 八皇后问题(python 生成器)
    问题: 在8×8格的国际象棋上摆放八个皇后,使其不能互相***,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。大致是下面这种样式: 思路: 第一步:皇后位置存放问题 用列表或元组表示。索引表示皇后所在的横行。列表的值...
    99+
    2023-01-31
    生成器 皇后 python
  • Python 迭代器与生成器实例详解
    Python 迭代器与生成器实例详解 一、如何实现可迭代对象和迭代器对象 1.由可迭代对象得到迭代器对象 例如l就是可迭代对象,iter(l)是迭代器对象 In [1]: l = [1,2,3,4] ...
    99+
    2022-06-04
    生成器 详解 实例
  • vue keepAlive缓存清除问题案例详解
    vue项目中经常会用到keepalive来做缓存,在应付基本要求上可以说非常方便。但是遇到同一个页面,根据条件不同,分别缓存或者不缓存,就有些麻烦了。 首先先把坑列出来: 1. ...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作