js概率抽奖算法应该如何写?

新手上路,请多包涵

比如下面这个数组对象,name是奖品名称,odds是固定中奖概率。请问如何通过随机数来实现概率抽奖呢

var model = [
    {
      name: '一等奖',
      odds: 0.01
    },
    {
      name: '二等奖',
      odds: 0.09
    },
    {
      name: '三等奖',
      odds: 0.9
    },
    {
      name: '四等奖',
      odds: 40
    },
    {
      name: '参与',
      odds: 59
    }
  ]
阅读 2.6k
3 个回答
var model = [
    {
      name: '一等奖',
      odds: 0.01
    },
    {
      name: '二等奖',
      odds: 0.09
    },
    {
      name: '三等奖',
      odds: 0.9
    },
    {
      name: '四等奖',
      odds: 40
    },
    {
      name: '参与',
      odds: 59
    }
]
/**
 * 获取随机数 r
 * r > 0 && r <= 1 其实只有=1时才为一等奖
 * r > 1 && r <= 10 二等奖
 * r > 10 && r <= 100 三等奖
 * r > 100 && r <= 4100 四等奖
 * r > 4100 && r <= 10000 五等奖
 */
function getWinPrize () {
   let r = Math.ceil(Math.random() * 10000)
   let PrizeName = model.find((v, i) => r > getOddsSummation(i) && r <= getOddsSummation(i + 1)).name
   return PrizeName
}
function getOddsSummation (i) {
   return model.slice(0, i).reduce((s, {odds}) => s + odds * 100, 0)
}
console.log(getWinPrize())

概率好算,已经有回答,我就不写了,只有两点提醒一下

  1. 概率这东西很神奇,样本越大,结果越接近,但是不能保证(不精确),所以 1% 的一等奖概率有可能最后一个都没抽出来,也有可能抽出 2%、3% 的一等奖。所以这东西除了按概率随机取值之外,可能还需要按一定的策略来控制数量,包含限制或补偿,而且最好能按时间等因素相对平均的分布。
  2. 抽奖,除非是专人控制(比如年会状态下,由主持人控制),否则不要做前端计算。前端数据是很容易伪造的。如果是线上抽奖,中奖的情况还是应该由后端来控制。

感觉这样可以,我验证一下

let r = Math.random() * 100
const prize = model.find(({ odds }) => {
    if (r < odds) return r
    r -= odds
})

验证好了,是没问题的

Devtool

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏