打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
用 Python 实现一个简单的微信红包算法

这里我给一个简单的实现方案。

基本思路就是,有多少个红包,就循环多少次,每一次,在剩下的钱里面随机出一个值作为这个红包的金额,然后把金额从总金额中扣除。这里要注意,需要保证每个人至少能拿得到 1 分钱。只剩最后一个人时,拿走剩下所有的金额。另外,为了保证计算时候方便,采用“分”作为金额的计算单位。

代码:

import random

def redPacket(people, money):

    result = []

    remain = people

    for i in range(people):

        remain -= 1

        if remain > 0:

            m = random.randint(1, money - remain)

        else:

            m = money

        money -= m

        result.append(m / 100.0)

    return result

redPocket 就是分配红包的函数,people 是红包总个数,money 是总金额(单位:分)。返回值 result 是最终的分配结果,单位换算成了“元”。

其中,为了保证每个人都至少拿到 1 分钱,所以随机数的取值范围为 1 到 money - remain,也就是为剩下的人每人至少预留 1 分钱。

添加一下输入:

people = int(input('红包个数:\n'))

money = int(input('总金额:\n') * 100)

redPocket(people, money)

这里意思一下,不做严格的输入检测了,没有判断金额是否够分,或者超过限额之类。总金额输入的时候是“元”,在代码里再转成“分”来计算。

运行下看结果是否正确。

红包个数:

4

总金额:

30

[13.88, 14.38, 0.18, 1.56]

总和上没有问题,但多跑几次你会发现,前面的人往往比后面的人要多拿,而还多不少。这是因为前面的人有可能在一开始就随机到大金额,而让后面人没有机会。于是我决定再加个限制:

def redPacket(people, money):

    result = []

    remain = people

    max_money = money / people * 2

    for i in range(people):

        remain -= 1

        if remain > 0:

            m = random.randint(1, min(money - remain, max_money))

        else:

            m = money

        result.append(m / 100.0)

        money -= m

    return result

注意增加的 max_money,它是平均金额的 2 倍,也就是说,你有再好的运气,也不会拿到超过两倍均值的红包。这个简单粗暴的限制基本可以解决差值过大的问题。

在随机金额的地方,原本的上限会和 max_money 相比较,取其中较小的一个。

再运行下,结果是不是看上去像那么回事儿了。

这个方法比较容易实现,但从概率上来说并不公平。我觉得另一个更好的方案是,先产生 people 个 0 到 1 之间的随机数,得到这些随机数的总和 s,再通过

x / s * money

得出每一个红包对应的金额。这个方案的代码实现留给你们,注意可能出现小数末位截断的误差。当然你也可以尝试一套自己的方案。

我不知道微信究竟是怎么实现的。但从实际效果来看,他们也并没有对红包之间的差值做过多限制。可能是觉得这样才有意思吧。

知乎上有一个相关问题,里面有更严谨的分析:

微信红包的随机算法是怎样实现的?

https://www.zhihu.com/question/22625187


本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
微信红包的算法实现探讨
PHP实现发红包程序
抢红包的红包生成算法
微信红包分配算法代码
“微信红包”用英文怎么说?
微信红包随机算法初探
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服