具有概率的枚举的随机值
我有一个枚举,我想随机选择一个值,但不是真正随机的。 我希望到目前为止,某些值不太可能被选中。 这是我到目前为止所拥有的……
private enum Type{ TYPE_A, TYPE_B, TYPE_C, TYPE_D, TYPE_E; private static final List VALUES = Collections.unmodifiableList(Arrays.asList(values())); private static final int SIZE = VALUES.size(); private static final Random RANDOM = new Random(); public static Type randomType() { return VALUES.get(RANDOM.nextInt(SIZE)); } }
是否有一种有效的方法为每个值分配概率?
代码从这里找到
几种方法,其中之一,类似于你的方法
private enum Type{ TYPE_A(10 /*10 - weight of this type*/), TYPE_B(1), TYPE_C(5), TYPE_D(20), TYPE_E(7); private int weight; private Type(int weight) { this.weight = weight; } private int getWeight() { return weight; } private static final List VALUES = Collections.unmodifiableList(Arrays.asList(values())); private int summWeigts() { int summ = 0; foreach(Type value: VALUES) summ += value.getWeight(); return summ; } private static final int SIZE = summWeigts(); private static final Random RANDOM = new Random(); public static Type randomType() { int randomNum = RANDOM.nextInt(SIZE); int currentWeightSumm = 0; for(Type currentValue: VALUES) { if (randomNum > currentWeightSumm && randomNum <= (currentWeightSumm + currentValue.getWeight()) { break; } currentWeightSumm += currentValue.getWeight(); } return currentValue.get(); } }
这是一种随机选择enum
值的通用方法 。 您可以按照此处的建议调整概率。
假设您具有有限数量的值,则可以为每个值设置单独的数组(float []权重;)。 这些值将介于0和1之间。当您选择随机值时,还会在其间生成另一个随机数,并且仅在第二个生成的数字低于该值的权重时才选择该值。
您可以通过提供自定义构造函数来创建包含关联数据的枚举,并使用构造函数为概率分配权重,然后
public enum WeightedEnum { ONE(1), TWO(2), THREE(3); private WeightedEnum(int weight) { this.weight = weight; } public int getWeight() { return this.weight; } private final int weight; public static WeightedEnum randomType() { // select one based on random value and relative weight } }
import java.util.*; enum R { a(.1),b(.2),c(.3),d(.4); R(final double p) { this.p=p; } private static void init() { sums=new double[values().length+1]; sums[0]=0; for(int i=0;i bins=new EnumMap(R.class); for(R r:R.values()) bins.put(r,0); final int n=1000000; for(int i=0;i
这是另一种允许在运行时指定分布的替代方法。
包括Alexey Sviridov的建议。 当有很多选项时,方法random()也可以包含来自Ted Dunning的建议。
private enum Option { OPTION_1, OPTION_2, OPTION_3, OPTION_4; static private final Integer OPTION_COUNT = EnumSet.allOf(Option.class).size(); static private final EnumMap
您可以使用Apache Commons Math库中的EnumeratedDistribution 。
EnumeratedDistribution distribution = new EnumeratedDistribution<>( RandomGeneratorFactory.createRandomGenerator(new Random()), List.of( new Pair<>(Type.TYPE_A, 0.2), // get TYPE_A with probability 0.2 new Pair<>(Type.TYPE_B, 0.5), // get TYPE_B with probability 0.5 new Pair<>(Type.TYPE_C, 0.3) // get TYPE_C with probability 0.3 ) ); Type mySample = distribution.sample();
- LinkedHashSet删除重复对象
- SpringDataRest并显示welcome-file-list / disable链接发现
- Struts 2错误 – com.opensymphony.xwork2.util.logging.commons.CommonsLogger错误
- Java Swing更新JList
- Java 8 – 将Integer转换为长编译问题
- JAVA链接列表如何使用for循环进行循环?
- 什么是Eclipse的最佳免费插件,允许格式化/缩进/清理JSP代码?
- 如何促进服务器上的php脚本与另一台服务器上正在运行的Java应用程序之间的通信?
- 如何在VTD Xpath查找上输入名称空间前缀