Random value from enum with probability

前端 未结 7 986
既然无缘
既然无缘 2020-12-20 21:40

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

7条回答
  •  情书的邮戳
    2020-12-20 22:08

    Here is another alternative which allows the distribution to be specified at runtime.

    Includes suggestion from Alexey Sviridov. Also method random() could incorporate suggestion from Ted Dunning when there are many options.

         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 buckets = new EnumMap(Option.class);
            static private final Random random = new Random();
            static private Integer total = 0;
    
            static void setDistribution(Short[] distribution) {
               if (distribution.length < OPTION_COUNT) {
                  throw new ArrayIndexOutOfBoundsException("distribution too short");
               }
               total = 0;
               Short dist;
               for (Option option : EnumSet.allOf(Option.class)) {
                  dist = distribution[option.ordinal()];
                  total += (dist < 0) ? 0 : dist;
                  buckets.put(option, total);
               }
            }
    
            static Option random() {
               Integer rnd = random.nextInt(total);
               for (Option option : EnumSet.allOf(Option.class)) {
                  if (buckets.get(option) > rnd) {
                     return option;
                  }
               }
               throw new IndexOutOfBoundsException();
            }
         }
    

提交回复
热议问题