抽奖算法

2018-11-21  本文已影响77人  Ludwigvan

最近要实现一个抽奖的功能;根据权重来决定奖品;其实就是数学里的概率问题;概率越大被选中的机会就越大;简单实现了一个算法工具类如下:

public class PrizeUtil {

    private static final Logger log =LoggerFactory.getLogger(PrizeUtil.class);

    public static String createReward(List<TbUserGameYybfVo> gameYybfs, TbGameYybf tbGameYybf){
        List<RewardVo> result = new ArrayList<>();
        log.info("----------------游戏金币:"+tbGameYybf.getPoint().doubleValue());
        BigDecimal reward = tbGameYybf.getPoint().multiply(new BigDecimal(0.8));
        log.info("----------------奖池 :"+reward.doubleValue()+"金币");
        BigDecimal devide = new BigDecimal(8);
        BigDecimal oneDevide = new BigDecimal(5);
        BigDecimal twoDevide = new BigDecimal(2);
        BigDecimal threeDevide = new BigDecimal(1);

        int oneReward = reward.divide(devide).multiply(oneDevide).intValue();
        double twoReward = reward.divide(devide).multiply(twoDevide).intValue();
        double threeReward = reward.divide(devide).multiply(threeDevide).intValue();
        log.info("一等奖金币:{};二等奖金币:{};三等奖金币:{}",oneReward,twoReward,threeReward);

        BigDecimal[] bigDecimals = new BigDecimal[]{new BigDecimal(oneReward),new BigDecimal(twoReward),new BigDecimal(threeReward)};
        List<Integer> users =new ArrayList<>();
        for(int i=0;i<3;i++){
            int index = drawGift(gameYybfs);
            Integer userId = gameYybfs.get(index).getUserId();
            if(users.contains(userId) ){
                i--;
            }else{
                users.add(userId);
                RewardVo vo =new RewardVo();
                vo.setName(gameYybfs.get(index).getName());
                vo.setHead(gameYybfs.get(index).getHead());
                vo.setId(userId);
                vo.setPoint(bigDecimals[i]);
                result.add(vo);
            }
        }
        return new Gson().toJson(result);
    }


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

        if(null != giftList && giftList.size()>0){
            List<Double> orgProbList = new ArrayList<Double>(giftList.size());
            for(TbUserGameYybf gift:giftList){
                //按顺序将概率添加到集合中
                orgProbList.add(gift.getPoint().doubleValue());
            }
            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;
    }


上一篇 下一篇

猜你喜欢

热点阅读