I am thinking if there is anyway to generate a set of random numbers of which the sum is always a constant. For example, 20 can be divided into 5 numbers ( 1, 2,3,4,10) I do
This method does the job, and also allows controlling the "difference degree" between the values (e.g. if you want the array values to be close one to another)
/**
* Create array of positive integers which exactly sums to a given (integer) number.
* @param {Number} number of items
* @param {Number} sum required sum
* @param {Number} [d=100] difference degree between the values (0..100)
*/
randomSumArray: function(len, sum, d) {
var _sum = 0;
var arr = [];
var n, i;
if (!d && d !== 0) {
d = 100;
}
for (i = 0; i < len; i++) {
var from = (100 - d) * 1000,
to = (100 + d) * 1000,
n = Math.floor(Math.random() * (to - from + 1) + from); //random integer between from..to
_sum += n;
arr.push(n);
}
var x = sum / _sum;
_sum = 0; //count sum (again)
for (var i = 0; i < len; i++) {
arr[i] = Math.round(arr[i] * x);
_sum += arr[i];
}
var diff = sum - _sum;
// Correct the array if its sum does not match required sum (usually by a small bit)
if (diff) {
x = diff / Math.abs(diff); //x will be 1 or -1
var j = 0;
while (diff && j < 1000) { //limit to a finite number of 'corrections'
i = Math.floor(Math.random() * (len + 1)); //random index in the array
if (arr[i] + x >= 0) {
arr[i] += x;
diff -= x;
}
j++;
}
}
return arr;
}