Python作弊者硬币谜题:将90%正面偏置硬币转为公平硬币
解题核心思路
你之前想的通过+1调整Tails出现频率的方向走不通——毕竟你不能修改broken_coin()的内部逻辑,只要单次调用这个函数,Heads的出现概率永远固定为90%,硬改返回值只会让概率偏差更大。
这个问题是经典的偏置硬币校正问题,用冯·诺依曼提出的方法就能完美解决,完全符合题目的所有限制:
连续抛两次偏置硬币,会出现四种结果组合,各自概率如下:
- 第一次Heads,第二次Heads:概率为0.9*0.9=0.81
- 第一次Heads,第二次Tails:概率为0.9*0.1=0.09
- 第一次Tails,第二次Heads:概率为0.1*0.9=0.09
- 第一次Tails,第二次Tails:概率为0.1*0.1=0.01
你会发现第一次Heads第二次Tails和第一次Tails第二次Heads这两种情况的概率完全相等,我们只要把这两种情况分别映射为公平硬币的Heads和Tails结果,剩下两种两次结果相同的情况直接丢弃、重新抛两次即可,最终得到两个结果的概率严格各为50%。这个方法对任意偏置程度的硬币都生效,只要硬币出两个面的概率都不为0。
实现代码
def fair_coin(): while True: first = broken_coin() second = broken_coin() # 两次结果不同时才返回有效结果 if first == "Heads" and second == "Tails": return "Heads" if first == "Tails" and second == "Heads": return "Tails" # 两次结果相同就进入下一轮循环重抛
合规性说明
- 全程没有修改题目给出的
broken_coin()函数,所有调用都是直接使用原函数的返回值 - 没有引入任何额外随机源,所有随机性都来自
broken_coin()本身,甚至没有调用random模块的其他方法 - 数学上可以严格证明返回Heads和Tails的概率均为50%,虽然为了得到有效结果平均需要抛约5.6次原偏置硬币,但完全满足公平硬币的效果要求。
内容的提问来源于stack exchange,提问作者Electric Ice Wolf
相关产品推荐
相关产品推荐

