从数组中选择元素的频率提高 35%

Selecting an element from an array 35% more often

已编辑

我有一个包含 N 个元素的列表,其中 K 个元素是“特殊”元素,其余元素是“普通”元素。我想做的是随机选择一个元素,但特殊元素的选择频率应该比普通元素高 35%。

例如:

var myList = [
   {id: 1, special: 0},
   {id: 2, special: 1} // <= special item
];

选择600次后,普通元素应该被选择250次,第二个应该比那个多选择35%,即350次。

这与建议的重复问题不同,因为我的权重加起来不等于 1。我的列表中可以有任意元素,零个或多个元素是特殊的。特殊商品权重始终为1.35,普通商品权重始终为1.0。

indexes 创建一个数组以选择主数组,然后从该数组中随机选择一个元素到 select 来自您的主数组:

var mainArray = [1, 2, 3];
var indexesArray = [0, 0, 0, 1, 2]; //1 has 3/5 chance of being chosen while 2 and 3 only have 1/5

使用随机数从 indexesArray 中随机 select 一个索引,然后:

mainArray[randomFromIndexArray];

您可以采取一种方法,首先确定是否要触发您的 "higher probability" 代码,然后从您的自定义列表中提取。

if ( Math.random() < .35 ) {
   element = randChoice(myCustomListOfMoreProbableChoices);
} else {
   element = randChoice(myListOfAllChoices);
}

关于“35% 的频率”部分,您的问题含糊不清。 (1) 是不是说特殊值整体比正常值整体多选了35%? (2) 还是说特殊值简单加权1.35,普通值加权1?

我描述的两个问题变体有不同的答案。

回答 (1)

请注意,您必须始终至少有一个特殊值和至少一个正常值。

我们知道,每次您采样一个值时,它要么是 Special 要么是 Normal,但不能同时是:

P(Special) + P(Normal) = 1

我们知道Special的可能性比Normal的可能性大35%:

P(Special) = 1.35 * P(Normal)

这是一个由两个具有两个未知数的线性方程组组成的系统。这是它的解决方案:

P(Normal) = 20 / 47
P(Special) = 27 / 47

只需将您的一组值分成两组,SpecialsNormals。现在进行以下操作:

  1. [0, 1].
  2. 均匀采样 r
  3. 如果r < 20 / 47,则从Normals均匀采样。
  4. 否则,则从Specials.
  5. 统一采样

回答 (2)

  1. 从列表中随机 select 一项。
  2. 如果是特殊的或者Math.random() < 1 / 1.35,那你就完了。
  3. 否则,return 到第 1 步。