js实现一个权重抽奖
权重抽奖实现方法
权重抽奖的核心是根据不同奖项的权重值随机抽取一个奖项。以下是使用JavaScript实现的几种方法:
方法一:基于数组和随机数
-
准备奖项及其权重数组
const prizes = [ { name: '一等奖', weight: 10 }, { name: '二等奖', weight: 20 }, { name: '三等奖', weight: 30 }, { name: '参与奖', weight: 40 } ]; -
计算总权重并生成随机数
function weightedRandom(prizes) { const totalWeight = prizes.reduce((sum, prize) => sum + prize.weight, 0); const random = Math.random() * totalWeight;
let currentWeight = 0; for (const prize of prizes) { currentWeight += prize.weight; if (random <= currentWeight) { return prize; } }
return prizes[prizes.length - 1]; // 默认返回最后一个 }
#### 方法二:使用概率分布
1. 预处理权重为累积概率
```javascript
function prepareWeights(prizes) {
const totalWeight = prizes.reduce((sum, prize) => sum + prize.weight, 0);
let cumulativeWeight = 0;
return prizes.map(prize => {
cumulativeWeight += prize.weight;
return {
...prize,
cumulativeWeight,
probability: prize.weight / totalWeight
};
});
}
- 执行抽奖
function drawPrize(preparedPrizes) { const random = Math.random() * preparedPrizes[preparedPrizes.length - 1].cumulativeWeight;
return preparedPrizes.find(prize => random <= prize.cumulativeWeight) || preparedPrizes[preparedPrizes.length - 1]; }

#### 方法三:优化版(适合大量奖项)
1. 使用二分查找提高效率
```javascript
function weightedRandomBinarySearch(prizes) {
const cumulativeWeights = [];
let sum = 0;
for (const prize of prizes) {
sum += prize.weight;
cumulativeWeights.push(sum);
}
const random = Math.random() * sum;
let left = 0;
let right = cumulativeWeights.length - 1;
while (left < right) {
const mid = Math.floor((left + right) / 2);
if (random > cumulativeWeights[mid]) {
left = mid + 1;
} else {
right = mid;
}
}
return prizes[left];
}
使用示例
const preparedPrizes = prepareWeights(prizes);
const result = drawPrize(preparedPrizes);
console.log(`恭喜获得:${result.name}`);
注意事项
- 权重值可以是任意正数,不限于百分比
- 确保权重总和不为零
- 对于高频抽奖场景,建议预处理权重数据
- 可根据需要添加奖项抽空后的处理逻辑
这些方法可根据实际需求进行调整,比如添加抽奖次数限制、奖项库存控制等功能。






