数组实现权重随机算法的核心是构建累积权重数组,如[2,7,10],再在[0,总权重)生成随机数并线性或二分查找其区间位置,从而按权重比例抽样。

用数组实现权重随机算法,核心是把“权重”变成可直观比对的区间位置。不需要复杂结构,靠一次遍历和累加就能完成,适合中小规模数据、对性能要求不高的场景。
构造权重累积数组
权重不是直接拿来比的,得先转化成递增的累积值。比如 A(2)、B(5)、C(3),总权重是 10;累积数组就是 [2, 7, 10] —— 表示 A 占前 2 个位置,B 占第 3 到第 7 个,C 占第 8 到第 10 个。
- 遍历原始权重列表,边读边加,每步存一个累计和
- 累积数组长度和原始项数一致,最后一个值等于总权重
- 这个数组天然有序,为后续二分查找或线性扫描提供基础
生成随机数并定位区间
在 [0, 总权重) 范围内取一个整数随机值(注意左闭右开),然后看它落在哪个“段”里。比如随机出 6,查累积数组 [2, 7, 10]:6 ≥ 2 且 6
- 用 线性扫描:从头开始比,遇到第一个“累计值 > 随机数”的索引即命中项(简单、易懂、适合 ≤100 项)
- 用 二分查找:调用
Arrays.binarySearch(),对累积数组查“插入点”,再换算成下标(适合高频调用或项数较多,如 >500) - 注意边界:随机数范围必须严格匹配累积逻辑,比如用
nextInt(totalWeight),不是nextDouble() * totalWeight后强转,避免浮点误差
按变量比例动态抽样
实际业务中权重常来自运行时变量,比如用户等级、点击率、库存余量等。只要把这些变量映射成整数权重,算法完全复用。
- 例如广告位投放:A 广告 CTR=2.1%、B=3.8%、C=1.5%,可放大 100 倍取整 → 权重 [210, 380, 150]
- 库存加权:商品 X 剩 12 件、Y 剩 5 件、Z 剩 20 件 → 权重 [12, 5, 20],自动倾向多库存项
- 避免零权重:若某变量为 0,对应权重设为 1 或跳过,否则会导致概率失真或除零异常
Java 实战片段(可直接嵌入项目)
以下代码封装了添加项、预计算累积数组、单次抽取三步,支持任意字符串+整数权重组合:
class WeightedPicker {private final List
private final int[] prefixSum;
private final Random rand = new Random();
public WeightedPicker(List
int n = data.size();
prefixSum = new int[n];
int sum = 0;
for (int i = 0; i String item = data.get(i).getKey();
int weight = data.get(i).getValue();
items.add(item);
sum += weight;
prefixSum[i] = sum;
}
}
public String pick() {
int r = rand.nextInt(prefixSum[prefixSum.length - 1]);
for (int i = 0; i if (r }
return items.get(0); // fallback
}
}










