[Java algorithm] Java lottery algorithm, suitable for all kinds of lottery

Algorithm principle:
block the interval from 0 to 1, and the basis of the block is the proportion of the item to the whole, and then generate a number between 0-1 according to the random number seed to determine which interval this number falls on , And the corresponding item is the item that was drawn. Random numbers are theoretically equal in probability, and each number generated should theoretically be equal in probability, so the number of numbers in the corresponding interval reflects the different probability of the lottery items. If the probability is 0, this interval is also 0, and it will not fall into this interval. The final return will return the corresponding product information.

Prize category

/**
 * 奖品类
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Prize {
    
    

    /**
     * 奖品序号
     */
    private Integer prizeIndex;
    /**
     * 奖品id
     */
    private Long prizeId;
    /**
     * 奖品名称
     */
    private String prizeName;
    /**
     * 库存
     */
    private Integer stock;
    /**
     * 概率
     */
    private double probability;
}

Lottery algorithm tools

/**
 * 抽奖算法工具类
 *
 * @author xiegege
 * @date 2021/1/7 17:02
 */
public class LotteryUtil {
    
    

    /**
     * 抽奖算法
     *
     * @param originRates 原始的概率列表,保证顺序和实际物品对应
     * @return 物品的索引
     */
    public static int lottery(List<Double> originRates) {
    
    
        // 计算总概率,这样可以保证不一定总概率是1
        double sumRate = 0d;
        for (double rate : originRates) {
    
    
            sumRate += rate;
        }
        // 计算每个物品在总概率的基础下的概率情况
        List<Double> sortOriginRates = new ArrayList<>();
        double tempSumRate = 0d;
        for (double rate : originRates) {
    
    
            tempSumRate += rate;
            sortOriginRates.add(tempSumRate / sumRate);
        }
        // 根据区块值来获取抽取到的物品索引
        double nextDouble = Math.random();
        sortOriginRates.add(nextDouble);
        Collections.sort(sortOriginRates);
        return sortOriginRates.indexOf(nextDouble);
    }
}

transfer

/**
 * 不同概率抽奖
 *
 * @author xiegege
 * @date 2021/1/5 17:02
 */
public class LotteryTest {
    
    
    public static void main(String[] args) {
    
    

        List<Prize> prizes = new ArrayList<>();
        // 奖品序号==奖品id==奖品名称==库存==概率
        prizes.add(new Prize(2580, 11L, "再来一次", -1, 0.2d));
        prizes.add(new Prize(1234, 22L, "本站VIP一年", 20, 0.1d));
        prizes.add(new Prize(5678, 33L, "谢谢参与", -1, 0.4d));
        prizes.add(new Prize(1230, 55L, "50金币", 0, 0.3d));
        prizes.add(new Prize(3726, 66L, "iphone12", 0, 0d));
        prizes.add(new Prize(3737, 77L, "ipad Air8", 0, -0.1d));
        prizes.add(new Prize(2568, 88L, "100元手机话费", 5, 0.008d));

        if (CollectionUtils.isEmpty(prizes)) {
    
    
            System.out.println("无奖品数据");
            return;
        }

        List<Double> originRates = new ArrayList<>();
        for (Prize prize : prizes) {
    
    
            double probability = prize.getProbability();
            int stock = prize.getStock();
            // 概率为负数或者库存为0的数据,概率设置为0
            if (probability < 0 || stock == 0) {
    
    
                probability = 0;
            }
            originRates.add(probability);
        }

        // 测试1000次的抽奖调用
        for (int i = 0; i < 1000; i++) {
    
    
            int originIndex = LotteryUtil.lottery(originRates);
            Prize prize = prizes.get(originIndex);
            if (prize.getProbability() <= 0 || prize.getStock() == 0) {
    
    
                // 多一步判断
                System.out.println("库存不足或概率小于等于0======谢谢参与======");
            } else {
    
    
                System.out.println(prize);
            }
        }
    }
}

When the inventory is 0 or the probability is less than or equal to 0, the prize cannot be drawn. The test code here does not do inventory deduction. In actual development, inventory deduction should be done. There are still some users who can take a few times and what conditions can be taken. These logics can be increased according to their own business needs.

to sum up

如果觉得不错,可以点赞+收藏或者关注下博主。感谢阅读!

Guess you like

Origin blog.csdn.net/weixin_42825651/article/details/112323460