Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Random value from enum with probability

Tags:

java

enums

I have an enum that I would like to randomly select a value from, but not truly random. I would like some of the values to be less likely of being selected so far. Here is what I have so far...

private enum Type{
        TYPE_A, TYPE_B, TYPE_C, TYPE_D, TYPE_E;

        private static final List<Type> 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));
          }
    }

Is there an efficient way of assigning probabilities to each of these values?

Code found from here

like image 722
tgrosinger Avatar asked Mar 11 '11 05:03

tgrosinger


People also ask

How do you generate a random value from an enum?

Inside randomDirection(), we call the method nextInt() with an integer argument. The nextInt() method returns a random number to access the directions array; therefore, we need to make sure the integer is not out of the bounds of the array by passing a bound argument to nextInt().

What is enum constant?

An enum type is a special data type that enables for a variable to be a set of predefined constants. The variable must be equal to one of the values that have been predefined for it. Common examples include compass directions (values of NORTH, SOUTH, EAST, and WEST) and the days of the week.


1 Answers

several ways to do it, one of them, similar to your approach

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<Type> 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();
    }
}
like image 200
Alexey Sviridov Avatar answered Sep 21 '22 17:09

Alexey Sviridov