摇奖算法:
package com.hs.services.utils; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collections; import java.util.List; import com.hs.commons.exception.ParameterErrorException; /** * 摇摇机 * @author ZHANGYUKUN * */ public class ShakeMachine { /** * 摇奖 * @param gradeSlice 中奖等级 和 概率的关系 * @return 0 表示不中奖,别的返回中奖等级 */ public static int shake(List<GradeSlice> gradeSlice) { if( gradeSlice.isEmpty() ) { return 0; } Collections.sort(gradeSlice); Double total = 0D; for(GradeSlice item : gradeSlice) { total = total + item.getGrade().doubleValue(); } if( total > 1D ) { throw new ParameterErrorException("总概率高于1"); } double min = gradeSlice.get( gradeSlice.size()-1 ).getGrade().doubleValue(); if( 1-total < min ) { min = 1-total; } int t = getNumberDecimalDigits( min ) ; int len = 0; if( t>len ) { len = t; } Double multiple = Math.pow( 10 , len ); Double random = Math.random()*multiple; long r = random.longValue(); int bj = 0; for( GradeSlice item : gradeSlice ) { Double totalItem = item.getGrade().doubleValue()*multiple; long dbj = totalItem.longValue(); bj +=dbj; if( r<bj ) { return item.getKey(); } } return 0; } public static int getNumberDecimalDigits(double number) { if (number == (long)number) { return 0; } int i = 0; while (true){ i++; if (number * Math.pow(10, i) > 1) { return i; } } } public static void main(String[] args) { List<GradeSlice> list = new ArrayList<>(); list.add(new GradeSlice(1, new BigDecimal(0.09) )); list.add(new GradeSlice(2, new BigDecimal(0.09) )); list.add(new GradeSlice(3, new BigDecimal(0.09) )); list.add(new GradeSlice(4, new BigDecimal(0.09))); list.add(new GradeSlice(5, new BigDecimal(0.09) )); list.add(new GradeSlice(6, new BigDecimal(0.09) )); list.add(new GradeSlice(7, new BigDecimal(0.09) )); int a0 = 0; int a1 = 0; int a2 = 0; int a3 = 0; int a4 = 0; int a5 = 0; int a6 = 0; int a7 = 0; System.out.println( ); long cc = System.currentTimeMillis(); for( int i = 0;i<100000;i++ ) { int a = shake(list); switch( a ) { case 0:{ a0++; break; } case 1:{ a1++; break; } case 2:{ a2++; break; } case 3:{ a3++; break; } case 4:{ a4++; break; } case 5:{ a5++; break; } case 6:{ a6++; break; } case 7:{ a7++; break; } } } System.out.println( a7 ); System.out.println( a6 ); System.out.println( a5 ); System.out.println( a4 ); System.out.println( a3 ); System.out.println( a2 ); System.out.println( a1 ); System.out.println( a0 ); System.out.println("用時:" + (System.currentTimeMillis()-cc ) ); } }
概率封装类:
package com.hs.services.utils; import java.math.BigDecimal; /** * 概率封装类 * @author ZHANGYUKUN * */ public class GradeSlice implements Comparable<GradeSlice> { public GradeSlice(int key, BigDecimal grade) { super(); this.key = key; this.grade = grade; } /** * 中几等奖 */ private int key; /** * 中奖概率 */ private BigDecimal grade; public int getKey() { return key; } public void setKey(int key) { this.key = key; } public BigDecimal getGrade() { return grade; } public void setGrade(BigDecimal grade) { this.grade = grade; } @Override public int compareTo(GradeSlice o) { return o.getGrade().compareTo( grade ); } }