Java根据奖品权重计算中奖概率实现抽奖http://www.bieryun.com/1035.html

双蛋节(圣诞+元旦)刚刚过去,前几天项目上线的砸金蛋活动也圆满结束。

  现在在许多网站上都会有抽奖的活动,抽奖的算法也是多种多样,这里介绍一下如何根据每种奖品的权重来抽奖,适用于多种抽奖形式。、

奖品设置


  比如现在举行一次砸金蛋活动中,奖品如下:

  奖品够丰富的哇,香车美女豪宅都有了~不过由于法律的原因,活人是不能赠送的,所以一等奖只能送海报了~~

  奖品在数据库中的存储情况

抽奖实现


  奖品实体 Prize.java

    public class Prize {    private int id;//奖品idprivate String prize_name;//奖品名称private int prize_amount;//奖品(剩余)数量private int prize_weight;//奖品权重//getter、setter

  这里只考虑最简单的抽奖实现,所以暂时只为奖品设计如上4个字段。

  见注释,prize_name表示奖品名称;prize_amount表示奖品数量,即本次抽奖活动计划发放此奖品的数量;prize_weight表示奖品权重,表示奖品被抽到的几率的比重,权重越大,被抽到的几率越大,比如本次砸金蛋活动有4种奖品,权重分别是1、2、3、4,总权重是10,那么每种奖品被抽到的几率就是1/10,2/10,3/10,4/10。

  核心算法:

/*** 根据Math.random()产生一个double型的随机数,判断每个奖品出现的概率* @param prizes* @return random:奖品列表prizes中的序列(prizes中的第random个就是抽中的奖品)*/public int getPrizeIndex(List<Prize> prizes) {DecimalFormat df = new DecimalFormat("######0.00");  int random = -1;try{//计算总权重double sumWeight = 0;for(Prize p : prizes){sumWeight += p.getPrize_weight();}//产生随机数double randomNumber;randomNumber = Math.random();//根据随机数在所有奖品分布的区域并确定所抽奖品double d1 = 0;double d2 = 0;          for(int i=0;i<prizes.size();i++){d2 += Double.parseDouble(String.valueOf(prizes.get(i).getPrize_weight()))/sumWeight;if(i==0){d1 = 0;}else{d1 +=Double.parseDouble(String.valueOf(prizes.get(i-1).getPrize_weight()))/sumWeight;}if(randomNumber >= d1 && randomNumber <= d2){random = i;break;}}}catch(Exception e){System.out.println("生成抽奖随机数出错,出错原因:" +e.getMessage());}return random;}

  抽奖的逻辑可以用下面这张图表示:

  分析:如上图,为了便于计算和理解,设置每种奖品的权重分别为1,2,3,4,所以被抽到的概率分别为0.1,0.2,0.3,0.4(本次活动中奖概率为100%)。

  先生成一个随机数randomNumber,然后根据随机数所处区域判断奖品:

0<randomNumber<=0.1   表示抽中一等奖
0.1<randomNumber<=0.3 表示抽中二等奖
0.3<randomNumber<=0.6 表示抽中三等奖
0.6<randomNumber<=1.0 表示抽中四等奖

抽奖测试


public static void main(String[] agrs) {int i = 0;PrizeMathRandom a = new PrizeMathRandom();int[] result=new int[4];List<Prize> prizes = new ArrayList<Prize>();Prize p1 = new Prize();p1.setPrize_name("范冰冰海报");p1.setPrize_weight(1);//奖品的权重设置成1prizes.add(p1);Prize p2 = new Prize();p2.setPrize_name("上海紫园1号别墅");p2.setPrize_weight(2);//奖品的权重设置成2prizes.add(p2);Prize p3 = new Prize();p3.setPrize_name("奥迪a9");p3.setPrize_weight(3);//奖品的权重设置成3prizes.add(p3);Prize p4 = new Prize();p4.setPrize_name("双色球彩票");p4.setPrize_weight(4);//奖品的权重设置成4prizes.add(p4);System.out.println("抽奖开始");for (i = 0; i < 10000; i++)// 打印100个测试概率的准确性{int selected=a.getPrizeIndex(prizes);System.out.println("第"+i+"次抽中的奖品为:"+prizes.get(selected).getPrize_name());result[selected]++;System.out.println("--------------------------------");}System.out.println("抽奖结束");System.out.println("每种奖品抽到的数量为:");System.out.println("一等奖:"+result[0]);System.out.println("二等奖:"+result[1]);System.out.println("三等奖:"+result[2]);System.out.println("四等奖:"+result[3]);       }

  尝试抽奖10000次的结果如下:

一等奖:962
二等奖:2007
三等奖:3043
四等奖:3988

  每类奖品获奖次数比例刚好大约为1:2:3:4,学过概率的你肯定知道抽奖次数越多,测试结果越准确~~

  Tips

  如果计划中奖率是100%的话,那么10个奖品只能抽奖10次,所以还要根据实际情况设置每种奖品数量和权重。

  如果需要设置中奖率不为100%,可以添加一个“伪奖品”,并为其设置权重,那么抽到这个“伪奖品”的概率就是不中奖的概率。

  如果在抽奖过程中某类奖品抽完了,可以做个判断,如果此奖品的剩余数量为0,则重新抽取奖品,直到抽到其他奖品位置。


  本来活动期间小编报着随时抢救bug的心态,连回家都抱着电脑,然而从活动上线到活动结束,并没有出现bug~~在此感谢产品部、测试部和研发部所有同事在上线前轰炸式的测试~~

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

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

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

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

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

  3. java中奖率算法_JS简单实现:根据奖品权重计算中奖概率实现抽奖的方法

    本文主要介绍:使用 JS 根据奖品权重计算中奖概率实现抽奖的方法. 一.示例场景 1.1.设置抽奖活动的奖项名称 奖项名称:["一等奖", "二等奖", &qu ...

  4. JS简单实现:根据奖品权重计算中奖概率实现抽奖的方法

    本文主要介绍:使用 JS 根据奖品权重计算中奖概率实现抽奖的方法. 一.示例场景 纯爱小说 www.shupu.org 1.1.设置抽奖活动的奖项名称 奖项名称:["一等奖", & ...

  5. html抽奖调整中奖率,JS简单实现:根据奖品权重计算中奖概率实现抽奖的方法 _ 惠州SEO...

    摘要 //layui模块化引用layui.use(['jquery','util'],function(){var$=layui.$,util=layui.util;//设置奖项名称.权重.中奖次数等 ...

  6. 视频教程-Springboot+Vue前后的分离整合项目实战-Java

    Springboot+Vue前后的分离整合项目实战 10多年互联网一线实战经验,现就职于大型知名互联网企业,架构师, 有丰富实战经验和企业面试经验:曾就职于某上市培训机构数年,独特的培训思路,培训体系 ...

  7. 视频教程-Vue、Spring Boot开发小而完整的Web前后端分离项目实战-Java

    Vue.Spring Boot开发小而完整的Web前后端分离项目实战 3年多.net开发经验:5年的java后端开发经验,熟悉行.net,java流行技术,拥有多个.net,java web企业级应; ...

  8. 视频教程-SpringBoot2+Vue+AntV前后端分离开发项目实战-Java

    SpringBoot2+Vue+AntV前后端分离开发项目实战 10多年互联网一线实战经验,现就职于大型知名互联网企业,架构师, 有丰富实战经验和企业面试经验:曾就职于某上市培训机构数年,独特的培训思 ...

  9. 项目实战 Java读取Excel数据

    项目实战 Java读取Excel数据 前言 实现步骤 导入POI依赖 示例Excel表结构 编写读取Excel工具类 实现思路 读取Excel数据工具类实现代码 取出从excel中获取的数据,并插入到 ...

最新文章

  1. py_innodb_page_info.py 脚本下载
  2. 第二十三周微职位elk日志系统
  3. (转)C#操作XML的完整例子——XmlDocument篇
  4. 【学术相关】谈谈国自然申请中标的经验
  5. linux里查看最耗CPU的线程
  6. leetcode1011. 在 D 天内送达包裹的能力(二分查找)
  7. HTML5 API详解(3):为何网页上要增加Battery电池状态API
  8. 北航教授李帅:“VR+医疗”仿真系统及关键技术分享
  9. linux 驱动读写文件,Linux下读写寄存器
  10. [小程序]_ELVE_小程序开发(1)
  11. python编程入门视频-2020年5个经典python编程入门视频教程推荐学习
  12. mysql省市区递归查询_mysql 递归查询
  13. Redis入门——狂神课程笔记
  14. 洲际酒店集团与国际青年成就达成全球合作
  15. 数字孪生|成熟度评价
  16. java短学期教师总结_短学期心得体会(共10篇).docx
  17. 学科前沿大作业:区块链技术的相关应用
  18. File-backed Storage
  19. java宝典 pdf下载_Java面试宝典2020修订版 PDF 下载
  20. 恢复桌面计算机图标不见了怎么办,桌面的图标不见了怎么恢复,桌面图标不见了怎么办...

热门文章

  1. 咖说丨一文读懂中国区块链“链圈”发展现状
  2. 找出最重的苹果C语言
  3. Python中级 —— 01面向对象进阶
  4. 【英语学习】——四六级作文常用句子
  5. 键盘驱动系列---JIURL键盘驱动 2
  6. mhz和mbps的转换
  7. 人工智能真的值得 All-In 么?
  8. VBA——word中书签与VS的完美搭配
  9. recat 基本学习
  10. POI中的手动公式计算方法