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();
    }
}
复制代码

 

posted @   草木物语  阅读(3217)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示