年末项目组需要做一个抽奖活动,奖品池有很多奖品,运营可以配置每个奖品的爆率,这篇文章给出一个简单的实现。
抽奖
首先有个必要条件是,奖品池的奖品总概率不能超过 1。
算法步骤:
- 把所有奖品放在一个数组内;
- 把奖品的概率分配到 0~1 的区间内;
- 生成一个 0~1 的随机数;
- 如果随机数落在区间内,则中奖,反之亦然。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| public class Lottery {
public static void main(String[] args) { List<Prize> prizes = new ArrayList<>(); prizes.add(new Prize(0.00001, "手机")); prizes.add(new Prize(0.00000001, "电脑"));
printPrize(prizes);
int count = 0; for (int i = 0; i < 10000000; i++) { if (doLottery(prizes)) count++; }
System.out.println("中奖次数:" + count); }
private static boolean doLottery(List<Prize> prizes) { double num = Math.random();
double start = 0; for (Prize p : prizes) { double end = start + p.possibility; if (num > start && num < end) { System.out.println(" 中奖:" + p.name + " " + double2String(num));
return true; }
start = end; }
return false; }
private static class Prize {
double possibility;
String name;
private Prize(double possibility, String name) { this.possibility = possibility; this.name = name; } }
private static void printPrize(List<Prize> prizes) { double start = 0; for (Prize p : prizes) { double end = start + p.possibility; System.out.println(p.name + ": [ " + double2String(start) + " - " + double2String(end) + " ]"); start = end; } }
private static String double2String(double d) { DecimalFormat df = (DecimalFormat) NumberFormat.getInstance(); df.setMaximumFractionDigits(10); return df.format(d); } }
|
执行结果:
1 2 3 4 5
| 手机: [ 0 - 0.0000001 ] 电脑: [ 0.0000001 - 0.0000002 ] 中奖:电脑 0.0000001615 中奖:手机 0.0000000219 中奖次数:2
|