如何增加或减少选择数组项的概率?

时间:2020-04-25 08:17:21

标签: javascript probability

因此,假设我要制作类似老虎机的东西,以使用我想使用的表情符号,并在数组中定义它们。

var arr = ["emoji","emoji2","emoji3","emoji4","emoji5"]

假设我希望表情符号1-4出现超过5个,并说要降低选择表情符号5的可能性。

我可以做一些大的事情,例如:

var arr = [
"emoji","emoji2","emoji3","emoji4",
"emoji","emoji2","emoji3","emoji4",
"emoji","emoji2","emoji3","emoji4",
"emoji","emoji2","emoji3","emoji4",
"emoji","emoji2","emoji3","emoji4",
"emoji","emoji2","emoji3","emoji4","emoji5",
]
var emoji = arr[Math.floor(Math.random() * arr.length)]

但这不是一个非常有效的主意,是否可以在不做很大数组的情况下进行上述主意?

我的主要目的是拥有

这样的数组
var arr = ["emoji","emoji2","emoji3","emoji4","emoji5"]

,它会输出一些东西,其中表情符号1-4出现的频率比表情符号5的出现频率更高,而且没有大的数组。

2 个答案:

答案 0 :(得分:6)

对于加权概率的一般情况,一种选择是使对象的键具有累积概率。假设您希望emoji5在4%的时间内出现-那么,累积概率将是24、48、72、96、100(其中最后间隔96到100表示​​emoji5的重量很轻)。然后生成一个介于1到100之间的随机数,然后找到第一个大于选取的数字的键:

const probs = {
  24: "emoji",
  48: "emoji2",
  72: "emoji3",
  96: "emoji4",
  100: "emoji5"
};

const keys = Object.keys(probs).map(Number);
const generate = () => {
  const rand = Math.floor(Math.random() * 100);
  const key = keys.find(key => rand < key);
  return probs[key];
};
for (let i = 0; i < 10; i++) {
  console.log(generate());
}

另一种选择是将一个weight数字与每个字符串关联,并给emoji5一个低数字,将权重加起来,生成一个介于0和总权重之间的随机数,然后查找第一次比赛:

const weights = [
  [4, 'emoji'],
  [4, 'emoji2'],
  [4, 'emoji3'],
  [4, 'emoji4'],
  [1, 'emoji5'],
];

const totalWeight = weights.reduce((a, [weight]) => a + weight, 0);
const weightObj = {};
let weightUsed = 0;
for (const item of weights) {
  weightUsed += item[0];
  weightObj[weightUsed] = item;
}
const keys = Object.keys(weightObj);
const generate = () => {
  const rand = Math.floor(Math.random() * totalWeight);
  const key = keys.find(key => rand < key);
  return weightObj[key][1];
};
for (let i = 0; i < 10; i++) {
  console.log(generate());
}

答案 1 :(得分:1)

以这种方式尝试

var arr = ["emoji","emoji2","emoji3","emoji4","emoji5"]
var emoji = arr[Math.floor(Math.random() * (Math.random() < 0.75 ? arr.length - 1 : arr.length))]