All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sghd.common.utils.guass.GaussRandom Maven / Gradle / Ivy

The newest version!
package com.sghd.common.utils.guass;
import java.util.Random;

public class GaussRandom {
	
	public static void main(String[] args) {
	   int[] cards =new int[]{1,6,5,3,5,6,0,0
	             ,4,12,6,5
	             ,5,4,6,3};//权重
	   
	   String[] names = new String[] {"10001","10002","10003","10004","10005","10006","99991","99992"
	                             ,"20001","20002","20003","20004"
	                             ,"30002","30003","30004","30009"};
	   //获取以前的Handle
	   RadomGaussResultHandle handle =   RadomGaussResultHandle.CreateAHanle(cards, null);
	   //检查handle是否一样,如果不一样重新生成一个
	   boolean same = handle.checkWeighsEqual(cards);
	   if(!same)
	   {
		   handle =   RadomGaussResultHandle.CreateAHanle(cards, null);
	   }
	   
	   Random r = new Random();
	   for(int i=0;i<1111;i++)
	   {
		   int index =randomGauss(r,cards,handle);
		   System.out.print(names[index]);
		   System.out.println();
	   }
	}
	
	/**
	 * 获得随机一个高斯分布概率选中的index,为了保证多次调用满足分布,必须RadomGaussResultHanle中
	 * 的refWeightGaussProbs每次调用都存储下来用于下次调用
	 * @param r
	 * @param weights
	 * @param refWeightGaussHandle
	 * @return
	 */
	public static int randomGauss(Random r, int[] weights,
			RadomGaussResultHandle refWeightGaussHandle) {
		//判断输入参数正确性
		if(weights==null||weights.length==0||refWeightGaussHandle==null){
			return -1;
		}
		double[] weightProbs = getWeightProbability(weights);
		//初始化引用对象
		if(refWeightGaussHandle.refWeightGaussProbs==null||refWeightGaussHandle.refWeightGaussProbs.length==0
				||refWeightGaussHandle.refWeightGaussProbs.length!=weights.length){
			//初始化第一次调用的高斯概率
			refWeightGaussHandle.refWeightGaussProbs = getWeightGaussProbability(r,weightProbs);
		}
		int index = randomGauss(r,weightProbs,refWeightGaussHandle.refWeightGaussProbs);
		return index;
	}
	
	/**
	 * 获得随机一个高斯分布概率选中的index,为了保证多次调用满足分布,必须refWeightGaussProbs每次调用都存储下来用于下次调用
	 * @param r
	 * @param weightProbs
	 * @param refWeightGaussProbs
	 * @return 错误的数据内容,如全为0或者空返回-1
	 */
	 static int randomGauss(Random r, double[] weightProbs,
			double[] refWeightGaussProbs) {
		double minp = Double.MAX_VALUE;
		int minPIndex = -1;
		// 找出概率最低值,选择它作为随机出来的目标
		for (int i = 0; i < refWeightGaussProbs.length; i++) {
			double pp = refWeightGaussProbs[i];
			if (pp < minp) {
				minp = pp;
				minPIndex = i;
			}
		}
		// 其他元素概率值减少
		for (int i = 0; i < refWeightGaussProbs.length; i++) {
			double pp = minp;
			refWeightGaussProbs[i] -= pp;
		}
		// 重新随机一个高斯分布概率替换原来的值
		double weightProb = weightProbs[minPIndex];
		double mu = 1.0 / weightProb;
		double sigma = 1.0 / weightProb / 3.0;
		refWeightGaussProbs[minPIndex] = nextGaussian(r, mu, sigma);
		//返回选中的index
		return minPIndex;
	}

	/**
	 * 随机一个int权重对应的高斯概率分布
	 * 
	 * @param r
	 * @param weightProbs/权重概率值
	 * @return
	 */
	  static double[] getWeightGaussProbability(Random r,double[] weightProbs) { 
		double[] weightGaussProp = new double[weightProbs.length];//权重高斯分布概率
		for (int i = 0; i < weightGaussProp.length; i++) {
			double weightProb = weightProbs[i];
			if (weightProb > 1)// 为0权重值,不处理,继续保持原本的极大值
			{
				weightGaussProp[i] = weightProb;
			} else {
				double mu = 1.0 / weightProb;
				double sigma = 1.0 / weightProb / 3.0;
				weightGaussProp[i] = nextGaussian(r, mu, sigma);
			}
		}
		return weightGaussProp;
	}

	/**
	 * 计算权重概率,如果为0的权重值,则设置为一个不存在的极大数
	 * 
	 * @param r
	 * @param weights
	 * @return
	 */
	  public synchronized static double[] getWeightProbability(int[] weights) {
		int sumWeight = sumIntArray(weights);
		double[] weightProp = new double[weights.length];
		for (int i = 0; i < weightProp.length; i++) {
			int weight = weights[i];
			if (weight > 0) {
				weightProp[i] = (1.0 * weight) / sumWeight;
			} else {
				weightProp[i] = Double.MAX_VALUE;
			}
		}
		return weightProp;
	}

	 static int sumIntArray(int[] arr) {
		int c = 0;
		for (int i = 0; i < arr.length; i++) {
			c += arr[i];
		}
		return c;
	}

	/**
	 * 生成一个非标准的正态随机
	 * 
	 * @param r
	 *            随机数,保证有序
	 * @param mu
	 *            数学期望
	 * @param sigma
	 *            标准差
	 * @return
	 */
	public synchronized static double nextGaussian(Random r, double mu, double sigma) {
		double ga = r.nextGaussian();
		return ga *  sigma  + mu;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy