Appearance
简介:拼手气类的游戏,更能激发用户购物和社交的趣味性,以及游戏竞争心理,拼手气类的活动甚至可以影响人们消费心理。拼手气红包就是最简单的例子。
顾名思义,二倍均值算法的核心思想是根据每次剩余的总金额M和剩余人数N,执行M/N再乘以2的操作得到一个边界值E,然后制定一个从0到E的随机区间,在这个随机区间内将产生一个随机金额R, 此时总金额M将更新为M-R,剩余人数N更新为N-1。再继续重复上述执行流程,以此类推,直至最终剩余人数N-1为0,即代表随机数已经产生完毕。
两种生成红包的方式对比
拼手气红包有两种计算方法,一种是预计算,一种是实时算。
预计算在生成拼手气红包的时候,会提前根据总金额M和红包人数N,生成每个红包的金额,在抢红包的过程中,只需要从金额列表中取出,直至取完。这种方式需要占用额外的存储空间并且增加额外的I/O,在高并发场景下并不是最优的解决方案。 实时算采用的是纯内存计算,不需要预算空间存储,实时性很高。
预计算代码实现
java
/**
* 拆包
*
* @param totalAmount 总金额
* @param totalCount 总数量
* @return 拆包结果
*/
public static List<Integer> divide(int totalAmount, int totalCount) {
if (totalAmount < 0) {
throw new IllegalArgumentException("totalAmount cannot be less than the 0");
}
if (totalAmount < totalCount) {
throw new IllegalArgumentException("totalAmount cannot be less than the totalCount");
}
List<Integer> result = new ArrayList<>();
Random random = new Random();
// 剩余金额
int remainingAmount = totalAmount;
// 剩余数量
int remainingCount = totalCount;
for (int i = 0; i < totalCount - 1; i++) {
// 本红包的最大值 人数 / 金额 * 2
int max = 2 * (remainingAmount / remainingCount);
// 随机生成一个 1 到 max 之间的金额
int amount = 1 + random.nextInt(max - 1);
// 更新剩余金额与人数
remainingCount--;
remainingAmount = remainingAmount - amount;
result.add(amount);
}
// 添加最后剩余的金额
result.add(remainingAmount);
return result;
}