微信抢红包大家都很熟悉。
现在考虑这样一种情况:将 100 元的红包分为 10 份,每份最低 5 元最高 15 元,金额精确到 0.01 元。那么如果算法没问题的话,每个人的期望值自然是平均值,即 100 元 /10 人=10 元 /人。
最先想到的算法:
在 5~15 内生成随机数,即为当前用户的红包值。这种方式会出现分配后余额不足以按要求继续分配(剩余过多或过少)的情况,导致之后的红包内容均为最大值或最小值。这似乎也是微信红包的算法。
后来考虑了一种避免后期红包数值统一于极值的方式:
根据红包总份数 N 生成 N 个 0~1 内的随机数,按照各随机数在这些随机数之和中所占的比重,分配可分配的那部分金额(总金额 - 最小值 * 份数)。当出现不符合分配要求的情况时,对已求得的每个随机数进行求根运算(也可以是其他运算,只要减小方差就行)并重新求和。(代价是必须一次性得出所有红包的分配方案)
然后问题来了:
我统计了上述两种方法都结果,均没有出现众数集中在平均值的结果:
算法 1:

算法 2:

按我的理解,众数应当接近于期望值才比较理想。求大神指导下问题所在,以及有没有更好的算法





