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;
    }
}
