当前位置: 首页 > 后端技术 > Python

Python抢红包算法仿真

时间:2023-03-25 20:36:55 Python

红包算法仿真本文是随机抢红包的仿真算法,仅供参考。方法本文采用双均值法。在此之前,先说说普通的随机方法。普通随机法该方法的原理是:每次取值在[最小值,剩余量值]之间随机选择。假设红包数量为88.88,红包个数为8,那么第一个人收到的金额将从[0.01,88.88]中取出,假设值为20.20,则剩余金额为68.68。第二次领取金额会从[0,01,68.68]中取,依此类推...这里我们可以很明显的看出这种方式的缺点,前面红包的金额范围更大,更容易获得红包金额较大。我们来看一下双均值法的原理。双均值法的原理是:每次在【最小值,红包剩余数量/人数*2】的区间内取值。假设红包数量为88.88,红包数量为8,理想情况下,该方法的实现效果:第一人领取红包数量范围为[0.01,88.88/8*2],即[0.01,22.22]之间的随机数获取金额。假设平均值为11.11,则剩余金额为77.77;第二个人收到红包,金额范围为[0.01,77.77/7*2],即在[0.01,22.22]之间随机获得的金额。假设平均值为11.11,则剩余金额为66.66;等等……这种方法并不完美。以上是在非常理想的情况下收到的红包数量,每个人的数量范围是比较公平的。但是当其中一个接近区间内的最小值或最大值时,就会影响后面的区间。当该值接近最小值时,后面收到的红包数量范围会变大;否则,它会变小。这也是这种方法的缺点。代码实现#-*-coding:utf-8-*-'''@File:red_pa??cket.py@Time:2020/01/2920:41:36@作者:大梦三千秋@联系人:yiluolion@126.com'''#importlibhereimportrandomdefget_random_red_pa??cket(total_amount,quantities):'''args:total_amount:红包总量Quantities:红包个数Returns:返回每个人收到的红包数量person'''#用于存储每个人收到的红包数量amount_list=[]#抢到红包的人数person_num=quantities#红包涉及的金额可以保留2位小数#乘以100计算先,再除以100处理小数部分cur_total_amount=total_amount*100#这里用的是双平均法#除了最后一个人,先处理之前收到的红包金额#最后剩下的金额就是_在范围内的最后一个人(数量-1):数量=随机.randint(1,cur_total_amount//person_num*2)#每次减去当前随机数量,剩余数量用于下一次随机获取cur_total_amount-=amountperson_num-=1amount_list.append(amount/100)amount_list.append(cur_total_amount/100)#print(sum(amount_list))returnamount_listdefmain():amount_list=get_random_red_pa??cket(88.88,8)foramount_list:print('红包金额:{}'.format(amount))if__name__=="__main__":main()实现效果红包金额:18.64红包金额:10.32红包金额:9.82红包数量:9.72红包数量:5.11红包数量:19.16红包数量:15.15红包数量:0.96延长线段切割法该方法的思路是:将红包总量视为一条线段,每个人收到的红包数量就是子线段除以线段。当红包的数量为第i次时,即第i个人抢到了红包。切割线段,确定i-1个切割点。当切割点确定后,即确定了子线段的长度。领取红包时,只需依次领取相应数量的子线即可。以上是本文的主要内容。欢迎关注微信公众号《书所集录》