算法原理:
把0到1的区间分块,而分块的依据就是物品占整个的比重,再根据随机数种子来产生0-1中间的某个数,来判断这个数是落在哪个区间上,而对应的就是抽到了那个物品。随机数理论上是概率均等的,产生的每个数理论上也应该概率均等,那么相应的区间所含数的多少就体现了抽奖物品概率的不同。如果概率是0的话,这个区间也就是0,就不会落在这个区间上。最终返回会返回对应商品信息。

奖品类

/*** 奖品类*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Prize {/*** 奖品序号*/private Integer prizeIndex;/*** 奖品id*/private Long prizeId;/*** 奖品名称*/private String prizeName;/*** 库存*/private Integer stock;/*** 概率*/private double probability;
}

抽奖算法工具类

/*** 抽奖算法工具类** @author xiegege* @date 2021/1/7 17:02*/
public class LotteryUtil {/*** 抽奖算法** @param originRates 原始的概率列表,保证顺序和实际物品对应* @return 物品的索引*/public static int lottery(List<Double> originRates) {// 计算总概率,这样可以保证不一定总概率是1double 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);}
}

调用

/*** 不同概率抽奖** @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的数据,概率设置为0if (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);}}}
}

当库存为0或者概率小于等于0时抽不到该奖品。这里的测试代码没有做库存扣减,实际开发中应做库存扣减操作,还有一些用户能抽几次,什么条件能抽,这些逻辑可以根据自己的业务需求去增加。

总结

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

【Java算法】Java抽奖算法,适用于各种抽奖相关推荐

  1. Java根据奖品权重计算中奖概率实现抽奖(适用于砸金蛋、大转盘等抽奖活动)

    ---------------------  作者:dannyhoo6688  来源:CSDN  原文:https://blog.csdn.net/huyuyang6688/article/detai ...

  2. 【项目实战】——Java根据奖品权重计算中奖概率实现抽奖(适用于砸金蛋、大转盘等抽奖活动)...

    Java根据奖品权重计算中奖概率实现抽奖http://www.bieryun.com/1035.html 双蛋节(圣诞+元旦)刚刚过去,前几天项目上线的砸金蛋活动也圆满结束. 现在在许多网站上都会有抽 ...

  3. 【项目实战】——Java根据奖品权重计算中奖概率实现抽奖(适用于砸金蛋、大转盘等抽奖活动)

    双蛋节(圣诞+元旦)刚刚过去,前几天项目上线的砸金蛋活动也圆满结束.   现在在许多网站上都会有抽奖的活动,抽奖的算法也是多种多样,这里介绍一下如何根据每种奖品的权重来抽奖,适用于多种抽奖形式. 奖品 ...

  4. java实现抽奖游戏_Java实现游戏抽奖算法

    常用抽奖算法对比 基础的游戏抽奖算法通常要求实现在指定奖品的集合中,每个奖品根据对对应概率进行抽取.个人了解的主要有以下几中抽奖算法: 随机数一一对应 算法思想 这种算法思想最为简单.将n个奖品编号0 ...

  5. 实现权重抽奖算法(java)

    实现权重抽奖算法(java) 1. 算法思想 为了完成随机抽取一个奖品的目的,我们需要在奖品对应的实体中有相应的权重字段,用来区别限制某种奖品对应的被抽中的概率. 首先要遍历全部奖品,将权重进行加合. ...

  6. java转盘旋转算法,转盘抽奖算法(java)

    转盘抽奖算法(java) public class LuckDraw { public int getPrizeIndex(List prizes) throws Exception { int ra ...

  7. java 抽奖算法_Java抽奖算法第二例

    本文实例为大家分享了java抽奖算法,供大家参考,具体内容如下 1. 算法分析 根据概率将奖品划分区间,每个区间代表一个奖品,然后抽取随机数,反查落在那个区间上,即为所抽取的奖品. 2. 代码核心算法 ...

  8. 游戏抽奖网站用java怎么做,Java实现游戏抽奖算法

    常用抽奖算法对比 基础的游戏抽奖算法通常要求实现在指定奖品的集合中,每个奖品根据对对应概率进行抽取.个人了解的主要有以下几中抽奖算法: 随机数一一对应 算法思想 这种算法思想最为简单.将n个奖品编号0 ...

  9. java加权随机数抽奖_java版根据权重抽奖算法

    根据权重进行抽取的算法应用比较广泛,其中抽奖便是主要用途之一.正好这几天也正在进行抽奖模块的开发,整个抽奖模块涉及到的地方大概有三处,分别是后台进行奖品的添加(同时设置权重和数量),前台根据后台配置生 ...

  10. java实现抽奖需求分析_Java开发游戏抽奖算法有哪些?

    Java开发游戏抽奖算法有哪些?抽奖算法根据需求而定,游戏抽奖算法在指定奖品的集合中,每个奖品根据对对应概率进行抽取.Java开发游戏抽奖算法主要有随机数一一对应.离散法Alias算法等. 一.随机数 ...

最新文章

  1. 真不夸张,90%的人都被需求整“哭”过
  2. 在 Centos7 用Jexus服务器 运行.Net Core 只需几步
  3. xlwings 合并单元格 读取_xlwings,让excel飞起来
  4. 【linux】RedHat 7.x 升级 openssh 为 8.x 版本
  5. Transformer-XL语言模型:超长上下文依赖
  6. 【map知识点总结】
  7. 关于Location of the Android SDK has not been setup in the preferences的解决方法
  8. 用C语言写一个函数返回参数二进制中1的个数
  9. jqgrid 点击列头的超链接或按钮时,不触发列排序事件
  10. DataGridView拖动换行
  11. Bootstrap---dateTimePicker时间控件配置与应用
  12. 文字游戏——《小黑屋》
  13. Java Keytool工具简介
  14. 诗和远方其实并不遥远
  15. F# 图形数学基础。
  16. Java实现利用在线的API对IP地址进行解析(内部代码分享)
  17. 从G1到冻酸奶Froyo
  18. 拼图游戏 玩法介绍及其代码实现(有意思的JS 一)
  19. 机器人 homework2
  20. linux的mount bind命令

热门文章

  1. 一个简单小说阅读网页html,简单版小说搜索阅读(64位程序)
  2. JavaScript断点调试高级教程
  3. 使用MySQL管理工具-SQLyog9.63报错号码2003,超详细解析
  4. 华为olt ma5680t常用命令详解
  5. 华为GPON设备ONU常见告警及处理
  6. Notepad2-mod,轻量级文本编辑器、代替记事本的最佳选择
  7. Ubuntu18.04 wineQQ完美配置(解决不能输入中文、不能加载头像和图片、企鹅图标不能进入托盘任务栏等问题,附deepin-wine、微信、QQ安装包网盘链接)
  8. qq批量登录软件_QQ账号永久冻结
  9. python核心编程---读书笔记:第16章 网络编程
  10. 电脑有网络,但所有浏览器网页都打不开,是怎么回事?