文章

java实现概率抽奖功能(正太分布)

记录一下java实现正太分布的抽奖功能, 以便以后使用

1. 先设置一下抽奖的实体类

该实体类中的内容主要包括抽奖的代码, 抽奖的概率, 以及抽奖的名称等等…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Data
public class Gift {
    private int id;         //奖品Id
    private String name;    //奖品名称
    private double prob;    //获奖概率
    
    @Override
    public String toString() {
        return "Gift{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", prob=" + prob +
                '}';
    }
}

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
  @RequestMapping(value = "/hello")
    public String getPrize(){

        Gift iphone = new Gift();
        iphone.setId(101);
        iphone.setName("SSR!");
        iphone.setProb(0.05D);

        Gift thanks = new Gift();
        thanks.setId(102);
        thanks.setName("SS");
        thanks.setProb(0.1D);

        Gift vip = new Gift();
        vip.setId(103);
        vip.setName("S!");
        vip.setProb(0.3D);

        Gift fouth = new Gift();
        fouth.setId(104);
        fouth.setName("A!");
        fouth.setProb(0.6D);

        List<Gift> list = new ArrayList<>();
        list.add(vip);
        list.add(thanks);
        list.add(iphone);
        list.add(fouth);

        for(int i=0;i<1000;i++){
            int index = drawGift(list);
            System.out.println(list.get(index));
        }
        return "";
    }

说明一下, id只是一个奖品代码,无实际意义, name是奖品名称, prob是奖品概率, 以上代码写了一个1000次循环抽奖,可以看到结果是很平均的

3. 抽奖工具类上传一下

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
public class DrawLotteryUtil {

    public static int drawGift(List<Gift> giftList) {

        if (null != giftList && giftList.size() > 0) {
            List<Double> orgProbList = new ArrayList<Double>(giftList.size());
            for (Gift gift : giftList) {
                //按顺序将概率添加到集合中
                orgProbList.add(gift.getProb());
            }
            return draw(orgProbList);
        }
        return -1;
    }

    public static int draw(List<Double> giftProbList) {

        List<Double> sortRateList = new ArrayList<Double>();
        // 计算概率总和
        Double sumRate = 0D;
        for (Double prob : giftProbList) {
            sumRate += prob;
        }
        if (sumRate != 0) {
            double rate = 0D;   //概率所占比例
            for (Double prob : giftProbList) {
                rate += prob;
                // 构建一个比例区段组成的集合(避免概率和不为1)
                sortRateList.add(rate / sumRate);
            }
            // 随机生成一个随机数,并排序
            double random = Math.random();
            sortRateList.add(random);
            Collections.sort(sortRateList);

            // 返回该随机数在比例集合中的索引
            return sortRateList.indexOf(random);
        }
        return -1;
    }
}
本文由作者按照 CC BY 4.0 进行授权