Python中掷硬币的连胜问题

《Python编程快速上手——让繁琐工作自动化 第2版》

4.11 实践项目
4.11.2 掷硬币的连胜

如果你掷硬币一百次,并在每次正面时写下“H”,在每次反面时写下“T”,就会创建一个看起来像“T T T T T H H H H T T ”这样的列表。编写一个程序,查找随机生成的正面和反面列表中连续出现6个正面或6个反面的频率。你的程序将实验分为两部分:第一部分生成随机选择的“正面”和“反面”值的列表,第二部分检查其中是否有连胜。将所有代码放入一个循环中,重复该实验10000次,这样我们就可以找出掷硬币中包含连续六个正面或反面的百分比

运行代码:
import random

repetitionsNumber = 6
completeList = []
completeStringList = []
numberOfStreaks = 0
# 生成值的列表
for experimentNumber in range(10000):
    tryList = []
    tryString = ''
    for try_nums in range(100):
        if random.randint(0, 1) == 0:
            tryList.append('H')
            tryString += 'H'
        else:
            tryList.append('T')
            tryString += 'T'
    completeList.append(tryList)
    completeStringList.append(tryString)
    # 检查是否连胜
    if ('H' * repetitionsNumber in tryString) or ('T' * repetitionsNumber in tryString):
        numberOfStreaks += 1

print("repetitionsNumber is ", repetitionsNumber)
print("numberOfStreaks is ", numberOfStreaks)
# print("completeList is ",completeList)
print('Chance of streak: %.2f%%' % ((numberOfStreaks / 10000) * 100))
运行结果:
repetitionsNumber is  6
numberOfStreaks is  8116
Chance of streak: 81.16%
题干个人理解:

1.要求保存“正面”和“反面”值的列表

2.检查其中是否有连胜

3.将所有代码放入一个循环中(除了打印)

扩展

修改下方代码中repetitionsNumber的值,可以得到从连续重复1次到连续重复repetitionsNumber次会出现的概率

运行代码:
# 结果关联
import random

repetitionsNumber = 25
completeList = []
completeStringList = []
# 生成值的列表
for experimentNumber in range(10000):
    tryList = []
    tryString = ''
    for try_nums in range(100):
        if random.randint(0, 1) == 0:
            tryList.append('H')
            tryString += 'H'
        else:
            tryList.append('T')
            tryString += 'T'
    completeList.append(tryList)
    completeStringList.append(tryString)

# 检查是否连胜
for repeatNum in range(1, repetitionsNumber + 1):
    numberOfStreaks = 0
    for String in completeStringList:
        if ('H' * repeatNum in String) or ('T' * repeatNum in String):
            numberOfStreaks += 1

    print("repeatNum is ", repeatNum)
    print("numberOfStreaks is ", numberOfStreaks)
    # print("completeList is ",completeList)
    print('Chance of streak: %.2f%%' % ((numberOfStreaks / 10000) * 100))
    print()
运行结果(节选):
repeatNum is  4
numberOfStreaks is  9996
Chance of streak: 99.96%

repeatNum is  5
numberOfStreaks is  9688
Chance of streak: 96.88%

repeatNum is  6
numberOfStreaks is  8105
Chance of streak: 81.05%

结果具有关联性,即使用同一套数据,不会出现连续19次的次数比连续出现18次的多的情况

使用numpy验证:
# numpy计算结果,结果独立
import numpy as np

repetitionsNumber = 25
for j in range(1, repetitionsNumber + 1):
    NUM_EXER = 10000
    count_max = 0
    for i in range(NUM_EXER):
        L = []
        for i in range(100):  # throw coins
            if np.random.rand() > 0.5:
                L.append(1)
            else:
                L.append(0)

        C = []
        count = 1
        L.append(-1)  # sentinel node
        for i in range(len(L) - 1):
            if L[i + 1] == L[i]:
                count += 1
            else:
                if count > 1:
                    C.append(count)
                count = 1
        if np.max(C) >= j:
            count_max += 1

    print("repetitionsNumber is ", j)
    print((count_max / NUM_EXER) * 100, '%')
    print()
运行结果(节选):
repetitionsNumber is  4
99.98 %

repetitionsNumber is  5
97.02 %

repetitionsNumber is  6
81.3 %

上述代码结果不具有关联性,即不使用同一套数据,可能会出现连续19次的次数比连续出现18次的多的情况

numpy思路参考:

python数学小实验(5)——掷硬币出现连续正面的概率
————————————————

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/houhuipeng/article/details/91443188

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值