國內(nèi)好用的五款開源建站系統(tǒng)企業(yè)培訓體系搭建
紅包算法
首先,如果紅包只有一個,本輪直接使用全部金額,確保紅包發(fā)完。
然后,
計算出本次紅包最少要領(lǐng)取多少,才能保證紅包領(lǐng)完,即本輪下水位;
本輪最多領(lǐng)取多少,才能保證每個人都領(lǐng)到,即本輪上水位。
主要方式如下:
計算本次紅包金額下水位:假設(shè)本次領(lǐng)到最小值1分,那接下來每次都領(lǐng)到200元紅包能領(lǐng)完,那下水位為1分;如果不能領(lǐng)完,那按接下來每次都領(lǐng)200元,剩下的本輪應全部領(lǐng)走,是本輪的下水位。
計算本輪紅包上水位:假設(shè)本輪領(lǐng)200元,剩下的錢還足夠接下來每輪領(lǐng)1分錢,那本輪上水位為200元;如果已經(jīng)不夠領(lǐng),那按接下來其他領(lǐng)1分,計算本輪的上水位。
為了使紅包金額不要太懸殊,使用紅包均值調(diào)整上水位。如果上水位金額大于兩倍紅包均值,那么使用兩倍紅包均值作為上水位。換句話說,每一輪搶到的紅包金額,最高為兩倍剩下紅包的均值。
最后,獲取隨機數(shù)并用上水位取余,如果結(jié)果比下水位還小,則直接使用下水位,否則使用隨機金額為本輪拆到金額。
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Random;public class RandomRedPocket implements RedPocket {BigDecimal avgAmount;private BigDecimal totalAmount;private BigDecimal lowestAmount;private Integer remainNum;public RandomRedPocket(BigDecimal totalAmount, int num) {this.totalAmount = totalAmount;this.remainNum = num;this.avgAmount = totalAmount.divide(new BigDecimal(num), 2, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(2));this.lowestAmount = BigDecimal.valueOf(0.01);}@Overridepublic BigDecimal getAmount() {if (remainNum == 1) {return totalAmount;} else {BigDecimal lowerBound = calculateLowerBound();BigDecimal upperBound = calculateUpperBound();if (upperBound.compareTo(avgAmount) > 0) {upperBound = avgAmount;}remainNum = remainNum - 1;BigDecimal randomAmount = genRandomMoney(lowerBound, upperBound);totalAmount = totalAmount.subtract(randomAmount);return randomAmount;}}private BigDecimal calculateUpperBound() {//后面每人獲取最低紅包,需要剩下多少錢BigDecimal multiplied = lowestAmount.multiply(BigDecimal.valueOf(remainNum - 1));BigDecimal upperBound = totalAmount.subtract(multiplied);return upperBound;}//計算本次紅包,最低領(lǐng)取多少金額,才能保證紅包領(lǐng)完//此處可進一步完善private BigDecimal calculateLowerBound() {return BigDecimal.valueOf(0.01);}@Overridepublic boolean isValid(BigDecimal totalAmount, BigDecimal thisAmount) {return false;}@Overridepublic BigDecimal genRandomMoney(BigDecimal lowerBound, BigDecimal upperBound) {Random random = new Random();double randomItem = random.nextDouble();BigDecimal decimal = upperBound.subtract(lowerBound).multiply(new BigDecimal(randomItem)).add(lowerBound);decimal = decimal.setScale(2, RoundingMode.HALF_UP);return decimal;}
}