欢迎来到Louis的博客

人生三从境界:昨夜西风凋碧树,独上高楼,望尽天涯路。 衣带渐宽终不悔,为伊消得人憔悴。 众里寻他千百度,蓦然回首,那人却在灯火阑珊处。
扩大
缩小

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

 

posted on 2018-08-21 14:49  Louiszj  阅读(2605)  评论(0编辑  收藏  举报

导航