本文只描述了根据权重实现抽奖的底层工具类
public class LotteryUtil {
public static void main(String[] args) {
List<Prize> prizes = new ArrayList<>();
Prize p2 = new Prize();
p2.setPrizeName("唇膏");
p2.setPrizeWeight(5.5);
prizes.add(p2);
Prize p3 = new Prize();
p3.setPrizeName("香水");
p3.setPrizeWeight(9.8);
prizes.add(p3);
Prize p1 = new Prize();
p1.setPrizeName("眼影");
p1.setPrizeWeight(4.5);
prizes.add(p1);
Prize p4 = new Prize();
p4.setPrizeName("谢谢参与");
p4.setPrizeWeight(66);
prizes.add(p4);
Prize p5 = new Prize();
p5.setPrizeName("抽奖次数");
p5.setPrizeWeight(14.2);
prizes.add(p5);
//所有奖品权重总和要等于100
int[] result = new int[prizes.size()];
System.out.println("抽奖开始");
for (int i = 0; i < 1000; i++)// 打印100个测试概率的准确性
{
int selected = LotteryUtil.getPrizeIndex(prizes);
System.out.println("第" + i + "次抽中的奖品为:" + prizes.get(selected).getPrizeName());
result[selected]++;
System.out.println("--------------------------------");
}
System.out.println("抽奖结束");
System.out.println("每种奖品抽到的数量为:");
System.out.println("唇膏:" + result[0]);
System.out.println("香水:" + result[1]);
System.out.println("眼影:" + result[2]);
System.out.println("谢谢参与:" + result[3]);
System.out.println("抽奖次数:" + result[4]);
}
/**
* 根据Math.random()产生一个double型的随机数,判断每个奖品出现的概率
*
* @param prizes
* @return random:奖品列表prizes中的序列(prizes中的第random个就是抽中的奖品)
*/
public static int getPrizeIndex(List<Prize> prizes) {
int random = -1;
try {
//计算总权重
double sumWeight = 0;
for (Prize p : prizes) {
sumWeight += p.getPrizeWeight();
}
//产生随机数
double randomNumber = Math.random();
//根据随机数在所有奖品分布的区域并确定所抽奖品
double d1 = 0;
double d2 = 0;
for (int i = 0; i < prizes.size(); i++) {
d2 += Double.parseDouble(String.valueOf(prizes.get(i).getPrizeWeight())) / sumWeight;
if ( i == 0 ) {
d1 = 0;
} else {
d1 += Double.parseDouble(String.valueOf(prizes.get(i - 1).getPrizeWeight())) / sumWeight;
}
if ( randomNumber >= d1 && randomNumber <= d2 ) {
random = i;
break;
}
}
log.info("getPrizeIndex===>sumWeight:{}--randomNumber:{}--prizes:{}--抽中的奖品是:{}", sumWeight, randomNumber, prizes, prizes.get(random).getPrizeName());
} catch (Exception e) {
throw new SimpleException("生成抽奖随机数出错,出错原因:" + e.getMessage());
}
return random;
}
@Data
public static class Prize {
/**
* 奖品id
*/
private Long id;
/**
* 奖品名称
*/
private String prizeName;
/**
* 奖品权重
*/
private double prizeWeight;
}
}