java抽奖概率算法
1. 有哪些经典的抽奖算法
常见的有两种
第一类是常见的有等级的抽奖活动,如一等、二等、三等奖等等
java">//分别为一、二、三、四等将的奖品数量,最后一个为未中奖的数量。
privatestaticfinalInteger[]lotteryList={5,10,20,40,100};
privateintgetSum(){
intsum=0;
for(intv:lotteryList){
sum+=v;
}
returnsum;
}
privateintgetLotteryLevel(){
Randomrandom=newRandom(System.nanoTime());
intsum=getSum();
for(inti=0;i<lotteryList.length;++i){
intrandNum=Math.abs(random.nextInt())%sum;
if(randNum<=lotteryList[i]){
returni;
}else{
sum-=lotteryList[i];
}
}
return-1;
}
第二类是不分等级的抽奖活动,仅需要参与人数与奖品总数,各奖品中奖概率相等。
//另一种抽奖算法,用于公司抽奖,即总参与人数与奖品数固定。
=75;
privatestaticfinalinttotal=175;
privatestaticSet<Integer>lotterySet=newHashSet<Integer>();
static{
for(inti=1;i<=lotteryNum;++i){
lotterySet.add(total*i/lotteryNum);
}
}
privateintgetLotteryNum2(){
Randomrand=newRandom(System.nanoTime());
intrandNum=Math.abs(rand.nextInt())%total;
if(lotterySet.contains(randNum)){
returnrandNum*lotteryNum/total;
}
return-1;
}
2. java集五福活动概率技术如何实现
- importjava.util.ArrayList; 
- importjava.util.List; 
- importjava.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】 
- * 
- */ 
- publicclassLotteryUtil{ 
- /** 
- *定义一个连续集合 
- *集合中元素x满足:(minElement,maxElement] 
- *数学表达式为:minElement<x<=maxElement 
- * 
- */ 
- publicclassContinuousList{ 
- privatedoubleminElement; 
- privatedoublemaxElement; 
- public者山丛ContinuousList(doubleminElement,doublemaxElement){ 
- if(minElement>maxElement){ 
- ("区间不合理,minElement不能大于maxElement!"); 
- } 
- this.minElement=minElement; 
- this.maxElement=maxElement; 
- } 
- /** 
- *判断当前集合是否包含特定元素 
- *@paramelement 
- *@return 
- */ 
- publicbooleanisContainKey(doubleelement){ 
- booleanflag=false; 
- if(element>minElement&&element<=maxElement){ 
- flag=true; 
- } 
- returnflag; 
- } 
- } 
- privateList<ContinuousList>lotteryList;唯余//概率连续集合 
- privatedoublemaxElement;//这里只需要最大值,最小值默认为0.0 
- /** 
- *构造抽奖集合 
- *@paramlist为奖品的概率 
- */ 
- publicLotteryUtil(List<Double>list){ 
- lotteryList=newArrayList<ContinuousList>(); 
- if(list.size()==0){ 
- ("抽奖集合不能为空!"); 
- } 
- doubleminElement=0d; 
- ContinuousListcontinuousList=null; 
- for(Doubled:list){ 
- minElement=maxElement; 
- maxElement=maxElement+d; 
- continuousList=newContinuousList(minElement,maxElement); 
- lotteryList.add(continuousList); 
- } 
- } 
- /** 
- *进行抽奖操作 
- *返回:奖品的概率list集合中的下标 
- */ 
- publicintrandomColunmIndex(){ 
- intindex=-1; 
- Randomr=newRandom(); 
- doubled=r.nextDouble()*maxElement;//生成首樱0-1间的随机数 
- if(d==0d){ 
- d=r.nextDouble()*maxElement;//防止生成0.0 
- } 
- intsize=lotteryList.size(); 
- for(inti=0;i<size;i++){ 
- ContinuousListcl=lotteryList.get(i); 
- if(cl.isContainKey(d)){ 
- index=i; 
- break; 
- } 
- } 
- if(index==-1){ 
- ("概率集合设置不合理!"); 
- } 
- returnindex; 
- } 
- publicdoublegetMaxElement(){ 
- returnmaxElement; 
- } 
- publicList<ContinuousList>getLotteryList(){ 
- returnlotteryList; 
- } 
- publicvoidsetLotteryList(List<ContinuousList>lotteryList){ 
- this.lotteryList=lotteryList; 
- } 
- } 
- packagecom.lottery; 
- importjava.util.ArrayList; 
- importjava.util.HashMap; 
- importjava.util.List; 
- importjava.util.Map; 
- importjava.util.Map.Entry; 
- classResult{ 
- privateintindex; 
- privateintsumTime; 
- privateinttime; 
- privatedoubleprobability; 
- privatedoublerealProbability; 
- publicintgetIndex(){ 
- returnindex; 
- } 
- publicvoidsetIndex(intindex){ 
- this.index=index; 
- } 
- publicintgetTime(){ 
- returntime; 
- } 
- publicvoidsetTime(inttime){ 
- this.time=time; 
- } 
- publicintgetSumTime(){ 
- returnsumTime; 
- } 
- publicvoidsetSumTime(intsumTime){ 
- this.sumTime=sumTime; 
- } 
- publicdoublegetProbability(){ 
- returnprobability; 
- } 
- (){ 
- returnrealProbability; 
- } 
- publicvoidsetRealProbability(doublerealProbability){ 
- this.realProbability=realProbability; 
- } 
- publicResult(){ 
- } 
- publicResult(intindex,intsumTime,inttime,doublerealProbability){ 
- this.setIndex(index); 
- this.setTime(time); 
- this.setSumTime(sumTime); 
- this.setRealProbability(realProbability); 
- } 
- publicStringtoString(){ 
- return"索引值:"+index+",抽奖总数:"+sumTime+",抽中次数:"+time+",概率:" 
- +realProbability+",实际概率:"+(double)time/sumTime; 
- } 
- } 
- publicclassTestLottery{ 
- staticfinalintTIME=100000; 
- publicstaticvoiditeratorMap(Map<Integer,Integer>map,List<Double>list){ 
- for(Entry<Integer,Integer>entry:map.entrySet()){ 
- intindex=entry.getKey(); 
- inttime=entry.getValue(); 
- Resultresult=newResult(index,TIME,time,list.get(index)); 
- System.out.println(result); 
- } 
- } 
- publicstaticvoidmain(String[]args){ 
- //构造概率集合 
- List<Double>list=newArrayList<Double>(); 
- list.add(20d); 
- list.add(80d); 
- list.add(50d); 
- list.add(30d); 
- LotteryUtilll=newLotteryUtil(list); 
- doublesumProbability=ll.getMaxElement(); 
- Map<Integer,Integer>map=newHashMap<Integer,Integer>(); 
- for(inti=0;i<TIME;i++){ 
- intindex=ll.randomColunmIndex(); 
- if(map.containsKey(index)){ 
- map.put(index,map.get(index)+1); 
- }else{ 
- map.put(index,1); 
- } 
- } 
- for(inti=0;i<list.size();i++){ 
- doubleprobability=list.get(i)/sumProbability; 
- list.set(i,probability); 
- } 
- iteratorMap(map,list); 
- } 
- } 
- publicLotteryUtil(List<Double>list) 
- 说明:构造方法,传入参数为一个概率集合 
- publicintrandomColunmIndex() 
- 功能:进行抽奖操作,返回List集合的索引下标,此下标对应的概率的奖品即为抽中的奖品 
该工具类的基本思想是,将抽奖概率分布到数轴上,如现有三个抽奖概率10、20、30,将三者依次添加到概率集合中,则构造的数轴为:0~10范围内表示概率10,10~30范围内表示概率为20,30~60范围内表示概率为30,数轴上的长度对应着相应的概率。由这种处理方式可知,概率总和并不需要等于1。该工具类的成功与否在于Random.nextDouble()能否等概率地生成0~1之间的任意一个数。
对该抽奖工具进行测试,测试类如下:
[java]view plain
运行结果:

由结果可知,抽奖100000时, 得到的实际概率基本与正式概率相当。
以下说明此类调用方式:
[java]view plain
[java]view plain
3. 抽奖概率的计算
/*
	 * 下面方法是在考虑奖项有名额限制的情运让况下
	 * 暂定一等奖1名 二等奖 2名 3等级3名 幸运奖10名
	 * 中奖方法适用math.random(1000) 
	 */
	Integer one = 1;
	 Integer two = 2;
   Integer three = 3;
	Integer lucky = 10;
	public Integer Lottery(){//返回值:1-一等奖 2-二等奖 3-三等奖 4-幸运奖 0-不中奖
		Integer ranNum = (int)(Math.random()*1000);
		System.out.println(ranNum);
		if(ranNum>=0&&ranNum<10)//获奖范围内凯悄滑
		{
			if(ranNum==0)//获得盯腊0 概率为0.1%
			{
				if(one>0)
				{
					one--;
					return 1;
				}
				if(two>0)
				{	
					two--;
					return 2;
				}
				if(three>0)
				{	
					three--;
					return 3;
				}
				if(lucky>0)
				{
					lucky--;
					return 4;
				}
			}
			
			if(ranNum>=0&&ranNum<2)
			{
				if(two>0)
				{	
					two--;
					return 2;
				}
				if(three>0)
				{	
					three--;
					return 3;
				}
				if(lucky>0)
				{
					lucky--;
					return 4;
				}
			}
			
			if(ranNum>=0&&ranNum<5)
			{
	
				if(three>0)
				{	
					three--;
					return 3;
				}
				if(lucky>0)
				{
					lucky--;
					return 4;
				}
			}
			
			if(lucky>0)
			{
				lucky--;
				return 4;
			}
		}
		
		return 0;
	}
4. 求java算法:根据物品的数量来确定抽奖的概率(当物品数量为0时无论如何都不可能选到)
public class Lottery {
    private int m = 1000;//发放奖券的数量
    private int n = 2;//奖品的数量
    public boolean getLottery(){
        boolean isLottery = false;
        double d = (double)n/(double)m;//中奖概率
        double r = Math.random();//0~1之间的随机数,包括0
        if(r<d){//如果随机数小于概率 那么中奖
            n--;//奖品数量-1
            isLottery = true;
        }
        m--;//奖券数量-1
        return isLottery;
    }
}
