如何仅用单个六面骰子在Python中生成1到16的随机整数
实现思路说明
现有代码问题
- 概率分布不均:三次6面骰子的和本身是正态分布,减2后得到的1~16值并不符合均匀随机的要求,中间值出现概率远高于两端
- 无边界处理逻辑:三次骰子和最大为18,减2后会出现17、18两个超出1~16范围的返回值,你注释中提到的超范围重扔逻辑没有实现
- 测试代码语法错误:最后一行
print(I)的变量I为大写,和之前定义的小写i不一致,运行会报未定义错误
可行实现方案(均匀随机,仅使用单个骰子)
roll6()本身就是模拟单个六面骰子的单次投掷,不管调用多少次都是仅使用单个骰子实现的,不需要额外随机源。这里推荐用拒绝采样+6进制编码的方案,可以保证输出1~16的每个值概率完全相等,核心思路如下:
- 把每次投骰子的结果转成05的6进制数位,投2次就可以生成035范围的等概率整数,计算方式为
(第一次结果-1)*6 + (第二次结果-1) - 取前32个值(0~31),直接通过
值 % 16 + 1就能得到1~16的均匀结果 - 如果得到的结果≥32,就丢弃本次两次投掷的结果,重新投2次,直到拿到符合要求的值
这个方案平均投掷次数不到2.25次,效率很高。
完整实现代码
import random # 模拟单个六面骰子投掷,返回1~6的随机整数 def roll6(): return random.randint(1,6) def roll16(): while True: # 单次骰子投两次,生成0~35的等概率值 num = (roll6() - 1) * 6 + (roll6() - 1) if num < 32: return num % 16 + 1 # 测试代码:一直输出直到出现1 i = roll16() while i != 1: print(i) i = roll16() print(i)
内容的提问来源于stack exchange,提问作者spraveenitpro
相关产品推荐
相关产品推荐

