时间:2021-05-19
本文实例为大家分享了java实现抽奖概率类的具体代码,供大家参考,具体内容如下
在一些项目需求中,可能会遇到抽奖问题,如提供一系列奖品及获奖概率,要求根据概率返回每次抽到的奖品。以下是本人在实际项目中写的一个抽奖工具类,与大家共同分享:
import java.util.ArrayList;import java.util.List;import java.util.Random; /** * 抽奖工具类,概率和可以不等于1 * 概率为百分数去掉百分号的部分,如10%,则为10 * 抽奖操作如下: * 1.输入抽奖概率集合,【抽奖概率集合为{10.0, 20.0, 30.0}】 * 2.生成连续集合, 【生成的连续集合为{(0.0, 10.0],(10.0, 30.0],(30.0, 60.0]}】 * 3.生成随机数, 【生成方法为 random.nextDouble() * maxElement】 * 4.判断随机数在哪个区间内,返回该区间的index【生成了随机数12.001,则它属于(10.0, 30.0],返回 index = 1】 * */public class LotteryUtil { /** * 定义一个连续集合 * 集合中元素x满足:(minElement,maxElement] * 数学表达式为:minElement < x <= maxElement * */ public class ContinuousList { private double minElement; private double maxElement; public ContinuousList(double minElement, double maxElement){ if(minElement > maxElement){ throw new IllegalArgumentException("区间不合理,minElement不能大于maxElement!"); } this.minElement = minElement; this.maxElement = maxElement; } /** * 判断当前集合是否包含特定元素 * @param element * @return */ public boolean isContainKey(double element){ boolean flag = false; if(element > minElement && element <= maxElement){ flag = true; } return flag; } } private List<ContinuousList> lotteryList; //概率连续集合 private double maxElement; //这里只需要最大值,最小值默认为0.0 /** * 构造抽奖集合 * @param list 为奖品的概率 */ public LotteryUtil(List<Double> list){ lotteryList = new ArrayList<ContinuousList>(); if(list.size() == 0){ throw new IllegalArgumentException("抽奖集合不能为空!"); } double minElement = 0d; ContinuousList continuousList = null; for(Double d : list){ minElement = maxElement; maxElement = maxElement + d; continuousList = new ContinuousList(minElement, maxElement); lotteryList.add(continuousList); } } /** * 进行抽奖操作 * 返回:奖品的概率list集合中的下标 */ public int randomColunmIndex(){ int index = -1; Random r = new Random(); double d = r.nextDouble() * maxElement; //生成0-1间的随机数 if(d == 0d){ d = r.nextDouble() * maxElement; //防止生成0.0 } int size = lotteryList.size(); for(int i = 0; i < size; i++){ ContinuousList cl = lotteryList.get(i); if(cl.isContainKey(d)){ index = i; break; } } if(index == -1){ throw new IllegalArgumentException("概率集合设置不合理!"); } return index; } public double getMaxElement() { return maxElement; } public List<ContinuousList> getLotteryList() { return lotteryList; } public void setLotteryList(List<ContinuousList> lotteryList) { this.lotteryList = lotteryList; } }该工具类的基本思想是,将抽奖概率分布到数轴上,如现有三个抽奖概率10、20、30,将三者依次添加到概率集合中,则构造的数轴为:0~10范围内表示概率10,10~30范围内表示概率为20,30~60范围内表示概率为30,数轴上的长度对应着相应的概率。由这种处理方式可知,概率总和并不需要等于1。该工具类的成功与否在于Random.nextDouble()能否等概率地生成0~1之间的任意一个数。
对该抽奖工具进行测试,测试类如下:
package com.lottery; import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Map.Entry; class Result{ private int index; private int sumTime; private int time; private double probability; private double realProbability; public int getIndex() { return index; } public void setIndex(int index) { this.index = index; } public int getTime() { return time; } public void setTime(int time) { this.time = time; } public int getSumTime() { return sumTime; } public void setSumTime(int sumTime) { this.sumTime = sumTime; } public double getProbability() { return probability; } public double getRealProbability() { return realProbability; } public void setRealProbability(double realProbability) { this.realProbability = realProbability; } public Result(){ } public Result(int index, int sumTime, int time, double realProbability) { this.setIndex(index); this.setTime(time); this.setSumTime(sumTime); this.setRealProbability(realProbability); } public String toString(){ return "索引值:" + index + ",抽奖总数:" + sumTime + ",抽中次数:" + time + ",概率:" + realProbability + ",实际概率:" + (double)time/sumTime; }} public class TestLottery { static final int TIME = 100000; public static void iteratorMap(Map<Integer, Integer> map, List<Double> list){ for(Entry<Integer, Integer> entry : map.entrySet()){ int index = entry.getKey(); int time = entry.getValue(); Result result = new Result(index, TIME, time, list.get(index)); System.out.println(result); } } public static void main(String[] args) { //构造概率集合 List<Double> list = new ArrayList<Double>(); list.add(20d); list.add(80d); list.add(50d); list.add(30d); LotteryUtil ll = new LotteryUtil(list); double sumProbability = ll.getMaxElement(); Map<Integer, Integer> map = new HashMap<Integer, Integer>(); for(int i = 0; i < TIME; i++){ int index = ll.randomColunmIndex(); if(map.containsKey(index)){ map.put(index, map.get(index) + 1); }else{ map.put(index, 1); } } for(int i = 0; i < list.size(); i++){ double probability = list.get(i) / sumProbability; list.set(i, probability); } iteratorMap(map, list); }}运行结果:
由结果可知,抽奖100000时, 得到的实际概率基本与正式概率相当。
以下说明此类调用方式:
public LotteryUtil(List<Double> list)
说明:构造方法,传入参数为一个概率集合
public int randomColunmIndex()
功能:进行抽奖操作,返回List集合的索引下标,此下标对应的概率的奖品即为抽中的奖品
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
本文实例讲述了java实现的根据概率随机中奖测试类。分享给大家供大家参考,具体如下:最近要做一个宝箱抽奖的功能自己先联系了一下,分别用list和set进行存储和
本文实例为大家分享了Java实现简单幸运抽奖的具体代码,供大家参考,具体内容如下代码模块:User类:packagetest1;publicclassUser{
本文实例讲述了PHP编程实现计算抽奖概率算法。分享给大家供大家参考,具体如下:$proCur){$randNum=mt_rand(1,$proSum);if($
本文实例讲述了PHP转盘抽奖接口的实现方法。分享给大家供大家参考。具体如下:这里的转盘抽奖随机返回一个转盘角度,概率可自己定义lottery_get.php接口
常用抽奖算法对比基础的游戏抽奖算法通常要求实现在指定奖品的集合中,每个奖品根据对对应概率进行抽取。个人了解的主要有以下几中抽奖算法:随机数一一对应算法思想这种算