JAVA使用随机数进行概率抽奖

来源:互联网 发布:淘宝卖家开通子账号 编辑:程序博客网 时间:2024/06/08 04:55

需求

网站现有一抽奖功能,已经定义好奖品,每个奖品都有对应的中奖概率。通过奖品概率随机进行抽奖

实现思路

  1. 每个奖品都有对应的中奖概率,先对所有奖品中奖概率求和
  2. 计算出每个奖品在0-1之间所占的区间块
  3. 随机产生0-1之间的随机数,随机数落在哪个区间,就是中奖哪个
    例如现有以下奖品:
    奖品A 中奖概率为 0.1
    奖品B 中奖概率为 0.01
    奖品C 中奖概率为 0.001
    奖品D 中奖概率为 0.8

第一步:求出概率总和 0.1+0.01+0.001+0.8 = 0.911
第二步:计算每个奖品的所占区间块
奖品A: 0.1 / 0.911 = 0.1098
奖品B: (0.1+0.01)/ 0.911 = 0.1207
奖品C:(0.1+0.11+0.001)/ 0.911 = 0.1218
奖品D:(0.1+0.11+0.001+0.8)/ 0.911 = 1
则:
奖品A的所占区间为:0~0.1098
奖品B的所占区间为:0.1098~0.1207
奖品C的所占区间为:0.1207~0.1218
奖品D的所占区间为:0.1218~1

代码如下

/** * 奖品实体类 */public class Award{    public Award(){}    public Award(String awardTitle,double probability){        this.awardTitle = awardTitle;        this.probability = probability;    }    /**奖品ID**/    private String awardId;    /**奖品名**/    private String awardTitle;    /**中奖概率**/    private double probability;    public String getAwardId() {        return awardId;    }    public void setAwardId(String awardId) {        this.awardId = awardId;    }    public String getAwardTitle() {        return awardTitle;    }    public void setAwardTitle(String awardTitle) {        this.awardTitle = awardTitle;    }    public double getProbability() {        return probability;    }    public void setProbability(double probability) {        this.probability = probability;    }}
public class LotteryUtil {    /**     * 抽奖,获取中奖奖品     * @param awardList 奖品及中奖概率列表     * @return 中奖商品     */    public static Award lottery(List<Award> awardList) {        if(awardList.isEmpty()){            throw new AwardListIsEmptyException();        }        //奖品总数        int size = awardList.size();        //计算总概率        double sumProbability = 0d;        for (Award award : awardList) {            sumProbability += award.getProbability();        }        //计算每个奖品的概率区间        //例如奖品A概率区间0-0.1  奖品B概率区间 0.1-0.5 奖品C概率区间0.5-1        //每个奖品的中奖率越大,所占的概率区间就越大        List<Double> sortAwardProbabilityList = new ArrayList<Double>(size);        Double tempSumProbability = 0d;        for (Award award : awardList) {            tempSumProbability += award.getProbability();            sortAwardProbabilityList.add(tempSumProbability / sumProbability);        }        //产生0-1之间的随机数        //随机数在哪个概率区间内,则是哪个奖品        double randomDouble = Math.random();        //加入到概率区间中,排序后,返回的下标则是awardList中中奖的下标        sortAwardProbabilityList.add(randomDouble);        Collections.sort(sortAwardProbabilityList);        int lotteryIndex = sortAwardProbabilityList.indexOf(randomDouble);        return awardList.get(lotteryIndex);    }    public static void main(String[] args) {        List<Award> awardList = new ArrayList<Award>();        awardList.add(new Award("10个积分",0.35d));        awardList.add(new Award("33个积分",0.25d));        awardList.add(new Award("5元红包",0.002d));        awardList.add(new Award("20元话费",0.003d));        awardList.add(new Award("京东100元购物卡",0.0005d));        awardList.add(new Award("未中奖",0.1d));        Map<String,Integer> result = new HashMap<String,Integer>();        for(int i=0;i<10000;i++){            Award award = lottery(awardList);            String title = award.getAwardTitle();            Integer count = result.get(title);            result.put(title, count == null ? 1 : count + 1);        }        for (Entry<String, Integer> entry : result.entrySet()) {            System.out.println(entry.getKey() + ", count=" + entry.getValue() +", reate="+ entry.getValue()/10000d);        }    }}

测试结果
这里写图片描述