public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
List<Integer> integers = randomGenerateHandler(880,10);
System.out.println(integers);
int count = 0;
for (Integer integer : integers) {
count += integer;
}
System.out.println(count);
}
}
/**
*
* @param totalAmount 总金额
* @param num 人数
* @return
*/
public static List<Integer> randomGenerateHandler(Integer totalAmount,Integer num) {
// 总金额转换
BigDecimal tAmount = new BigDecimal(totalAmount);
// 最小额转换
BigDecimal mAmount = new BigDecimal(RED_MIN_AMOUNT);
//剩余红包金额
BigDecimal remainAmount = tAmount.setScale(0, BigDecimal.ROUND_DOWN);
//剩余红包个数
Integer remainSize = num;
// 装配计算后的红包金额
List<Integer> amounts = new ArrayList<>();
for (int i = 1; i < num; i++) {
//前n-1个红包的金额,用随机算法
BigDecimal random = BigDecimal.valueOf(Math.random());
BigDecimal halfRemainSize = BigDecimal.valueOf(remainSize).divide(new BigDecimal(2), BigDecimal.ROUND_UP);
//计算单次红包的最大值,该算法也是微信的红包算法,可以保证抢红包的期望收益应与先后顺序无关,但后抢红包的方差更大,因此手气最佳更可能在后抢的人中诞生
BigDecimal max1 = remainAmount.divide(halfRemainSize, BigDecimal.ROUND_DOWN);
//同时,最大值需要保证,减去该红包后,剩下的红包足以满足剩余人数的最小金额
BigDecimal minRemainAmount = mAmount.multiply(BigDecimal.valueOf(remainSize - 1)).setScale(0, BigDecimal.ROUND_DOWN);
BigDecimal max2 = remainAmount.subtract(minRemainAmount);
//最终,单次红包的最大值等于两个最大值中较小的一个
BigDecimal max = (max1.compareTo(max2) < 0) ? max1 : max2;
BigDecimal amount = random.multiply(max).setScale(0, BigDecimal.ROUND_DOWN);
//每个红包的数额不能小于预设的最小金额
if (amount.compareTo(mAmount) < 0) {
amount = mAmount;
}
remainAmount = remainAmount.subtract(amount).setScale(0, BigDecimal.ROUND_DOWN);
remainSize = remainSize - 1;
amounts.add(amount.intValue());
}
//最后一个红包,金额等于剩余金额
BigDecimal amount = remainAmount;
amounts.add(amount.intValue());
return amounts;
}
拼手气红包,随机算法
最新推荐文章于 2023-09-04 12:02:00 发布