积分夺宝算法

参考文章

关于权重的随机抽取算法,抽一个次或抽多次的实现

/**
     * 积分夺宝开奖算法
     * @param userDrawList 夺宝用户list
     * @param targetPersonTimes 总中奖人次
     * @param drawInfo 抽奖信息记录(记录抽奖详情)
     */
    private List<UserDrawDTO> drawPrize(List<UserDrawDTO> userDrawList, Integer targetPersonTimes, Map<String,Object> drawInfo){
        //中奖人list
        List<UserDrawDTO> winnerList = Collections.EMPTY_LIST;
        Random random = new Random();

        //总抽奖次数
        Integer totalTimes = 0;

        //从大到小排序
        userDrawList = userDrawList.stream().sorted(((o1, o2) -> {
            if (o1.getTimes() > o2.getTimes()) {
                return -1;
            }
            if (o1.getTimes() < o2.getTimes()) {
                return 1;
            }
            return 0;
        })).collect(Collectors.toList());

        for (int i = 0; i < targetPersonTimes; i++) {
            //中奖号码
            int drawNum = random.nextInt(totalTimes) + 1;
            for (int j = 0; j < userDrawList.size(); j++) {
                Integer currentTimes = userDrawList.get(j).getTimes();
                if (currentTimes >= drawNum) {
                    //中奖人
                    winnerList.add(userDrawList.get(j));
//                    System.out.println("获奖人:" + userDrawList.get(j) + ", drawNum: " + drawNum);
                    //总抽奖次数减去此次中奖人的参加次数
                    totalTimes -= currentTimes;
                    userDrawList.remove(j);
                    break;
                }
                //如果当前用户未中奖,减去当前用户的参与次数,与下一位进行对比,一直减小到 >=下一位的参与次数
                drawNum -= currentTimes;
            }
        }
        drawInfo.put("totalTimes", totalTimes);

        return winnerList;
    }

@AllArgsConstructor
@Data
public class UserDraw {
    static int count = 0;
    //用户id
    int userId;
    //抽奖次数
    int times;

    public static void main(String[] args) {
//        for (int j = 0; j < 10; j++){
//            Random random = new Random();
//            System.out.println(random.nextInt(10) + 1);
//        }
//        System.out.println(count/10);
        choujiang();

    }

    public static void choujiang(){
        Random random = new Random();
        //总抽奖人次
        Integer totalTimes = 0;

        //模拟数据
        List<UserDraw> userDrawList = new ArrayList<>();
        for (int i = 1; i < 10; i++) {
            int times = random.nextInt(1000) + 1;
            UserDraw userDraw = new UserDraw(i, times);
            totalTimes += times;
            userDrawList.add(userDraw);
        }

        //排序
        userDrawList = userDrawList.stream().sorted(((o1, o2) -> {
            if (o1.getTimes() > o2.getTimes()) {
                return -1;
            }
            if (o1.getTimes() < o2.getTimes()) {
                return 1;
            }
            return 0;
        })).collect(Collectors.toList());
        System.out.println("算法前积分总和:" + totalTimes);
        userDrawList.stream().forEach(e -> {
//            System.out.println(e.toString());
        });
        //中奖人数
        int drawTotal = 10;
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < drawTotal; i++) {
            int index = 0;
            //中奖号码
            int drawNum = random.nextInt(totalTimes) + 1;
            list.add(drawNum);
            for (int j = index; j < userDrawList.size(); j++) {
//                System.out.println("对比的数据:" + userDrawList.get(j).getTimes() + ">= " + drawNum);
                if (userDrawList.get(j).getTimes() >= drawNum) {
                    if (userDrawList.get(j).getUserId() == 2){
                        count ++;
                    }
                    //中奖人
                    System.out.println("获奖人:" + userDrawList.get(j) + ", drawNum: " + drawNum);
                    totalTimes -= userDrawList.get(j).getTimes();
                    userDrawList.remove(j);
                    break;
                }
                drawNum -= userDrawList.get(j).getTimes();
            }
        }

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值