generate random numbers of which the sum is constant

后端 未结 7 766
暗喜
暗喜 2020-12-03 15:40

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

7条回答
  •  执念已碎
    2020-12-03 16:29

    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;
        }
    

提交回复
热议问题