Write an algorithm with js

  1. for example, there are now 40 numbers, which take random numbers in the range of 40 to 75, but the average of these 40 random numbers must be
    equal to an average of my death, such as 63.
  2. The idea of
  3. is to make 39, and then get the 40th random number based on the average, but then the 40th number will not be in the specified range of 40 to
    75.
  4. look for answers from kind-hearted people
Apr.24,2022

< del > Don't be so troublesome to describe what the average value of 40 random numbers is a fixed value
if you think differently, the sum of these 40 random numbers is a fixed value, isn't this the WeChat red packet algorithm? Is it easy? < / del >

< hr >

if you still limit the scope, you can't use Wechat to grab red packets. While this limits the scope, it also limits the sum of random numbers, and the probability of numbers in that range is definitely not equal. If you don't limit the probability of each number, there are countless ways of
changing Wechat's method of grabbing red envelopes. The idea is to generate random numbers one by one. The probability distribution of the next random number is determined according to the remaining sum
(WeChat red packet's probability distribution is different, and the mathematical expectation is equal)


look at your needs.

there is a very simple but random method, for example, if your first random number is A, then the next number will directly get abs (avg-A). As long as it is even, then the average must be a given avg.


Thank you for your answers. I still choose to randomly pick out the first few digits, then set aside the last number, and calculate the value of the last number according to the average. if it is not in this range, it will be recursively random again until the number in this range is randomly selected.
Thank you for your help!


40 numbers, the average needs to be 63
, then the sum of these 40 numbers should be 2520
, the problem is, choose 40 numbers from 40 to 75, and the sum is 2520

.
const selectScope = [40, 75]
const targetAvg = 63
const selectCount = 40
const selectSum=targetAvg*selectCount

that becomes a constrained random problem: n random numbers whose sum is S


do not use conventional thinking to do this, you are using a computer, do not be afraid of trouble, since it is a random number, it has to be random thoroughly.
for example: you randomly 40, calculate the average, not what you want, then random, until the average of 40 random numbers is what you want.

refer to this, there is still a lot of room for optimization, you can try to improve

function randomInt(a,b){
    return Math.min(a,b) + Math.round(Math.abs(a-b) * Math.random())
}

function sum(a,b){
    return a + b;
}

function randomInts(min,max,length,average){
    var rfn = randomInt.bind(null,min,max);
    var arr = [];
    while(arr.length < length){
        arr.push(rfn());
    }
    while(arr.reduce(sum)/length != average){
        arr.shift();
        arr.push(rfn());
    }
    return arr;
}

var arr = randomInts(40,75,40,63);

-supplement-

is relatively idle. I will do a good job to the end. After optimization, the algorithm is as follows:

var _c1=0,_c2=0; //.
//randomInt  .
function randomInt_(a,b){
    _c1PP;
    return Math.min(a,b) + Math.round(Math.abs(a-b) * Math.random())
}
function randomInt(a,b){
    _c2PP;
    return Math.min(a,b) + Math.round(Math.abs(a-b) * Math.random())
}

function sum(a,b){
    return a + b;
}

//
function randomInts1(min,max,length,average){
    var rfn = randomInt_.bind(null,min,max);
    var arr = [];
    while(arr.length < length){
        arr.push(rfn());
    }
    while(arr.reduce(sum)/length != average){
        arr.shift();
        arr.push(rfn());
    }
    return arr;
}

//
function randomInts2(min,max,length,average){
    var arr = [];
    var k = 0; //
    // var _sum = 0;
    if(average>max || average<min) throw '!';
    function _autoRandom(){
        if(k > 0){
            return randomInt(min,average)
        }else if(k < 0){
            return randomInt(average,max);
        }else{
            return randomInt(min,max);
        }
    }
    function add(){
        var _n = _autoRandom();
        k += _n - average;
        // _sum += _n;
        arr.push(_n);
        
    }
    while(arr.length < length){
        add();
    }
    while(k != 0){
        var _s = arr.shift();
        // _sum -= _s;
        k -= _s - average;
        add();
    }
    return arr;
}

//
function test(a,b,c,d){
    console.log(`--${c},${d}--`);
    var arr1 = randomInts1(a,b,c,d);
    console.log('arr1 :', arr1.reduce(sum)/c, ' :',_c1);
    _c1 = 0;
    
    var arr2 = randomInts2(a,b,c,d);
    console.log('arr2 :', arr2.reduce(sum)/c, ' :',_c2);
    _c2 = 0;
}

test(40,75,40, 63);

/*
--40,63--
arr1 : 63  : 21147
arr2 : 63  : 54
*/

,.
Menu