当前位置:首页 > JavaScript

js实现一个权重抽奖

2026-01-31 09:43:09JavaScript

权重抽奖实现方法

权重抽奖是一种根据每个奖项的权重值来随机抽取奖项的方法,权重越高,被抽中的概率越大。以下是使用JavaScript实现权重抽奖的几种方法。

方法一:基于数组的权重抽奖

定义一个奖项数组,每个奖项包含名称和权重。通过计算总权重,生成随机数,然后遍历数组确定中奖奖项。

js实现一个权重抽奖

function weightedDraw(prizes) {
    let totalWeight = prizes.reduce((sum, prize) => sum + prize.weight, 0);
    let random = Math.random() * totalWeight;
    let currentWeight = 0;

    for (let prize of prizes) {
        currentWeight += prize.weight;
        if (random <= currentWeight) {
            return prize.name;
        }
    }
}

// 示例
const prizes = [
    { name: "一等奖", weight: 1 },
    { name: "二等奖", weight: 3 },
    { name: "三等奖", weight: 6 },
    { name: "谢谢参与", weight: 90 }
];

console.log(weightedDraw(prizes));

方法二:使用概率分布

将权重转换为概率分布,然后使用累积概率进行抽奖。这种方法适用于权重较大的情况。

js实现一个权重抽奖

function weightedDrawWithProbability(prizes) {
    const totalWeight = prizes.reduce((sum, prize) => sum + prize.weight, 0);
    const probabilities = prizes.map(prize => prize.weight / totalWeight);
    const cumulativeProbabilities = [];
    let sum = 0;

    for (let prob of probabilities) {
        sum += prob;
        cumulativeProbabilities.push(sum);
    }

    const random = Math.random();
    for (let i = 0; i < cumulativeProbabilities.length; i++) {
        if (random <= cumulativeProbabilities[i]) {
            return prizes[i].name;
        }
    }
}

// 示例
const prizes = [
    { name: "一等奖", weight: 1 },
    { name: "二等奖", weight: 3 },
    { name: "三等奖", weight: 6 },
    { name: "谢谢参与", weight: 90 }
];

console.log(weightedDrawWithProbability(prizes));

方法三:使用二分查找优化

当奖项数量较多时,可以使用二分查找来提高效率。首先计算累积权重数组,然后使用二分查找确定中奖奖项。

function weightedDrawWithBinarySearch(prizes) {
    const totalWeight = prizes.reduce((sum, prize) => sum + prize.weight, 0);
    const cumulativeWeights = [];
    let sum = 0;

    for (let prize of prizes) {
        sum += prize.weight;
        cumulativeWeights.push(sum);
    }

    const random = Math.random() * totalWeight;
    let left = 0;
    let right = cumulativeWeights.length - 1;

    while (left < right) {
        const mid = Math.floor((left + right) / 2);
        if (random <= cumulativeWeights[mid]) {
            right = mid;
        } else {
            left = mid + 1;
        }
    }

    return prizes[left].name;
}

// 示例
const prizes = [
    { name: "一等奖", weight: 1 },
    { name: "二等奖", weight: 3 },
    { name: "三等奖", weight: 6 },
    { name: "谢谢参与", weight: 90 }
];

console.log(weightedDrawWithBinarySearch(prizes));

方法四:使用ES6的Map和reduce

利用ES6的Map和reduce方法简化代码,适用于现代JavaScript环境。

function weightedDrawWithMap(prizes) {
    const totalWeight = prizes.reduce((sum, prize) => sum + prize.weight, 0);
    const random = Math.random() * totalWeight;
    let currentWeight = 0;

    return prizes.find(prize => {
        currentWeight += prize.weight;
        return random <= currentWeight;
    }).name;
}

// 示例
const prizes = [
    { name: "一等奖", weight: 1 },
    { name: "二等奖", weight: 3 },
    { name: "三等奖", weight: 6 },
    { name: "谢谢参与", weight: 90 }
];

console.log(weightedDrawWithMap(prizes));

注意事项

  1. 权重值可以是任意正数,但通常建议使用整数以便于计算和理解。
  2. 确保权重总和不为零,否则会导致抽奖失败。
  3. 对于大量奖项,建议使用方法三的二分查找以提高性能。
  4. 可以根据实际需求调整奖项和权重值,以适应不同的抽奖场景。

标签: 权重js
分享给朋友:

相关文章

js实现动画

js实现动画

使用 CSS 动画与 JavaScript 控制 通过 JavaScript 动态添加或移除 CSS 类来触发动画。CSS 定义关键帧(@keyframes),JavaScript 通过 classL…

js实现全屏

js实现全屏

实现全屏的基本方法 使用JavaScript实现全屏功能主要依赖Element.requestFullscreen()方法。现代浏览器均支持此API,但不同浏览器可能需要添加前缀。 // 触发全屏…

原生js实现轮播图

原生js实现轮播图

基本结构搭建 HTML部分需要包含轮播图容器、图片列表及导航按钮。结构示例如下: <div class="slider-container"> <div class="slid…

节流js实现

节流js实现

节流(Throttle)的实现原理 节流是一种限制函数执行频率的技术,确保函数在一定时间间隔内最多执行一次。适用于高频触发事件(如滚动、输入、窗口调整等)的场景。 基础实现方式 使用时间戳判断是否执…

js实现文字滚动

js实现文字滚动

实现文字滚动的几种方法 使用CSS动画实现滚动 通过CSS的@keyframes和transform属性可以实现平滑的文字滚动效果。 <style> .scroll-text { w…

js 实现页面刷新

js 实现页面刷新

使用 location.reload() location.reload() 是原生 JavaScript 提供的页面刷新方法。调用该方法会重新加载当前页面,相当于点击浏览器的刷新按钮。 // 基本…