思路
随机数生成范围:0-1(不包含1) Math.random();
概率 = 权重 / 总权重 (概率一定是 小于 1的)
判断概率是在哪个权重概率范围内
//举例 总权重为10 随机数为 0.431213
//第一个奖品权重为 2 权重概率为 0.2
//第二个奖品权重为 3 权重概率为 0.3
//第三个奖品权重为 4 权重概率为 0.4
//第四个奖品权重为 1 权重概率为 0.1
1:循环奖品,计算权重概率
2:第一个奖品权重概率 0.2 是否 > 随机数0.431213 不大于继续当前循环
3:第二个奖品权重概率 0.3
当不是第一个奖品时,需要加上之前的权重概率 : 0.3 + 0.2 = 0.5 是否 > 随机数0.431213 大于 = 中奖
当循环到第二个奖品时 随机数一定是大于 上一个奖品的权重概率的
public String lootteryDraw(List<LotteryDraw> lotteryDrawList
{
//总权重
BigDecimal brandSumWeight = new BigDecimal(0);
//中奖ID
String lotteryDrawId = "";
//1:计算总权重
for(LotteryDraw lotteryDraw : lotteryDrawList)
{
brandSumWeight = brandSumWeight.add(new BigDecimal(lotteryDraw.getWeight()));
}
// do{}while() 判断如果lotteryDrawId为空 出现的肯是
//所有权重概率和相加不等于1 因为 权重 / 总权重 会有除不尽
//随机数正好大于 所有权重概率和 小于 1
//例如:随机数0.9999 权重概率和: 0.999999
do
{
BigDecimal probability = BigDecimal.valueOf(Math.random());
//判断随机数是否等于0 如果等于0 重新随机
while(probability.doubleValue() == 0)
{
probability = BigDecimal.valueOf(Math.random());
}
BigDecimal precent = new BigDecimal(0);
for(int i = 0; i < lotteryDrawList.size(); i++)
{
LotteryDraw lotteryDraw = lotteryDrawList.get(i);
BigDecimal bigDecimalWeight = new BigDecimal(lotteryDraw.getWeight());
//权重概率相加 除不尽 小数8为 四舍五入
precent = precent.add(bigDecimalWeight.divide(brandSumWeight,8,BigDecimal.ROUND_HALF_UP));
double resultStart = probability.subtract(precent).doubleValue();
if(resultStart > 0)
{
continue;
}
else
{
//抽中
lotteryDrawId = lotteryDraw.getLotteryDrawId();
break;
}
}
}
while (lotteryDrawId.equals(""));
return lotteryDrawId;
}
网友评论