3

我希望生成 6 个随机百分比,在 JavaScript 中加起来为 100。我不希望最大和最小百分比之间的差异超过 20%。

这样做最有效的方法是什么?

非常感谢。

4

4 回答 4

2

我有一个类似的问题。这样做的一个好处是,不仅数字是随机的,而且数组最大的项目也是随机的,因为数组已经被打乱了。

否则,大多数时候第一个数字将是最大的,而第二个数字将是第二个最大的,依此类推。

另一个好处是,这将生成尽可能多的细分,并且您可以对最大细分设置一个上限。例如,如果你想加到 100,你的第一个数字不会是 99.9。

var generateProportion = function() {
  var max = 100,
    segmentMax = 60,
    tempResults = [],
    remaining = max,
    segments = 5,
    finalResults = [];

   //create a series of random numbers and push them into an array
  for (var i = 1; i <= segments; i++) {
    var r = Math.random() * segmentMax;
    if (i === segments) {
      // the final segment is just what's left after the other randoms are added up
      r = remaining;
    }
    tempResults.push(r);
    // subtract them from the total
    remaining -= r;
    // no segment can be larger than what's remaining
    segmentMax = remaining;
  }

  //randomly shuffle the array into a new array
  while (tempResults.length > 0) {
    var index = Math.floor(Math.random() * tempResults.length);
    finalResults = finalResults.concat(tempResults.splice(index, 1));
  }
  return finalResults;
}
var proportion = generateProportion();
var total = proportion.reduce( (a,b) => a+b);
console.log(proportion, "=", total);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

于 2016-09-22T04:11:36.580 回答
0

首先,您制作一个 100 到 120 之间的随机数数组,如下所示:

var arPercentages = [];

for(var i = 0; i < 6; i++) {
    arPercentages.push(Math.random()*20 + 100);
}

然后你添加所有的数字。选择你的方法,我总是使用下划线,所以我会 map()。但基本上,你必须做的是这样的:

var total = arPercentages[0] + arPercentages[1] + arPercentages[2] + arPercentages[3] + arPercentages[4] + arPercentages[5];

最后,您只需对每个数字进行除法运算:

for (var i = 0; i < 6; i++) {
    arPercentages[i] = arPercentages[i] / total * 100;
}

您有一个包含 6 个百分比的数组,加到 100 并且介于基值的 100% 到 120% 之间(但这非常接近)

于 2013-09-06T16:25:29.313 回答
0

这是部分解决方案:

function get_6_rands() {
    var rands = [], rand, total = 0, normalized_rands = [];
    for (var i = 0; i < 6; i += 1) {
        rand = Math.random();
        rands.push(rand);
        total += rand;
    }
    for (var i = 0; i < 6; i += 1) {
        rand = rands[i] / total;
        normalized_rands.push(rand);
    }
    return normalized_rands;
}

function_is_valid(attempt) {
    return true; // implement `is_valid` yourself
}
do {
    var attempt = get_6_rands();
} while (is_valid(attempt) === false);
console.log(attempt); // success!

该函数将生成 6 个随机数,它们加起来是1. 它是通过标准化来实现的。如果你想要整数(而不是浮点数),你需要做一些聪明的事情,仅仅四舍五入是不够的。

您可以20%通过检查需求来获得需求,如果失败,请重试,并继续尝试,直到获得满足您需求的需求。你最终应该得到一个,毕竟它是随机的。

于 2013-09-06T16:20:34.510 回答
0

我不得不解决一个类似的问题。我是这样做的:

const random = (min, max) => {
    return min + Math.random() * (max - min);
};

const randomFill = (amount, min, max) => {
    const arr = [];
    let total = 0;

    // fill an array with random numbers
    for (let i = 0; i < amount; i++) arr.push(random(min, max));

    // add up all the numbers
    for (let i = 0; i < amount; i++) total += arr[i];

    // normalise so numbers add up to 1
    for (let i = 0; i < amount; i++) arr[i] /= total;

    return arr;
};

min并且max可以是任何东西。实际值并不重要,因为总数是标准化的。

const values = randomFill(6, 0.2, 0.5);
// [0.1549, 0.2023, 0.1681, 0.0981, 0.1621, 0.2141]

这是一个jsfiddle:https ://jsfiddle.net/brunoimbrizi/q3fLp8u5/27/

于 2019-03-25T12:04:03.397 回答