NodeJS 中奖概率

amrnrhlw  于 2022-12-03  发布在  Node.js
关注(0)|答案(2)|浏览(273)

我很好奇基于概率的轮盘旋转算法是如何工作的,所以我写了这段代码
我创建了一个包含每个奖品及其概率的对象

const chances = {
        "Apple" : 22.45,
        "Peaches" : 32.8,
        "Grapes" : 20,
        "Bananas" : 6.58,
        "Strawberry" : 18.17
    }

然后生成一个随机数,并检查它是否在奖金的中奖范围内

const random = Math.floor((Math.random() * 10000) + 1);
var rangeStart= 0;

    for (var key in chances){
        var rangeEnd= rangeStart+ chances[key];
        if (rangeStart*100 < random &&  random <= rangeEnd*100){
            console.log(rangeStart*100+" < "+random+" <= "+rangeEnd*100);
            console.log("You won a "+key)
            break;
        }
        rangeStart+= chances[key];
    }

您可以检查代码here
我走的路对吗?

z2acfund

z2acfund1#

看起来你的方向是正确的。你的代码几乎是正确的。但是,有几个问题你需要修复。
首先,您要生成一个1到10000之间的随机数,但chances对象中的概率是百分比,这意味着所有概率的总和是100,而不是10000。您需要生成一个1到100之间的随机数。
第二,在循环中,在检查随机数是否在范围内之前,将rangeStartrangeEnd乘以100。这将使比较始终为假,因为rangeStartrangeEnd是百分比,而不是实际百分比值的100倍。您需要从比较中删除乘以100。
以下是应用了这些更改的更新代码:

const chances = {
  "Apple" : 22.45,
  "Peaches" : 32.8,
  "Grapes" : 20,
  "Bananas" : 6.58,
  "Strawberry" : 18.17
};

const random = Math.floor((Math.random() * 100) + 1);
let rangeStart = 0;

for (const key in chances) {
  const rangeEnd = rangeStart + chances[key];
  if (rangeStart < random && random <= rangeEnd) {
    console.log(rangeStart + " < " + random + " <= " + rangeEnd);
    console.log("You won a " + key);
    break;
  }
  rangeStart += chances[key];
}

我希望这能帮上忙。

bgibtngc

bgibtngc2#

如前所述,不要使用10000,而是使用百分比100
为了证明你的代码运行良好(如果你不确定所使用的算法),为了测试它,对多次迭代的结果进行采样。如果收集到的结果接近预期的原始值--这是一个好迹象,表明你的思路是正确的:
下面是一个迭代次数为1,000,000次的例子,精度看起来相当不错:

const chances = {
  "Apple" : 22.45,
  "Peaches" : 32.8,
  "Grapes" : 20,
  "Bananas" : 6.58,
  "Strawberry" : 18.17
};

const results = {};

const generate = () => {
  
  const random = Math.floor((Math.random() * 100) + 1);
  var rangeStart = 0;

  for (var key in chances){
    var rangeEnd = rangeStart+ chances[key];
    if (rangeStart < random &&  random <= rangeEnd){
      results[key] ??= 0;
      results[key] += 1;
      break;
    }
    rangeStart+= chances[key];
  }
};

// noprotect
const samples = 1000000;
for (let i=0; i<samples; i++) generate();

Object.entries(results).forEach(([k, v]) => {
  console.log(`${k} ${(v / samples * 100).toFixed(2)}% (Expected: ${chances[k]}%)`); 
});

相关问题