/Lucky-money-simulator

【练习程序】个人尝试实现QQ、微信红包模拟程序,仅兼容Python3.2以上版本

Primary LanguagePython

QQ红包模拟器

注意:这只是一个练习程序。

作者尝试实现QQ拼手气红包,QQ拼手气红包具有这些特点:

  • 金额数为两位小数;
  • 每个人都可以领到钱;
  • 每个红包的金额随机分配;
  • 所有红包的金额数总和等于预设的金额。

本程序仅可运行于Python3.5以上的版本,程序没有判断输入是否合法,如果输入意外的数值,将得到不合理的结果。

2017年1月1日更新

当初写完这个程序之后,做了统计,发现产生的随机数分布存在一些问题。 整体分布与正态分布相似,但比平均数小的红包数量偏多,比平均数多的红包数量偏少。 容易出现一个大红包+一组小红包这样的组合。

然后发现知乎上有人提供了据说是内部人员提供的算法(微信红包)。 提供了一份Java代码。 代码很简单,阅读之后总结官方抽红包算法如下: (已简化) 1.如果红包数量为1,返回余额,否则继续; 2.随机产生一个从0.01到平均数的两倍之间的数值,保留两位小数; 3.从总额中扣除上一步得到的数值,红包剩余数量减1。

因为那段时间之后都很忙,也很少写个人爱好向的代码了。所以我也没更新这个repo。 根据官方算法,每次抽到的红包金额取值范围是0.01到平均数的两倍,所以,第一次抽的红包最多不超过 总额/个数*2 。 而最后抽的红包在极端情况下,有一定概率会得到 总额-0.01*(个数-1) 金额,当然,概率极小。 而第一次抽到超过算法上限的金额是不可能发生的情况。

这并不代表着抽红包越晚越划算,如果前几个抽取结果运气比较好,得到了较大的面额,剩余红包的平均金额变得更少,在该算法的限制下,最大金额上限更低。

所以,随着红包数量的减少,得到的金额的波动会逐渐增大(假设不知道之前的抽取结果)。也就是,越靠后,方差越大。

平均下来,早抢和晚抢区别不大。

结论: 如果希望风险小一些,赶紧抢比较好; 如果希望得到更多的钱,晚点抢比较好。

不过,红包数量有限,要想抢红包,看到就抢吧。

补上了真正的红包模拟器:red_packet.py

使用说明:

# 导入
from red_packet import RedPacket

# 发红包
rp = RedPacket(个数, 总金额)

# 抢红包
rp.get_money() # 返回金额,浮点型

# 检查红包是否被抢完
rp.is_empty()

同样没有判断输入是否合法,需要自行处理输入。

PS:刚才在QQ里测试了一下,QQ和微信的算法不一样。 PPS:QQ的随机更精确一些。

2020年9月28日更新

魔改为了中文编程版本1.0