適用於「按權重比例隨機選取」的場景,如廣告輪播、負載均衡、抽獎系統:
sum[1, sum] 區間隨機數 rdcurWt,首個 curWt >= rd 的項目即為選中結果import java.util.*;
public class WeightRandomSelector {
static class Node {
int weight;
String keyword;
Node(int w, String k) { weight = w; keyword = k; }
}
public static void main(String[] args) {
List<Node> nodes = Arrays.asList(
new Node(10, "廣告A"),
new Node(20, "廣告B"),
new Node(30, "廣告C"),
new Node(40, "廣告D")
);
int sum = nodes.stream().mapToInt(n -> n.weight).sum();
Map<String, Integer> stats = new LinkedHashMap<>();
// 模擬 100 次選取,驗證分佈
for (int i = 0; i < 100; i++) {
int rd = (int) (Math.random() * sum) + 1;
Node selected = select(nodes, rd);
stats.merge(selected.keyword, 1, Integer::sum);
}
stats.forEach((k, v) -> System.out.println(k + ": " + v + "%"));
// 預期輸出接近:廣告A:10%, 廣告B:20%, 廣告C:30%, 廣告D:40%
}
static Node select(List<Node> nodes, int rd) {
int curWt = 0;
for (Node n : nodes) {
curWt += n.weight;
if (curWt >= rd) return n;
}
return nodes.get(nodes.size() - 1); // 理論上不會到達
}
}
| 特性 | 說明 |
|---|---|
| 順序敏感 | 相同權重下,靠前項目被選中機率略高 (邊界條件 >=) |
| 時間複雜度 | O(n) 線性掃描,項目少時極快 |
| 空間複雜度 | O(1) 額外空間 |
| 動態調整 | 支援運行時修改權重、增減項目 |