机会逻辑问题/重构百分比(javascript)

时间:2011-11-28 18:30:25

标签: javascript logic

我有一组数字,这些数字中的每一个代表重量。数组中的数字介于0和1之间,这些数字的总和加起来为1.因此,如果说数组[1]为0.6,则表示我希望它显示大约60%的时间。我不知道数组本身所以我不知道这些数字,例如它们是用户输入。

我有一个可行的解决方案,但我不知道这是否是最有效的方法。我的解决方案似乎效率很低。这是

  • 生成随机数
  • 将此用户输入数组复制到新数组中,并将其从最小到最大排序
  • 将随机数与这个新数组中的数字进行比较,因此它将从数组中的最小数据到最大数据进行比较,当随机数小于数组数时,我将数组数存储到变量x和退出循环
  • 最后,我将x与原始数组进行比较,以找出x在原始数组中的索引

这似乎要做很多工作,是否有更简单的解决方案?我的脑袋不会旋转那么快

编辑 - 原始数组未以任何方式排序

编辑2 - 基本上我无法将此随机数与未排序数组进行比较。我需要未分类保持不变,这就是我在逻辑

中创建新数组的原因

1 个答案:

答案 0 :(得分:1)

如果您的数组的元素总和为1,则可以使用以下算法:

  1. 选择一个均匀分布的(pseuo)随机数r,介于0和权重之和之上。
  2. 每个重量,
    • 如果r小于重量,请选择并退出。
    • 否则从r中减去权重,所以它现在介于0和剩余权重之和。
  3. 由于r始终在0和剩余权重之和之间,因此总是存在一个与每个权重成比例的机会,即r小于环路达到该权重时的权重。

    在JavaScript中:

    var weights = [0.5, 0.15, 0.3, 0.05];
    var index = weights.length - 1;  // Last by default to avoid rounding error.
    var r = Math.random();
    
    for (var i = 0; i < a.length - 1; ++i) {
      if (weights[i] > r) { index = i; break; }
      // The rest of the array sums to 
      // 1 - sum(weights[0]..weights[i])
      // so rescale r appropriately.
      r -= weights[i];
    }
    

    将为您提供所需的分发。

    技巧是r -=,它确保r始终介于0和未处理数组元素的总和之间。

    您可以在http://jsfiddle.net/KdKdb/

    进行测试
相关问题