说明
最近测试一个刮卡抽奖的活动,为了估算一下刮卡集齐的难度,需要计算一下集齐卡片的所需卡片数的分布。
集卡活动规则
- 一套卡片一共8张,每张刮卡的概率都是0.125
- 每个人都可以获得无限多的抽奖次数,直到集齐8张卡
- 卡片没有库存,无法赠送
由于没有现在抽奖次数,直接使用概率计算难度较大(主要是也不会算),所以直接选用模拟多用户抽奖,收集抽奖结果的频次分布可以约等于概率分布
# -*- coding: utf-8 -*-
import numpy,random
import matplotlib.pyplot as plt
#发卡程序,这里简单的返回1-8的随机数,这个地方可以使用真正的发卡程序
def lottery():
return random.randint(1,8)
#模拟一个人集卡,集齐后返回刮卡次数
def hit():
#设置8张初始卡片都是0
card=[0, 0, 0, 0, 0, 0, 0, 0]
count=0
#为了方便模拟设置了最大刮卡次数99,当达到最大次数后不再抽奖直接返回count
while count<99:
c=lottery()
#将抽中的卡片对应记录设置为0
card[c-1]=1
count+=1
# 当八张卡片都是集齐后返回刮奖次数
if numpy.sum(card)==8:
return count
return count
#绘制分布曲线
def show(data):
x=numpy.linspace(0,100,100)
y=data
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.plot(x,y)
plt.title(u'集卡概率分布曲线(50万次模拟)')
plt.xlabel(u'中奖时的卡片数')
plt.ylabel(u"分布")
plt.show()
if __name__=="__main__":
#结果list存储抽奖结果
res=[0 for x in range(100)]
#n为模拟次数
n=500000
for i in range(n):
c=hit()
res[c]=res[c]+1
print(numpy.array(res)/n)
show(numpy.array(res)/n)
可以看出基本上40张以内绝大多数人就能集齐,一半的人20张以内可以集齐