抢红包算法 随机法和二倍均值法

对抢红包,大家肯定不陌生,但是,有想过抢红包是如何实现的嘛?今天就来讨论下抢红包的几种实现。

首先,我们得明确一下需求和需求的限制条件。红包主要有三点限制

  1. 抢到的总额 = 红包的总额,不能多也不能少了
  2. 最小值是0.01元,即每个人都有份
  3. 每个人抢到的红包金额,尽量平均

假设红包总金额是M元,抢红包的人数是N人

随机法1.0

随机法1.0–无脑随机法,是每个人抢红包,红包金额 = (1,红包剩余金额);最后一个人就不用随机了,无论剩下多少都是最后一个人的了。这种方法,优点是实现简单,但是,先抢的人会很赚,抢到大红包的概率很高,后面的人就比较吃亏了,甚至最后的人都没红包可抢

随机法2.0

随机法2.0–随机结果比例法(名字取的有点随意,没想到更形象生动的 -_-),是借鉴了上面说的 ”无脑随机法“,但是比较巧妙的避免了后面的人抢的少甚至抢不到的情况。思路是:每个人都随机,随机的范围是(0,M),然后把所有人的随机金额加起来得到random_total_money,把总金额M除以random_total_money,得到每个人的比例,然后把每个人的比例除以M。

举个例子:总金额是100元,抢红包人数是10人,随机范围是(1,M),假设10次随机的结果是200元,那100/200=0.5,那每个人实际抢到的红包金额=随机金额*0.5

但是,这个算法,有两个缺点:

  1. 对最小值的考虑不全面,如果比例值是0.5,而又有人随机随到了最小值0.01,那就违背了最开始所说的“限制2”

  2. 对无限循环小数考虑不全,如果算出的比例是1/3=0.333333…,那就得额外考虑

二倍均值法

假设总金额是M元,N个人,每次抢的金额=(0, (M/N) *2),比如,还是之前说的条件,金额100,人数10,

第一个人抢的金额是 (0,20),抢到的数值,根据正态分布,应该是10左右,远低于10的概率很小,同样远大于10的概率和很小,这里假设第一个人抢到的数值是10;

第二个人抢的金额是(0,90/9 *2)=(0,20),同第一个人,第二个人红包金额也应该是10附近;

剩下的人,以此类推。

查阅了“微信红包的架构设计”,里面就是使用的这个方法。但是,这个算法,也不是完美的,假如第一个人抢到15,第二个人的范围是(0,18.89),假如第二个人又抢到很高,那对后面的人是不利的

另外,还看到了一种叫“线性切割法”的算法,这个算法的思想是:把总金额数值,想象成一条绳子,对绳子切割N-1刀(N就是人的数量),每个人抢到的红包金额就是切割的绳子的占比,但是,这方法也不能避免“无限循环小数”问题;并且,对每个人抢到的金额尽量平均,该如何保证呢?需要考虑的点很多,时间复杂度、空间复杂度都比较高

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值