抛硬币1000次,至少连续10次正面朝上的概率 详细解答

本文探讨了抛硬币实验中连续出现特定次数正面的概率问题,通过递推公式和随机模拟的方法,详细解析了计算过程,并对比了不同解法的效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 起因

看论文的时候,论文里简单提了一下。大概意思是,抛硬币1000次,至少连续10次正面朝上的概率比较大。我无聊就算了一下(后来就想拍死这个无聊的自己T^T)。

2. 问题陈述

一开始没什么思路,查了很多资料,答案五花八门。但是有一个观点让我很惊喜,他强调了一下问题本身。
这个问题到底什么意思?

  1. 角度1
    抛硬币1000次,如果至少连续10次正面朝上,则称事件A发生。(连续11次、12次,或者有好多次“连续10次”都不管,只要至少有一次连续10次就看作事件A发生)
  2. 角度2
    抛硬币1000次,共有 2 1000 2^{1000} 21000种情况。可以看作一个基数为 2 1000 2^{1000} 21000的集合,记为 S S S。集合 S S S中的每一个元素都是长度为1000,仅包含字符0,1的字符串。集合 A ⊂ S A\subset S AS,如果“1111111111”(10个1)是某一字符串的子串,那么该字符串在集合 A A A中。实际上集合 S S S就是样本空间,集合 A A A就是随机事件A。
    我们想知道 ∣ A ∣ |A| A

3. 问题简化版本

好了,现在我们对问题已经比较清楚了。先看一个简化版本,这样有助于思考:连续抛10次硬币,至少连续两次正面朝上的概率是多少?
但好像不太好算欸:

  1. 思考1 分解事件A

事件 A A A=事件 B 2 B_2 B2(恰好连续两次正面朝上)+事件 B 3 B_3 B3(恰好连续三次正面朝上)+···+事件 B 10 B_{10} B10(恰好连续十次正面朝上)

  • 事件 B 2 B_2 B2=事件 B 2 , 1 B_{2,1} B2,1(恰好一次连续两次正面朝上)+事件 B 2 , 2 B_{2,2} B2,2(恰好两次连续两次正面朝上)+事件 B 2 , 3 B_{2,3} B2,3(恰好三次连续两次正面朝上)(四次是不可能的)
  • 事件 B 3 B_3 B3=事件 B 3 , 1 B_{3,1} B3,1(恰好一次连续三次正面朝上)+···
  • ···
    (我选择放弃)
  1. 思考2 反事件
    P ( A ) = 1 − P ( A ‾ )    P(A)=1-P(\overline{A})\; P(A)=1P(A) 但事件 A ‾ \overline{A} A也很难求
3.1 遇事不决 先Brutal一下

2 10 2^{10} 210好像也挺大的(但比 2 1000 2^{1000} 21000小得多),就直接暴力搜索一下吧:

# 暴力法直接搜索
# 投掷硬币m次 其中n次连续正面朝上的情况种数/概率
def brutal(m=10, n=2):
	# 表示连续n次的子串,也就是关键字
    s = '1'*n
    count = 0
    # 直接枚举样本空间
    for i in range(2**m):
        if s in bin(i)[2:]:
            count += 1
    # 返回符合条件的种数,以及概率P
    return count, count/(2**m)

结果出来了,count=880, p=0.859375。这个结果可能还不够清晰,我们再看个更简单的例子:只抛四次硬币。
这时就比较直观了:(O表示正面,X表示反面)

----
XXXXXOXXOXXXOOXX
XXXOXOXOOXXOOOXO
XXOXXOOXOXOXOOOX
XXOOXOOOOXOOOOOO

发现brutal函数在这个输入下的输出是正确的

3.2 换个思路

我们先定义一个数列 A n k A_n^k Ank 表示投掷硬币n次,连续k次正面朝上的情况种数(数列下标还是喜欢n啊)
现在我们想求 A 10 2 A_{10}^2 A102

要抛10次硬币,第一次要么正面,要么反面:(@表示任意)
O@@@@@@@@@ (情况1)
X@@@@@@@@@ (情况2)

  • 对于(情况1),再考虑第二次抛硬币:
    OO@@@@@@@@@ (情况1.1)
    OX@@@@@@@@@ (情况1.2)
    • 对于(情况1.1),已经满足条件了,剩下8次就随便吧 2 8 2^8 28
    • 对于(情况1.2),既然已经抛出反面了,又得重新开始了。 A 8 2 A_{8}^2 A82
  • 对于(情况2),不就是投掷硬币9次的情况种数吗? A 9 2 A_{9}^2 A92

以上,我们可以得出 A 10 2 = 2 8 + A 8 2 + A 9 2 A_{10}^2 = 2^8+A_{8}^2+A_{9}^2 A102=28+A82+A92
推广一下: A n 2 = 2 n − 2 + A n − 1 2 + A n − 2 2 A_{n}^2 = 2^{n-2}+A_{n-1}^2+A_{n-2}^2 An2=2n2+An12+An22
再推广一下: A n k = 2 n − k + ∑ i = 1 k A n − i k ( 1 ) A_{n}^k = 2^{n-k}+\sum_{i=1}^{k}A_{n-i}^k \quad(1) Ank=2nk+i=1kAnik(1)

用本节的推导方式可以验证 k = 10 k=10 k=10时,公式(1)是正确的

4. 用递推公式算算通项吧

4.1 线性代数解法

(这里巨坑,算了好久还算错了。最后用线性代数的解法才解出来)
递推公式:(隐含    k = 2 \;k=2 k=2
A n = 2 n − 2 + A n − 1 + A n − 2 A_{n} = 2^{n-2}+A_{n-1}+A_{n-2} An=2n2+An1+An2配一下:
A n − 2 n = A n − 1 − 2 n − 1 + A n − 2 − 2 n − 2 A_{n} -2^n= A_{n-1}-2^{n-1}+A_{n-2}-2^{n-2} An2n=An12n1+An22n2 B n = A n − 2 n    B_n=A_n-2^n\; Bn=An2n,则特征方程:
x 2 = x + 1 x 1 = 1 + 5 2 ,    x 2 = 1 − 5 2 x^2=x+1\\ x_1=\frac{1+\sqrt{5}}{2},\;x_2=\frac{1-\sqrt{5}}{2} x2=x+1x1=21+5 ,x2=215    B 1 = A 1 − 2 = − 2 ,    B 2 = A 2 − 2 2 = − 3 \;B_1=A_1-2=-2, \;B_2=A_2-2^2=-3\quad B1=A12=2,B2=A222=3 ( A 1 , A 2 A_1, A_2 A1,A2的值应该比较显然),则 { c 1 x 1 + c 2 x 2 = − 2 c 1 x 1 2 + c 2 x 2 2 = − 3 \begin{cases} c_1 x_1+c_2 x_2=-2\\ c_1 x_1^2+c_2 x_2^2=-3 \end{cases} {c1x1+c2x2=2c1x12+c2x22=3解得 { c 1 = − 1 2 ( 3 5 + 1 ) c 2 = 1 2 ( 3 5 − 1 ) \begin{cases} c_1=-\frac{1}{2}(\frac{3}{\sqrt{5}}+1)\\ c_2=\frac{1}{2}(\frac{3}{\sqrt{5}}-1) \end{cases} {c1=21(5 3+1)c2=21(5 31)    B n = − 1 2 ( 3 5 + 1 ) ( 1 + 5 2 ) n + 1 2 ( 3 5 − 1 ) ( 1 − 5 2 ) n \;B_n=-\frac{1}{2}(\frac{3}{\sqrt{5}}+1)(\frac{1+\sqrt{5}}{2})^n+\frac{1}{2}(\frac{3}{\sqrt{5}}-1)(\frac{1-\sqrt{5}}{2})^n Bn=21(5 3+1)(21+5 )n+21(5 31)(215 )n
   A n = 2 n − 1 2 ( 3 5 + 1 ) ( 1 + 5 2 ) n + 1 2 ( 3 5 − 1 ) ( 1 − 5 2 ) n    ( 2 ) \;A_n=2^n-\frac{1}{2}(\frac{3}{\sqrt{5}}+1)(\frac{1+\sqrt{5}}{2})^n+\frac{1}{2}(\frac{3}{\sqrt{5}}-1)(\frac{1-\sqrt{5}}{2})^n\;(2) An=2n21(5 3+1)(21+5 )n+21(5 31)(215 )n(2)

4.2 Mathematica法

命令如下:
RSolve[{a[n] == 2^(n - 2) + a[n - 1] + a[n - 2], a[1] == 0, a[2] == 1}, a[n], n]
Mathematica太强了
将斐波那契数列和卢卡斯数列展开就可以得到公式(2)
(第一次碰到卢卡斯数列,刚开始一脸懵)
检查数列的项,来进行验证。

5. 回到原问题

递归计算

公式(1)已经给出了我们所需要的通项公式,但如果按第4节的解法,是解不出来的。线性代数法里会出现一个一元十次方程(菜鸡不会解这个特征方程),Mathematica则差点把我电脑烧坏(谨慎尝试,尽快放弃计算)
这个通项公式的确很难解,但我们可以绕开它:

# 递推公式法
# 投掷硬币m次 其中n次连续正面朝上的情况种数/概率
def recurrence(m=10, n=2):
	# 通项公式的最开始几项
    if m < n:
        return 0
    if m == n:
        return 1
    l = [0]*n
    l[-1] = 1
    multi = 1
    # 不断向前递推
    for _ in range(n, m):
        multi *= 2
        tmp = sum(l)+multi
        del l[0]
        l.append(tmp)
    return l[-1], l[-1]/(2**m)

这个算法,比3.1节中的算法快很多 O ( 2 n ) → O ( n ) O(2^n) \to O(n) O(2n)O(n)

结果

A 1000 10 A_{1000}^{10} A100010大约 1 0 301 10^{301} 10301,这里就不列出来了。P=0.38544975241248164。
我们还是验证一下吧

  1. 在n很小的时候,其实很好算的(把10次正面朝上看作一个整体),然后验证recurrence函数的输出是否正确
  2. 更有说服力的验证,就是随机事件模拟了
# 随机事件模拟
# 投掷硬币m次 其中n次连续正面朝上的概率
def simulate(m=10, n=2, size=10000000):
    count = 0
    for i in range(size):
    	# 一次模拟出m次投掷的结果
        sample = np.random.randint(0, 2, (m))
        for j in range(m-n):
        	# 滑动长度为n的窗口 判断是否满足条件
            if np.sum(sample[j:j+n]) == n:
                count += 1
                break
        # 进度条君
        if (i+1) % (size//100) == 0:
            print('\r %d%%' % ((i+1)//(size//100)), end='')
    print()
    print(count/size)
    return count/size

在size=1000000时,结果为0.384777,已经比较接近了(注意:费时操作)

6. 尾声

虽然没能得到最终的通项公式,但还是较完美地解决了这个问题。概率论真的太难了。当时我算了几个小时,还算错了,随意用Mathematica跑了一下,竟然算得十分漂亮。辛辛苦苦,还输给了一个数学软件T^T.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值