JAVA实现抽奖大转盘摇一摇核心算法 亲测实用

2 篇文章 0 订阅
1 篇文章 0 订阅

公司最近市场活动需求频繁更新 什么抽奖活动 大转盘  摇一摇 各种活动 活动类型各种各样但是都是通过概率去算出来是否中将废话不多说 新手上路 大神勿喷

实体类


public class AnniversaryPrizePool {
    //序号
    private int index;
    //中奖概率
    private BigDecimal winningProbability;
    //奖品Id
    private Integer prizeId;
    //奖品名称
    private String giftName;

    public int getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }

    public BigDecimal getWinningProbability() {
        return winningProbability;
    }

    public void setWinningProbability(BigDecimal winningProbability) {
        this.winningProbability = winningProbability;
    }

    public Integer getPrizeId() {
        return prizeId;
    }

    public void setPrizeId(Integer prizeId) {
        this.prizeId = prizeId;
    }

    public String getGiftName() {
        return giftName;
    }

    public void setGiftName(String giftName) {
        this.giftName = giftName;
    }

    public AnniversaryPrizePool(int index, BigDecimal winningProbability, Integer prizeId, String giftName) {
        this.index = index;
        this.winningProbability = winningProbability;
        this.prizeId = prizeId;
        this.giftName = giftName;
    }

    @Override
    public String toString() {
        return "AnniversaryPrizePool{" +
                "index=" + index +
                ", winningProbability=" + winningProbability +
                ", prizeId=" + prizeId +
                ", giftName='" + giftName + '\'' +
                '}';
    }

核心算法

 /**
     * 抽奖
     * @param anniversaryPrizePools 原始的概率列表,保证顺序和实际物品对应
     * @return 物品的索引
     */
    public static int lottery(List<AnniversaryPrizePool> anniversaryPrizePools) {
        //扩大倍数
        int mulriple = 100;
        BigDecimal now = BigDecimal.ZERO;
        for (AnniversaryPrizePool anniversaryPrizePool : anniversaryPrizePools) {
            //所有概率加起来
            now = now.add(anniversaryPrizePool.getWinningProbability());
        }
        //概率乘以倍数
        mulriple = now.multiply(new BigDecimal(mulriple)).intValue();
        int lastScope = 0;
        // 洗牌,打乱奖品次序
        Collections.shuffle(anniversaryPrizePools);
        Map<Integer, int[]> prizeScopes = new HashMap<Integer, int[]>();
        for (AnniversaryPrizePool anniversaryPrizePool : anniversaryPrizePools) {
            int prizeId = anniversaryPrizePool.getPrizeId();
            // 划分区间
            int currentScope = lastScope + anniversaryPrizePool.getWinningProbability().multiply((new BigDecimal(mulriple).divide(now,0,BigDecimal.ROUND_HALF_UP))).intValue();
            prizeScopes.put(prizeId, new int[] { lastScope + 1, currentScope });
            lastScope = currentScope;
        }
        //获得随机的概率
        int luckyNumber = new Random().nextInt(mulriple);
        int luckyPrizeId = 0;
        // 查找随机数所在的区间
        if ((null != prizeScopes) && !prizeScopes.isEmpty()) {
            Set<Map.Entry<Integer, int[]>> entrySets = prizeScopes.entrySet();
            for (Map.Entry<Integer, int[]> m : entrySets) {
                int key = m.getKey();
                if (luckyNumber >= m.getValue()[0] && luckyNumber <= m.getValue()[1]) {
                    luckyPrizeId = key;
                    break;
                }
            }
        }
        return luckyPrizeId;
    }

算法实现

 首先把所有的商品中间的概率相加然后扩大多少倍我这里是扩大一百倍 扩大倍数可以根据自己的需求去扩大 然后打乱次序

然后获取随机数划分区间

看测试

 public static void main(String[] args) {

        List<AnniversaryPrizePool> anniversaryPrizePoolsList = new ArrayList<AnniversaryPrizePool>();
        anniversaryPrizePoolsList.add(new AnniversaryPrizePool(1, new BigDecimal(0.4), 1, "再来一次"));
        anniversaryPrizePoolsList.add(new AnniversaryPrizePool(2, new BigDecimal(0.3), 3, "本站VIP一年"));
        anniversaryPrizePoolsList.add(new AnniversaryPrizePool(3, new BigDecimal(0.5), 0, "谢谢参与"));
        anniversaryPrizePoolsList.add(new AnniversaryPrizePool(4, new BigDecimal(0.2), 5, "50金币"));
        anniversaryPrizePoolsList.add(new AnniversaryPrizePool(5, new BigDecimal(0.1), 6, "Iphone 6"));
        anniversaryPrizePoolsList.add(new AnniversaryPrizePool(6, new BigDecimal(0), 7, "Ipad Air2"));
        anniversaryPrizePoolsList.add(new AnniversaryPrizePool(7, new BigDecimal(0), 8, "100元手机话费"));
        double num = 100;
        int index = 0;
        int indexs = 0;
        for (int i = 0; i < num; i++) {
            int lottery = LotteryUtil.lottery(anniversaryPrizePoolsList);
            index = index + 1;
        }
        System.out.println("第" + index + "抽奖");
        System.out.println("谢谢参与次数为:"+indexs);

    }

所谓概率不是百分百精准 也就是说众生平等 这里这概率设置为0的就怎么抽都抽不到

既然说到了概率不会是百分百精准 在实际场景中我们的商品还有一个库存的概念也就是说你中奖了但是库存不足也会是谢谢参与

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值