Python 掷两个骰子,其分布与概率不一致
在棋盘游戏卡坦中,你每回合掷2个六面骰子,可能的结果从2到12,在100000次掷骰中,总和的分布应该是这样的:Python 掷两个骰子,其分布与概率不一致,python,python-3.x,distribution,dice,Python,Python 3.x,Distribution,Dice,在棋盘游戏卡坦中,你每回合掷2个六面骰子,可能的结果从2到12,在100000次掷骰中,总和的分布应该是这样的: ***CATAN DICE*** 2 *****5998 3 ********8170 4 ********8170 5 **********10299 6 ************12283 7 **************14341 8 ************12331 9 **********10149 10 ********8090 11 ******6
***CATAN DICE***
2 *****5998
3 ********8170
4 ********8170
5 **********10299
6 ************12283
7 **************14341
8 ************12331
9 **********10149
10 ********8090
11 ******6033
12 ****4068
然而,我只在骰子是从0到6的七边时使用randint(0,6)
得到这个结果。
当我使用randint(1,6)
时,分布如下:
***CATAN DICE***
2 **2771
3 *****5560
4 *****5560
5 ********8410
6 ***********11088
7 **************14132
8 ****************16491
9 *************13768
10 ***********11163
11 ********8220
12 *****5616
这是错误的,8不太可能出现在一对六面骰子中。
?我的代码有问题吗?,?这可能与randint()
的工作方式有关吗
这是我的代码:
from random import randint
print("***CATAN DICE***")
normal = [0,0,0,0,0,0,0,0,0,0,0]
for i in range(0, 100000):
a=randint(0, 6)
b=randint(0, 6)
throw = a+b
if throw == 2:
normal[0]+=1
if throw == 3:
normal[1]+=1
if throw == 3:
normal[2]+=1
if throw == 4:
normal[3]+=1
if throw == 5:
normal[4]+=1
if throw == 6:
normal[5]+=1
if throw == 7:
normal[6]+=1
if throw == 8:
normal[7]+=1
if throw == 9:
normal[8]+=1
if throw == 10:
normal[9]+=1
if throw == 11:
normal[10]+=1
i=0
j=0
for i in range(len(normal)):
print(i+2, end = " ")
for j in range(int(normal[i]/1000)):
print("*",end="")
print(f"{normal[i]}\n")
我已经添加了缺少的if条件,并且分布是正确的。由于骰子是七面的,上面有0,因此独特结果的数量从11(即)2-12增加到13(即)0-12。根据中心极限定理,结果6的出现次数最多6是所有结果的中位数 此外,我还对打印分发版的最终for循环进行了更改 我还纠正了@Axe319提到的打字错误
from random import randint
print("***CATAN DICE***")
normal = [0,0,0,0,0,0,0,0,0,0,0,0,0]
for i in range(0, 100000):
a=randint(0, 6)
b=randint(0, 6)
throw = a+b
if throw == 0:
normal[0]+=1
if throw == 1:
normal[1]+=1
if throw == 2:
normal[2]+=1
if throw == 3:
normal[3]+=1
if throw == 4:
normal[4]+=1
if throw == 5:
normal[5]+=1
if throw == 6:
normal[6]+=1
if throw == 7:
normal[7]+=1
if throw == 8:
normal[8]+=1
if throw == 9:
normal[9]+=1
if throw == 10:
normal[10]+=1
if throw == 11:
normal[11]+=1
if throw == 12:
normal[12]+=1
i=0
j=0
for i in range(len(normal)):
print(i, end = " ")
for j in range(int(normal[i]/1000)):
print("*",end="")
print(f"{normal[i]}\n")
结果如下:
***CATAN DICE***
0 **2019
1 ****4245
2 ******6000
3 ********8255
4 **********10232
5 ************12314
6 **************14143
7 ************12208
8 **********10179
9 ********8170
10 ******6123
11 ****4060
12 **2052
您使代码变得比需要的更复杂,并且在这个过程中引入了一些bug。我通过直接从结果
throw
计算要更新的索引,消除了if
语句链。我消除了循环以逐个获得星星,使用舍入而不是整数截断(floor)来获得星星数,并对总和的值进行右对齐。我还将代码分为初始化、生成和输出阶段,以便于阅读和更改正在运行的试用次数。不用多说,代码:
来自随机导入randint
#初始化
n=100000
计数=[0表示uu在范围(11)]#不太容易出现手动错误计数错误
#生成:不需要if,直接从抛出结果计算索引
对于范围(n)中的i:
投掷=随机数(1,6)+随机数(1,6)
计数[投掷-2]+=1
#输出
打印(***卡坦骰子***\n)
对于范围内的i(len(count)):
星号=”+“*”*四舍五入(计数[i]/(n//100))
打印(f“{i+2:>2}”+星+f“{count[i]}”)
产生如下输出:
***卡坦骰子***
2 ***2741
3 ******5637
4 ********8210
5 ***********11099
6 **************14068
7 *****************16659
8 **************13821
9 ***********11074
10 ********8365
11 ******5500
12 ***2826
如果您希望将结果从0更改为6,而不是从1更改为6,则可以很容易地修改此值
最后,为了好玩,这里有一个更通用的实现,这样你就可以玩骰子的数量和范围了
来自随机导入randint
#初始化
n=100000次试验
骰子数=2#骰子数
#模具的低值和高值
模头=1
模具hi=6
最小结果=数量骰子*骰子数
num_outcours=num_dice*die_hi-min_outcours+1
#生成:不需要if,直接从抛出结果计算索引
计数=[0表示范围内的u(num_结果)]
对于范围(n)中的i:
投掷=范围内(数值骰子)的总和
计数[投掷-最小结果]+=1
#输出
打印(***卡坦骰子***\n)
对于范围内的i(num_结果):
星号=”+“*”*四舍五入(计数[i]/(n//100))
打印(f“{i+min_结果:>3}”+stars+f“{count[i]}”)
我认为这说明了不硬连接一系列
if
语句的好处。首先你应该有randint(1,6)而不是randint(0,6)。如果你使用numpy,你可以这样做:np.unique(np.random.randint(1,7,[100000,2])。sum(1),return\u counts=True)
我尝试了两种方法:randint(1,6)和randint(0,6)但是当我使用1,6时,我得到8的频率更高,这是错误的。你的问题在于你的if
语句。如果throw==3:,则出现两次。你的双5560
就是一个提示。这里没有正态分布。两个离散制服的总和具有离散的三角形分布。您应该用单个语句normal[throw]+=1
替换庞大的if…
。此外,CLT在确定一笔金额的期望值方面也不起作用。