java计算抽奖活动概率 - 爱问答

(爱问答)

java计算抽奖活动概率

比如:某一次抽奖活动,一等奖是23部手机,二三等奖等等等,

活动持续一个月时间,大概就是2天抽一部手机,

怎么写这个抽奖概率呢,限制在这一个月时间内,可以少几个一等奖,但最多只抽23部手机。

大神给点思路,我自己想的几种都感觉行不通

https://blog.csdn.net/a46788304/article/details/65437754

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


实体:

 

[java] view plain copypublic class Prize {         private int id;//奖品id     private 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。

核心算法:

 

[java] view plain copy/**      * 根据Math.random()产生一个double型的随机数,判断每个奖品出现的概率      * @return random:奖品列表prizes中的序列(prizes中的第random个就是抽中的奖品)      */      public int getPrizeIndex(List<Prize> prizes) {          DecimalFormat df = new DecimalFormat("######0.00");            int random = -1;          try{       * @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,然后根据随机数所处区域判断奖品:

 

[java] view plain copy0<randomNumber<=0.1   表示抽中一等奖  0.1<randomNumber<=0.3 表示抽中二等奖  0.3<randomNumber<=0.6 表示抽中三等奖  0.6<randomNumber<=1.0 表示抽中四等奖  


抽奖测试

 

[java] view plain copypublic 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);//奖品的权重设置成1          prizes.add(p1);            Prize p2 = new Prize();          p2.setPrize_name("上海紫园1号别墅");          p2.setPrize_weight(2);//奖品的权重设置成2          prizes.add(p2);            Prize p3 = new Prize();          p3.setPrize_name("奥迪a9");          p3.setPrize_weight(3);//奖品的权重设置成3          prizes.add(p3);            Prize p4 = new Prize();          p4.setPrize_name("双色球彩票");          p4.setPrize_weight(4);//奖品的权重设置成4          prizes.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次的结果如下:

[java] view plain copy一等奖:962  二等奖:2007  三等奖:3043  四等奖:3988  

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

 

Tips:

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

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

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

 

概率很低 不要贪小便宜 自己努力赚钱才是真。

相关标签:java

下一篇:证明:对所有集合A,B和C,有(A交B)并C=A交(B并C)iffC是A的子集

上一篇:有题向量题。帮我看看怎么做,平行四边形abcd中,AB=3,AD=4,AB*AD=-b*DM=1/3DC,求MA*MB的值

热门标签:
英语 谜语 作文 数学 公式 语文 物理 化学 工艺 java c语言 实验 方程 金属 分子 数据库 硫酸 酒精 运算 石油 vc 世界大战 php 化合物 mysql
最新更新:
电学的一个小问题 为什么打点计时器只能粗略瞬时速度 lookdownupon用法 中专都考不上大学有必要复读一年吗? 如图,已知∠B=∠DEF,AB=DE,请添加一个条件使△ABC≌△DEF,则需添加的条件是__________. 求曲线y=2x^2和直线y=2的所围图形的面积 夜上受降城闻笛是哪句 这个怎么填数字? 小明家下五层楼是5楼,那么小明家上五层楼是几层楼? 填空题,这个题目是怎么算的呢…… 22335577()143中括号里填什么数字。 懂得人帮我看一下这个英文是啥意思??? 最小的物质单位是什么 怎么估算根号52000000 about的重读字母是哪里