如何通过投掷一枚硬币产生各种概率

30 篇文章 0 订阅

一枚均值硬币(fair coin),其概率分布为 [(0,0.5),(1,0.5)]

import random

def coin():
    p = random.random()
    return 1 if p < 0.5 else 0

产生0.25, 0.75的概率分布

投掷(toss)一枚硬币,正面向上为1,反面向上为0。连续投掷两次,11为1:对应概率为0.25,{10, 01, 00}为0:对应概率为0.75。也即此时的随机变量(rv,random variable) X 为投掷两次的与(and)值。

应用:A, B, C, D的四个选项,用一枚硬币产生每个选项相等的概率,也即各位0.25.

  • A11
  • B10
  • C01
  • D00
def prob1():
    a, b = coin(), coin()
    if (a & b) == 1:
        return 1
    else:
        return 0 

测试:

import collections 
cnt = collections.defaultdict(int)
N = 10**5
for i in range(N):
    cnt[prob1()] += 1
for n in cnt:
    print(n, cnt[n]/N)
                                    # 0 0.749835
                                    # 1 0.250165

产生 13,23 的概率分布

投掷一枚硬币两次,11为1,{10, 01}为0,{00}重新投掷。

应用:自然是A, B, C三个选项,用一枚硬币产生每个选项相等的概率。

def prob2():
    while True:
        a, b = coin(), coin()
        if (a & b) == 1:
            return 1
        if (a | b) == 1:
            return 0
                # while 和 两个 if(但没有else)的结合很妙
                # 实现对else情况的重新投掷判断

产生 0.3,0.7 的概率分布

投掷一枚硬币四次,前三种情况为1,也即{0000, 0001, 0010},再有六种情况为0,如{0011, 0100, 0101, 0110, 0111, 1000},其余情况重新投掷。

当然方案并不唯一。这里再提供一个利用条件概率解决方案,首先定义离散型随机变量 X :投掷一枚硬币四次得到的二进制表示(0000-1111)(如同掷一个骰子得到点数为1-6)。在点数不大于10的情况下点数不大于3的概率(这方案有点耍无赖,:-D)。

再转念一想,“点数不大于10的条件下”莫不就是把其他的情况排除了嘛,原来两种方案是等价的,只不过条件概率的概念可以解释第一种方案罢了。

def prob3():
    while True:
        a, b, c, d = coin(), coin(), coin(), coin()
        if ...

如果是一个骰子呢?


这里写图片描述

如何通过一个掷骰子获得 14,34 的概率分布(probability distribution)?

其实只需要一步就可将掷骰子问题转化为抛硬币问题。how ?
抛出的点数为奇数,也即{1, 3, 5}为1,概率为1/2;
抛出的点数为偶数,也即{2, 4, 6}为0,概率为1/2;
如此便将掷骰子问题转换为了抛硬币问题。

以任一概率执行某一动作

某一概率 P 执行某一动作,在(0, 1)区间均匀分布上进行采样,也即 uU(0,1)

import scipy.stats as st

p = .6
u = st.uniform(0, 1)
if u.rvs() < p:
    ...

非均匀硬币:如何产生均匀的概率分布

就以普通的一元人民币硬币为例,正面为1字,反面为花,事实上,重心是稍微偏向反面的,此时如果想保证公平,应该如何指定。根据前面的描述,这道题目的答案应该十分简单了。正反:为正,反正:为反。

import random
from collections import Counter

def unfair_coin(p):
    return 1 if random.random() < p else 0
def toss(p):
    while True:
        a, b = unfair_coin(p), unfair_coin(p)
        if a - b == 1:
            return 1
        if b - a == 1:
            return 0
if __name__ == '__main__':
    N, p = 10000, 0.49
    c = Counter((toss(p) for _ in range(N)))
  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五道口纳什

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值