当前位置:首页 > 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
分享给朋友:

相关文章

vue.js实现轮播

vue.js实现轮播

Vue.js 实现轮播功能 使用第三方库(推荐) Vue.js 生态中有许多成熟的轮播组件库,例如 vue-awesome-swiper 或 swiper,它们功能丰富且易于集成。 安装 swip…

js实现继承

js实现继承

原型链继承 通过将子类的原型指向父类的实例实现继承。子类实例可以访问父类原型上的属性和方法。 function Parent() { this.name = 'parent'; } Paren…

js 实现vue

js 实现vue

Vue.js 的基本实现 在 JavaScript 中实现 Vue.js 的核心功能,可以通过数据绑定、响应式系统和虚拟 DOM 来实现。以下是实现 Vue.js 核心功能的简化版本。 数据响应式系…

js实现复制到剪贴板

js实现复制到剪贴板

使用document.execCommand方法(传统方式,已废弃但部分浏览器仍支持) 该方法适用于旧版浏览器,但已被标记为废弃。执行前需确保文本已被选中: function copyToClip…

js实现求导

js实现求导

实现数值求导的方法 在JavaScript中实现求导通常采用数值方法,因为JavaScript不是符号计算语言。以下是常见的数值微分方法: 中心差分法 中心差分法提供较高精度的导数近似:…

js实现交换

js实现交换

交换变量的方法 在JavaScript中,交换两个变量的值有多种方法。以下是常见的几种实现方式: 使用临时变量 通过引入一个临时变量来存储其中一个变量的值,实现交换: let a = 1;…