学会编一个按概率抽奖的函数!Python3实现为每个随机事件指定一个抽奖概率

最近编写一个模拟游戏抽奖的程序,需要使用到标准库random模块,但是使用的时候出现了一个很大的问题,游戏中的抽奖概率是2.23%,是一个二位小数,并带有百分号,化成小数是0.0223,也就是说一万次抽奖中约有223次抽中,如果把所有的抽奖结果放进一个列表并用random.choice函数的话,那需要一万项,其中223项为目标结果,这样对于程序员来说工作量实在太大,所以应该编写一个对每个事件制定一个概率,让程序按照概率进行抽奖的函数。

在这里给大家推荐一个比较好的方法,可以实现每个事件有对应的出现概率:
注:在代码块中events是所有可能出现的事件的列表,values是每个事件的概率的列表,和events一一对应,points是所有点的列表,num则是挨个检查是否符合事件的一个不起眼的变量。

from random import *
def sampling(dictionary):
    #本函数的原理是代数化的几何概率
    '''按照参数所指定的概率随机抽取一个元素,传入的参数始终是一个字典
    其中键为事件,值为事件发生的概率,所有的值必须是介于0和1的浮点数
    且所有值的和应为1,若不是这样,则抛出异常。
    不支持无法化为有限小数的分数'''
    events=[]
    values=[]
    
    for i in dictionary:
        events.append(i)#将事件从字典中分离出来,因为dictionary.keys()返回的不是一个列表
        values.append(dictionary[i])#将每个事件的概率也分离出来,与事件一一对应
        
    if sum(values)!=1:#如果概率加起来并不是1,则抛出异常
        raise ValueError('All values must be float numbers between 0 and 1 and the sum of all values should be 1.')
    
    points=[]
    for i in values:
        point=0
        a=values.index(i)
        while a>=0:#下面将参数中提供的每个事件的概率转换为一个个类似数轴上的点
            point+=values[a]
            a-=1
        points.append(point)
    points.insert(0,0)#把数轴原点0也加入列表
    
    #假设在数轴上,第一个点是0,第一个点和第二个点的距离是第一个事件的概率
    
    #第二个点到第三个点的距离是第二个事件的概率,所以第三个点在数轴上的值是前两个事件概率的和,以此类推
    
    result=random()#在0到1之间选取一个数
    
    for num in points:
        if num<=result<points[points.index(num)+1]:#这里必须是小于等于和小于,这样保证不会正好抽到1引发特殊情况而产生异常
            return events[points.index(num)]#从events中获取result所在区间对应的事件

试了一下,效果还可以,适合多种事件,只要不是容易产生浮点数误差的无限循环小数就不会有问题,对于三分之一这种概率还是不支持的,像这种情况,如果是等可能事件,使用random.choice还是可以的。

本文为作者原创,转载请注明出处。

-----------------END-------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值