
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