700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Java根据奖品权重计算中奖概率实现抽奖(适用于砸金蛋 大转盘等抽奖活动)

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

时间:2020-03-24 14:13:19

相关推荐

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

---------------------

作者:dannyhoo6688

来源:CSDN

原文:/huyuyang6688/article/details/50480687

版权声明:本文为博主原创文章,转载请附上博文链接!

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

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

奖品设置

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

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

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

抽奖实现

奖品实体 Prize.java

public 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。

核心算法:

/**

* 根据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;

}

---------------------

作者:dannyhoo6688

来源:CSDN

原文:/huyuyang6688/article/details/50480687

版权声明:本文为博主原创文章,转载请附上博文链接!

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

分析:如上图,为了便于计算和理解,设置每种奖品的权重分别为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);//奖品的权重设置成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]);

}

---------------------

作者:dannyhoo6688

来源:CSDN

原文:/huyuyang6688/article/details/50480687

版权声明:本文为博主原创文章,转载请附上博文链接!

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

一等奖:962

二等奖:

三等奖:3043

四等奖:3988

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

Tips:

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

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

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

---------------------

作者:dannyhoo6688

来源:CSDN

原文:/huyuyang6688/article/details/50480687

版权声明:本文为博主原创文章,转载请附上博文链接!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。