zoukankan      html  css  js  c++  java
  • Java抽奖概率算法

    奖品

    在这里插入图片描述

    实体

    package com.leigq.www.shiro.controller;
    
    import lombok.AllArgsConstructor;
    import lombok.Builder;
    import lombok.Data;
    
    /**
     * 奖品 DTO
     * <br/>
     *
     * @author :leigq
     * @date :2019/7/5 23:00
     */
    @Data
    @Builder
    @AllArgsConstructor
    public class GiftDTO {
    
        /**
         * 索引
         */
        private Integer index;
    
    
        /**
         * 奖品名称
         */
        private String name;
    
        /**
         * 奖品编号
         */
        private String no;
    
    
        /**
         * 中奖概率
         */
        private Double probability;
    }
    
    

    抽奖方法

     /**
      * 抽奖方法
      * <br/>
      * create by: leigq
      * <br/>
      * create time: 2019/7/5 23:08
      * @param orignalRates 商品中奖概率列表,保证顺序和实际物品对应
      * @return 中奖商品索引
      */
     public static int lottery(List<Double> orignalRates) {
    
         if (orignalRates == null || orignalRates.isEmpty()) {
             return -1;
         }
    
         int size = orignalRates.size();
    
         // 计算总概率,这样可以保证不一定总概率是1
         double sumRate = 0d;
         for (double rate : orignalRates) {
             sumRate += rate;
         }
    
         // 计算每个物品在总概率的基础下的概率情况
         List<Double> sortOrignalRates = new ArrayList<>(size);
         Double tempSumRate = 0d;
         for (double rate : orignalRates) {
             tempSumRate += rate;
             sortOrignalRates.add(tempSumRate / sumRate);
         }
    
         // 根据区块值来获取抽取到的物品索引
         double nextDouble = Math.random();
         sortOrignalRates.add(nextDouble);
         Collections.sort(sortOrignalRates);
    
         return sortOrignalRates.indexOf(nextDouble);
     }
    

    测试

    我这里就只用两个商品测试

    public static void main(String[] args) {
    
        List<GiftDTO> gifts = new ArrayList<>();
        gifts.add(new GiftDTO(1,  "一等奖", "P1", 0.4d));
        gifts.add(new GiftDTO(2, "谢谢参与","P2", 0.6d));
    
        // 存储概率
        List<Double> orignalRates = new ArrayList<>(gifts.size());
        for (GiftDTO gift : gifts) {
            double probability = gift.getProbability();
            if (probability < 0) {
                probability = 0;
            }
            orignalRates.add(probability);
        }
    
        // 统计
        Map<Integer, Integer> count = new HashMap<>();
    
        // 测试次数
        double num = 1000000;
        for (int i = 0; i < num; i++) {
            int orignalIndex = lottery(orignalRates);
            Integer value = count.get(orignalIndex);
            count.put(orignalIndex, value == null ? 1 : value + 1);
        }
    
        for (Map.Entry<Integer, Integer> entry : count.entrySet()) {
            System.out.println(gifts.get(entry.getKey()) + ", 命中次数=" + entry.getValue() + ", 实际概率="
                    + entry.getValue() / num);
        }
    }
    

    在这里插入图片描述
    结果与预期差不多。

    感谢


    作者:不敲代码的攻城狮
    出处:https://www.cnblogs.com/leigq/
    任何傻瓜都能写出计算机可以理解的代码。好的程序员能写出人能读懂的代码。

     
  • 相关阅读:
    linux下svn命令大全
    php常用函数
    在centos上设置计划任务
    sphinx使用心得
    sphinx2.8.8的配置文件
    Mac使用
    sftp
    uwp应用在debug模式下运行正常,编译为release版本的时候抛出异常
    win10 uwp 读取resw资源文件
    dll被设置为用记事本打开的解决方法
  • 原文地址:https://www.cnblogs.com/leigq/p/13406544.html
Copyright © 2011-2022 走看看