问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

解决一个有意思的抛硬币问题,计算连续两次正面所需次数的数学期望

创作时间:
作者:
@小白创作中心

解决一个有意思的抛硬币问题,计算连续两次正面所需次数的数学期望

引用
1
来源
1.
https://cloud.tencent.com/developer/article/2421009

对于一枚质地均匀的硬币,连续两次得到正面所需的次数数学期望是多少?这是一个经典的概率论问题,可以通过马尔可夫链或递归方法来解决。本文将从问题分析、数学推导到代码实现,完整地探讨这个问题的解决方案。

一、问题与分析

问题:对于质地均匀的硬币,连续两次得到正面所需的次数数学期望是多少?

关键词:抛硬币、均匀、连续、两次正面

一些分析

  • 这个经典的概率论问题要求我们给出抛掷一枚均匀硬币,直到连续两次都出现正面为止,平均需要抛掷多少次。连续两次的概念很关键。
  • 这代表了一类问题,它们可以总结为在一连串不断重复的实验中,第一次连续出现n次成功所需要的平均次数。
  • 解决此问题可采用马尔可夫链(马尔可夫状态转换图,列方程求解)或更简单的递归方法。通过数学推导,还能得到通项公式:平均抛掷2^{(n+1)} - 2次硬币才会出现n连正的情况。

二、基本的数学推导

我们可以通过建立一个递归关系来解决这个问题。设E为得到连续两次正面所需的抛掷次数的期望值。我们可以将问题分解为以下几种情况:

  • 第一次抛掷就得到正面(概率为\frac{1}{2}),然后我们就处于了一个新的状态,即下一次抛掷如果再次得到正面,游戏结束;否则,我们回到初始状态。设从这个状态开始,直到游戏结束所需的期望抛掷次数为E_{1}。
  • 第一次抛掷得到反面(概率为\frac{1}{2}),这时我们仍然处于初始状态,因为我们一次正面也没有得到过。设从这个状态开始,直到游戏结束所需的期望抛掷次数为E_{0}。

由于E_{0} = E(因为它们都代表从游戏开始直到结束的期望抛掷次数),我们可以建立以下等式:

E = \frac{1}{2} \times (1 + E_1) + \frac{1}{2} \times (1 + E)

对于E_{1},如果第二次抛掷得到正面(概率为\frac{1}{2}),游戏结束;如果得到反面(概率为\frac{1}{2}),则回到初始状态E。因此有:

E_1 = \frac{1}{2} \times (1) + \frac{1}{2} \times (1 + E)

联立解这两个方程,我们可以求出E的值为6。

另一种推导

在这里插入图片描述

E = \frac{1}{2} \times (E+1) + \frac{1}{4} \times (E+2) + 2 \times \frac{1}{4} \tag{连续两次正面}
E = \frac{1}{2}\times (E+1) + \frac{1}{4} \times (E+2) + \frac{1}{8} \times (E+3) + 3 \times \frac{1}{8} \tag{连续三次正面}

此外,当抛掷的硬币不均匀时,即正面的概率不再是\frac{1}{2},通项公式为:

\frac{p^{-n}-1}{1-p}

代入不同的n(要求连续出现的次数)和p(正面的概率)就能得到准确结果。

三、代码示例

下面这段代码的主要功能是通过模拟实验来估计在一系列硬币投掷中,得到连续n次正面的平均所需次数(即数学期望)。这个问题在概率论和统计学中很常见,尤其是在研究随机过程和伯努利试验时。代码通过大量模拟来近似实际的数学期望值,这种方法在理论值难以直接计算时特别有用。

import random

def simulate_coin_toss(n, p):
    """模拟投掷硬币直到出现连续 n 次正面"""
    # 记录投掷次数和连续正面的次数
    count, consecutive_heads = 0, 0
    while consecutive_heads < n:
        # random() 方法返回一个在 [0,1) 范围内的随机实数
        if random.random() < p:         # 随机投掷硬币,得到正面的概率为 p。
            consecutive_heads += 1
        else:
            consecutive_heads = 0       # 如果得到反面,重置连续正面的计数。
        count += 1      # 每次投掷都增加计数
    return count

def calculate_expected_value(num_simulations, n, p):
    """计算得到连续 n 次正面所需次数的数学期望"""
    # 记录所有模拟的总次数
    total_count = 0
    for _ in range(0, num_simulations):
        total_count += simulate_coin_toss(n, p)
    return total_count / num_simulations      # 计算平均次数作为数学期望的近似值

# 质地均匀的硬币,得到连续两次正面所需次数的数学期望是?
# 示例:模拟 1000000 次投掷
num_simulations = 1000000
# 正面的概率
positive_probability = 0.5
# 连续出现次数
successive_times = 2
expected_value = calculate_expected_value(num_simulations,
                                          successive_times,
                                          positive_probability
                                         )
print(f"经过 {num_simulations} 次模拟,得到连续 {successive_times} 次正面所需次数的数学期望近似为:{expected_value:.2f}")
# 程序运行结果如下:
# 经过 1000000 次模拟,得到连续 2 次正面所需次数的数学期望近似为:6.00

代码解释

  • 导入了 Python 的random模块,它提供了生成随机数的函数,用于模拟投掷硬币的随机性。
  • 定义模拟函数。这个函数接受两个参数:n表示连续出现正面的次数目标,p表示每次投掷得到正面的概率。当达到连续出现指定次数的正面后,函数返回总的投掷次数。
  • 定义计算期望值的函数。这个函数通过多次模拟来计算达到连续两次正面所需次数的平均值(即数学期望)。它接受三个参数:模拟次数num_simulations、连续出现正面的目标次数n和每次投掷得到正面的概率p。将累加的总投掷次数除以模拟次数,得到平均投掷次数,作为连续两次正面所需次数的近似期望值。
  • 主程序部分。这部分代码设置了模拟参数,并调用calculate_expected_value函数进行模拟计算。然后打印出通过大量模拟得到的连续两次正面所需次数的近似期望值。

该算法的时间复杂度为O(n),其中 n 是模拟投掷的次数。这是因为我们需要对每次模拟投掷进行计数,直到满足条件为止。空间复杂度为O(1),因为我们只使用了固定数量的变量来存储投掷次数和连续正面的计数。

使用通项公式直接计算,其时间复杂度和空间复杂度均为O(1)。以下是一个代码示例:

def expected_number_of_tosses(n, p):
    """
    计算得到连续 n 次正面所需的抛掷硬币次数的数学期望。
    Return:
        float:连续 n 次正面所需的抛掷次数的数学期望。
    """
    return (p ** (-n) - 1) / (1 - p)

# 正面的概率
positive_probability = 0.5
# 连续出现次数
successive_times = 2
result = expected_number_of_tosses(successive_times,
                                   positive_probability
                                  )
print(f"得到连续 {successive_times} 次正面所需次数的数学期望是: {result}")
# 程序运行结果如下:
# 得到连续 2 次正面所需次数的数学期望是:6.00
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号