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

com.sghd.common.utils.model.RatioProbability Maven / Gradle / Ivy

The newest version!
package com.sghd.common.utils.model;

import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;

import com.sghd.common.utils.math.MathUtils;
import com.sghd.common.utils.math.RandomUtils;

/**
 * 人品(RP = Ratio of Probability)对象
 */
public class RatioProbability {

	/** 概率与结果的映射关系 */
	private LinkedHashMap odds = new LinkedHashMap();

	/** 构造器 */
	private RatioProbability(Map values) {
		double total = 0.0;
		for (int i : values.values()) {
			total += i;
		}
		double count = 0.0;
		int i = 0;
		for (Entry entry : values.entrySet()) {
			int v = entry.getValue();
			if (v > 0) {
				Key key;
				if (i < values.size()) {
					count += v;
					key = Key.valueOf(i, count / total);
				} else {
					key = Key.valueOf(i, 1.0);
				}
				odds.put(key, entry.getKey());
			}
			i++;
		}
	}
	
	public int getSize(){
		return odds.size();
	}

	/** 构造器 */
	private RatioProbability(T[] values, int[] weight) {
		double total = MathUtils.sum(weight);
		double count = 0.0;
		for (int i = 0; i < values.length; i++) {
			int v = weight[i];
			if (v > 0) {
				Key key;
				if (i != values.length - 1) {
					count += v;
					key = Key.valueOf(i, count / total);
				} else {
					key = Key.valueOf(i, 1.0);
				}
				odds.put(key, values[i]);
			}
		}
	}

	/** 获取人品结果 */
	public T getResult() {
		double value = RandomUtils.nextDouble();
		double prev = 0.0;
		for (Entry entry : odds.entrySet()) {
			Key key = entry.getKey();
			if (key.getRate() == prev) {
				continue;
			}
			double odd = key.getRate();
			if (value >= prev && value <= odd) {
				return entry.getValue();
			}
			prev = odd;
		}
		throw new IllegalStateException("概率内容无法获取随机结果:" + odds.toString());
	}
	
	/**
	 * 获取人品结果
	 * 用于多次随机  注意防止死循环
	 * @param ignore 需要忽略的结果 
	 * @return
	 */
	public T getResult(Collection ignore) {
		double value = RandomUtils.nextDouble();
		double prev = 0.0;
		boolean ignored = false;
		for (Entry entry : odds.entrySet()) {
			Key key = entry.getKey();
			if (key.getRate() == prev) {
				continue;
			}
			T result = entry.getValue();
			double odd = key.getRate();
			if (value >= prev && value <= odd) {
				if(ignore.contains(result)){
					ignored = true;
					break;
				}
				return result;
			}
			prev = odd;
		}
		if(ignored){
			for (Entry entry : odds.entrySet()) {
				T result = entry.getValue();
				if(!ignore.contains(result)){
					return result;
				}
			}
		}
		throw new IllegalStateException("概率内容无法获取随机结果:" + odds.toString());
	}

	/** 获取人品结果 */
	public Ratio getRatioResult() {
		double value = RandomUtils.nextDouble();
		double prev = 0.0;
		for (Entry entry : odds.entrySet()) {
			Key key = entry.getKey();
			if (key.getRate() == prev) {
				continue;
			}
			double odd = key.getRate();
			if (value >= prev && value <= odd) {
				return Ratio.valueOf(key.getSeed(), entry.getValue());
			}
			prev = odd;
		}
		throw new IllegalStateException("概率内容无法获取随机结果:" + odds.toString());
	}

	// Static Method's ...

	/** 构造方法 */
	public static  RatioProbability valueOf(Map values) {
		return new RatioProbability(values);
	}

	/** 构造方法 */
	public static  RatioProbability valueOf(T[] values, int[] weight) {
		return new RatioProbability(values, weight);
	}

	// 内部类
	public static class Ratio {
		private int seed;
		private T value;

		public int getSeed() {
			return seed;
		}

		public T getValue() {
			return value;
		}

		private Ratio() {
		}

		private static  Ratio valueOf(int seed, T value) {
			Ratio e = new Ratio();
			e.seed = seed;
			e.value = value;
			return e;
		}
	}

	/**
	 * @author Ramon
	 */
	private static class Key {
		private int seed;
		private double rate;

		public int getSeed() {
			return seed;
		}

		public double getRate() {
			return rate;
		}

		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			long temp;
			temp = Double.doubleToLongBits(rate);
			result = prime * result + (int) (temp ^ (temp >>> 32));
			result = prime * result + seed;
			return result;
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			Key other = (Key) obj;
			if (Double.doubleToLongBits(rate) != Double.doubleToLongBits(other.rate))
				return false;
			if (seed != other.seed)
				return false;
			return true;
		}

		@Override
		public String toString() {
			return "Key [seed=" + seed + ", rate=" + rate + "]";
		}

		private static Key valueOf(int seed, double rate) {
			Key e = new Key();
			e.seed = seed;
			e.rate = rate;
			return e;
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy