本文实例为大家分享了java抽奖算法,供大家参考,具体内容如下
1. 算法分析
根据概率将奖品划分区间,每个区间代表一个奖品,然后抽取随机数,反查落在那个区间上,即为所抽取的奖品。
2. 代码
核心算法
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
|
public class Arithmetic {
// 放大倍数
private static final int mulriple = 1000000 ;
public int pay(List<Prize> prizes) {
int lastScope = 0 ;
// 洗牌,打乱奖品次序
Collections.shuffle(prizes);
Map<Integer, int []> prizeScopes = new HashMap<Integer, int []>();
Map<Integer, Integer> prizeQuantity = new HashMap<Integer, Integer>();
for (Prize prize : prizes) {
int prizeId = prize.getPrizeId();
// 划分区间
int currentScope = lastScope + prize.getProbability().multiply( new BigDecimal(mulriple)).intValue();
prizeScopes.put(prizeId, new int [] { lastScope + 1 , currentScope });
prizeQuantity.put(prizeId, prize.getQuantity());
lastScope = currentScope;
}
// 获取1-1000000之间的一个随机数
int luckyNumber = new Random().nextInt(mulriple);
int luckyPrizeId = 0 ;
// 查找随机数所在的区间
if (( null != prizeScopes) && !prizeScopes.isEmpty()) {
Set<Entry<Integer, int []>> entrySets = prizeScopes.entrySet();
for (Map.Entry<Integer, int []> m : entrySets) {
int key = m.getKey();
if (luckyNumber >= m.getValue()[ 0 ] && luckyNumber <= m.getValue()[ 1 ] && prizeQuantity.get(key) > 0 ) {
luckyPrizeId = key;
break ;
}
}
}
if (luckyPrizeId > 0 ) {
// 奖品库存减一
}
return luckyPrizeId;
}
}
|
Prize bean
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
|
public class Prize {
/**
* 奖品唯一标示
*/
private Integer prizeId;
/**
* 中奖概率
*/
private BigDecimal probability;
/**
* 奖品数量
*/
private Integer quantity;
public Integer getPrizeId() {
return prizeId;
}
public void setPrizeId(Integer prizeId) {
this .prizeId = prizeId;
}
public BigDecimal getProbability() {
return probability;
}
public void setProbability(BigDecimal probability) {
this .probability = probability;
}
public Integer getQuantity() {
return quantity;
}
public void setQuantity(Integer quantity) {
this .quantity = quantity;
}
}
|
3. 测试
prize1概率: 5%
prize2概率: 10%
prize3概率: 15%
prize4概率: 20%
prize5概率: 50%
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
63
64
65
66
67
68
|
public class Test {
public static void main(String[] args) {
List<Prize> prizes = new ArrayList<Prize>();
Prize prize1 = new Prize();
prize1.setPrizeId( 1 );
prize1.setProbability( new BigDecimal( 0.05 ));
prize1.setQuantity( 1 );
prizes.add(prize1);
Prize prize2 = new Prize();
prize2.setPrizeId( 2 );
prize2.setProbability( new BigDecimal( 0.10 ));
prize2.setQuantity( 10 );
prizes.add(prize2);
Prize prize3 = new Prize();
prize3.setPrizeId( 3 );
prize3.setProbability( new BigDecimal( 0.15 ));
prize3.setQuantity( 20 );
prizes.add(prize3);
Prize prize4 = new Prize();
prize4.setPrizeId( 4 );
prize4.setProbability( new BigDecimal( 0.20 ));
prize4.setQuantity( 50 );
prizes.add(prize4);
Prize prize5 = new Prize();
prize5.setPrizeId( 5 );
prize5.setProbability( new BigDecimal( 0.50 ));
prize5.setQuantity( 200 );
prizes.add(prize5);
int prize1GetTimes = 0 ;
int prize2GetTimes = 0 ;
int prize3GetTimes = 0 ;
int prize4GetTimes = 0 ;
int prize5GetTimes = 0 ;
Arithmetic arithmetic = new Arithmetic();
int times = 1000 ;
for ( int i = 0 ; i < times; i++) {
int prizeId = arithmetic.pay(prizes);
switch (prizeId) {
case 1 :
prize1GetTimes++;
break ;
case 2 :
prize2GetTimes++;
break ;
case 3 :
prize3GetTimes++;
break ;
case 4 :
prize4GetTimes++;
break ;
case 5 :
prize5GetTimes++;
break ;
}
}
System.out.println( "抽奖次数" + times);
System.out.println( "prize1中奖次数" + prize1GetTimes);
System.out.println( "prize2中奖次数" + prize2GetTimes);
System.out.println( "prize3中奖次数" + prize3GetTimes);
System.out.println( "prize4中奖次数" + prize4GetTimes);
System.out.println( "prize5中奖次数" + prize5GetTimes);
}
}
|
结果:
通过1000次抽取,我们看出算法精度还是很高的。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。