zoukankan      html  css  js  c++  java
  • java Random 带权重的随机选择

    实际场景中,经常要从多个选项中随机选择一个,不过,不同选项经常有不同的权重。

    /**
     * Created by xc on 2019/11/23
     * 带权重的随机选择
     */
    public class Test {
    
        public static void main(String[] args) {
            Pair[] options = new Pair[]{new Pair("first", 3.3), new Pair("second", 3.3), new Pair("third", 3.3)};
            WeightRandom rnd = new WeightRandom(options);
            for (int i = 0; i < 10; i++) {
                System.out.print(rnd.nextItem() + " ");
            }
        }
    
    
    }
    /**
     * Created by xc on 2019/11/25
     * 表示选项和权重的类Pair
     */
    public class Pair {
        Object item;
        double weight;
    
        public Pair(Object item, double weight) {
            this.item = item;
            this.weight = weight;
        }
    
        public Object getItem() {
            return item;
        }
    
        public double getWeight() {
            return weight;
        }
    }
    /**
     * Created by xc on 2019/11/25
     * 代码清单7-9 带权重的选择WeightRandom
     */
    public class WeightRandom {
        private Pair[] options;
        private double[] cumulativeProbabilities;
        private Random rnd;
    
        public WeightRandom(Pair[] options) {
            this.options = options;
            this.rnd = new Random();
            prepare();
        }
    
        /**
         * prepare()方法计算每个选项的累计概率,保存在数组cumulativeProbabilities中
         */
        private void prepare() {
            int weights = 0;
            for (Pair pair : options) {
                weights += pair.getWeight();
            }
            cumulativeProbabilities = new double[options.length];
            int sum = 0;
            for (int i = 0; i < options.length; i++) {
                sum += options[i].getWeight();
                cumulativeProbabilities[i] = sum / (double) weights;
            }
        }
    
        /**
         * nextItem()方法根据权重随机选择一个,具体就是,首先生成一个0~1的数,
         * 然后使用二分查找,如果没找到,返回结果是-(插入点)-1,所以-index-1就是插入点,插入点的位置就对应选项的索引。
         * @return
         */
        public Object nextItem() {
            double randomValue = rnd.nextDouble();
            int index = Arrays.binarySearch(cumulativeProbabilities, randomValue);
            if (index < 0) {
                index = -index - 1;
            }
            return options[index].getItem();
        }
    }
  • 相关阅读:
    14-快速排序
    linux上挂在windows的共享文件系统,大小写不敏感
    【mount】linux挂共享盘
    监控windows服务或者进程
    自定义时间间隔
    示例
    filebeat
    kafka
    文档碎片
    简单DOM操作
  • 原文地址:https://www.cnblogs.com/ooo0/p/11927140.html
Copyright © 2011-2022 走看看