Skip to content

Instantly share code, notes, and snippets.

@creadone
Created April 19, 2020 05:45
Show Gist options
  • Save creadone/cb506356a356db41f44a928dd6e57273 to your computer and use it in GitHub Desktop.
Save creadone/cb506356a356db41f44a928dd6e57273 to your computer and use it in GitHub Desktop.
N random numbers with constant sum
// https://stackoverflow.com/a/26976623/1597964
function randomSumArray(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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment