python 实现模拟微信发红包
红包逻辑制定:
分配:红包里的金额怎么算?为什么出现各个红包金额相差很大?
答:随机,额度在0.01和(剩余平均值x2)之间。
例如:发100块钱,总共10个红包,那么平均值是10块钱一个,那么发出来的红包的额度在0.01元~20元之间波动。
当前面3个红包总共被领了40块钱时,剩下60块钱,总共7个红包,那么这7个红包的额度在:0.01~(60/7*2)=17.14之间。
注意:这里的算法是每被抢一个后,剩下的会再次执行上面的这样的算法
这样算下去,会超过最开始的全部金额,因此到了最后面如果不够这么算,那么会采取如下算法:保证剩余用户能拿到最低1分钱即可。
如果前面的人手气不好,那么后面的余额越多,红包额度也就越多,因此实际概率一样的。
import random def luck_money(total, num): tmp = num for i in range(num-1): #循环num-1次,根据[0.01 ,total/num*2]的规则生成9个红包 hb = round(random.uniform(0.01, total/num*2), 2) total = total - hb if total <= num*0.01: # 为了保证每个人最少能拿到0.01元,则做一个判断,如果余额不足的情况,上一个红包的金额=余额-(剩余的人数*0.01),余下所有人拿到的都是0.01 total = total + hb num -= 1 hb = total - num*0.01 yield round(hb, 2) for j in range(i+1, tmp): #接着上面的循环, yield 0.01 break #循环完后结束上次循环 yield hb num -= 1 else: #最后一个红包如果余额还有,所有余额给分给最后一个 total = round(total, 2) yield total g = luck_money(100, 10) for i in g: print(i)
红包规则来源于:https://blog.csdn.net/lb_383691051/article/details/79379384
第二个版本,使用的类似锯木头的思想,随机长度的锯一整根木头,最后得到多段随机长度的木头。
import random def redbags(money, num): while True: choice = random.sample(range(1, int(money * 100)), num - 1) choice.extend([0, money*100]) choice.sort() for i in range(len(choice)-1): if (choice[i+1] - choice[i]) > (money * 100 / num * 2): #这里控制红包最大的额度 break else: return [(choice[i + 1] - choice[i]) / 100 for i in range(num)],choice