• 抽奖算法 百万次抽奖 单线程环境下 约 3.5 秒


    摇奖算法:

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

      

  • 相关阅读:
    url中的特殊字符问题
    Gridview中几个Button的应用
    Asp.net中static变量和viewstate的使用方法(谨慎)
    my97DatePicker选择年、季度、月、周、日
    Server.MapPath()
    asp.net(C#)读取文件夹和子文件夹下所有文件,绑定到GRIDVIEW并排序 .
    sql union和union all的用法及效率
    asp.net 字符串替换、截取和从字符串中最后某个字符 开始截取
    ASP.NET
    sql中查询中的when...then 语句
  • 原文地址:https://www.cnblogs.com/cxygg/p/10772491.html
Copyright © 2020-2023  润新知