Created
April 19, 2020 05:45
-
-
Save creadone/cb506356a356db41f44a928dd6e57273 to your computer and use it in GitHub Desktop.
N random numbers with constant sum
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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