在日常 Java 开发中,业务上可能会遇到一些拉新引流的相关需求,比如:发放红包、签到领现金等(这里以发放红包为例)。
那么就会面临一个问题:怎么保证红包在领取时,金额随机,且至少能领0.01元?
一般会有两种红包方案:
“拼手速”红包
我们假设有一个100元的红包。第一个人可以在0.01元到100元之间,随机地分配到一定金额。
如果我们把第一个人抽到的所有可能的金额都计算在内,并取个平均值,那么他平均能获得50元。
这50元在数学上还有个形象的名字,叫作数学期望。
既然是“期望”,就总会有落空的时候,也不排除会有意外的惊喜。
因此,第一个人抽到的金额可能不足50元,也可能大于50元。
如上所述,虽然每一个人在抢红包时都是随机分配数额,貌似很公平,但总会有“先来后到”。
“雨露均沾”红包
原理其实很简单,就是把每个人可能抽到的最高金额强行降低,即使你是第一个打开红包的人,也不允许你任意的从0.01到100元之间抽取金额。
这时候就需要有个相对“公平”的算法来计算相应金额:二倍均值法
假设红包总金额是X,红包个数为Y,每个红包的最低金额是0.01元
那么每次抢到的红包金额的范围在 (0.01, (X/Y) *2) 之间。
即:每次运算时,在 0.01 ~ (剩余金额 / 剩余个数 * 2) 的范围内随机取值
也就是最大值为:0~100的随机值 / 100 * (剩余金额 /