最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Javascript: Generate random numbers with fixed mean and standard deviation - Stack Overflow

programmeradmin4浏览0评论

My question:

How can I create a list of random numbers with a given mean and standard deviation (sd) in Javascript?

Example:

I want to create a list with 5 random numbers in a range between 1 to 10. The resulting mean should be 5 and the standard deviation should be 2.

What I've done so far:

My idea was (/):

  1. Make a function (named "createData") which creates 5 random numbers between 1 and 10 and push them into an "array"
  2. This function should also calculate the mean (and the sd) of those 5 numbers.
  3. With a "do-while"-loop: Do the above function as long as the "average bees 5" (and "sd bees 2"). But when I call the do-while Loop, the browser crashes of course because there are a lot of cases when the average is != 5 (and the sd != 2).

Note: I haven't add the SD yet, since the code isn't very elegant.

I've found another script from this site which stated: "The goal of this code is to generate a collection filled with 5 normally distributed random numbers with a mean of 1.0 and a standard deviation of 0.5." . I've tried to adjust it according to my needs by adding "Math.floor" and changed the condition in the "for"-loop (i < 5).

function randomNormal() {
    return Math.floor(Math.cos(2 * Math.PI * Math.random()) * Math.sqrt(-2 * Math.log(Math.random())))
}

var a = []
for (var i=0; i < 5; i++){
    a[i] = randomNormal() / 2 + 1
}

How I want to modify my code:

I'm not quite sure whether I've understood the mathematical part of this code. According to the webpage it will create a normal distribution (which is great but not necessary). So what I need in addition is:

  • Where can I change the given mean and sd (e.g. mean = 5, sd = 2) in order to create random numbers (which fulfill those properties).
  • How do I implement the range between 1 and 10? (Maybe I could use something like: Math.floor(Math.random()*10)+1)

Thanks a lot!

My question:

How can I create a list of random numbers with a given mean and standard deviation (sd) in Javascript?

Example:

I want to create a list with 5 random numbers in a range between 1 to 10. The resulting mean should be 5 and the standard deviation should be 2.

What I've done so far:

My idea was (http://jsfiddle/QASDG/3/):

  1. Make a function (named "createData") which creates 5 random numbers between 1 and 10 and push them into an "array"
  2. This function should also calculate the mean (and the sd) of those 5 numbers.
  3. With a "do-while"-loop: Do the above function as long as the "average bees 5" (and "sd bees 2"). But when I call the do-while Loop, the browser crashes of course because there are a lot of cases when the average is != 5 (and the sd != 2).

Note: I haven't add the SD yet, since the code isn't very elegant.

I've found another script from this site which stated: "The goal of this code is to generate a collection filled with 5 normally distributed random numbers with a mean of 1.0 and a standard deviation of 0.5." http://rosettacode/wiki/Random_numbers#JavaScript. I've tried to adjust it according to my needs by adding "Math.floor" and changed the condition in the "for"-loop (i < 5).

function randomNormal() {
    return Math.floor(Math.cos(2 * Math.PI * Math.random()) * Math.sqrt(-2 * Math.log(Math.random())))
}

var a = []
for (var i=0; i < 5; i++){
    a[i] = randomNormal() / 2 + 1
}

How I want to modify my code:

I'm not quite sure whether I've understood the mathematical part of this code. According to the webpage it will create a normal distribution (which is great but not necessary). So what I need in addition is:

  • Where can I change the given mean and sd (e.g. mean = 5, sd = 2) in order to create random numbers (which fulfill those properties).
  • How do I implement the range between 1 and 10? (Maybe I could use something like: Math.floor(Math.random()*10)+1)

Thanks a lot!

Share Improve this question edited Mar 24, 2014 at 22:55 OhDaeSu asked Mar 24, 2014 at 20:17 OhDaeSuOhDaeSu 5251 gold badge7 silver badges22 bronze badges 9
  • Doesn't Math.floor in that place always round to 0? – Bergi Commented Mar 24, 2014 at 20:30
  • wikihow./Calculate-Standard-Deviation now code. show us what have you tried then we help. I bet it's your exercise for school and to be honest it's quite interesting so for your own good don't look for ready solution, don't ask for ready solution – Peter Commented Mar 24, 2014 at 20:30
  • 1 @Peter: Please re-read the question. He doesn't want to calculate standard deviation, he wants to generate a set that has the wanted property. Also, he did provide the code he tried. – Bergi Commented Mar 24, 2014 at 20:32
  • 1 @Peter: Then why did you ment "show us what have you tried" and link to wikihow./Calculate-Standard-Deviation? – Bergi Commented Mar 24, 2014 at 20:34
  • 1 @OhDaeSu: It seems to me it is not possible to find 5 integers in a range between 1 to 10 with the mean = 5 and the sd = 2. Is it possible in your case to set the sd not as a number, but as a range? – Ruslan Commented Dec 27, 2017 at 11:31
 |  Show 4 more ments

1 Answer 1

Reset to default 16 +50

How can I create a list of random numbers with a given mean and standard deviation (sd) in JavaScript?

This appears to be a question about randomly creating a list of numbers that has an exactly specified mean and an exactly specified standard deviation (and not a question about drawing random numbers from a specific probability distribution with a given mean and sd).

A straightforward solution is to draw a list of random numbers, then to shift and scale this list to have the desired mean and sd, as described in this answer from stats.stackexchange.

Say, we generate the following 5 random numbers between 1 and 10:

4.527991433628388
6.3254986488276055
5.123502737960912
7.3331068522336125
9.069573681037484

This list has a mean of 6.475934670737601 and sd of 1.8102412442104023.

Then, we transform each number in the list like this:

newNum = newSD * (oldNum - oldMean) / oldSD + newMean

By setting the new mean to 5 and new sd to 2, we get the following transformed list:

2.847863379160965
4.83379450402964
3.505799227476338
5.947025358346529
7.865517530986525

Computing the mean and sd of this list confirms that they are indeed 5 and 2.

Below is code demonstrating this approach in JavaScript:

// create a list of 5 random numbers between 1 and 10
var list = randomList(5, 1, 10);

// transform the list to have an exact mean of 5 and sd of 2
var newList = forceDescriptives(list, 5, 2);

// display the transformed list and descriptive statistics (mean and sd)
console.log('Transformed random list', newList, descriptives(newList));

// display the original list and descriptive statistics (mean and sd)
console.log('Original random list', list, descriptives(list));


/* demo functions */

function randomList(n, a, b) {
  // create a list of n numbers between a and b
  var list = [],
    i;
  for (i = 0; i < n; i++) {
    list[i] = Math.random() * (b - a) + a;
  }
  return list;
}

function descriptives(list) {
  // pute mean, sd and the interval range: [min, max]
  var mean,
    sd,
    i,
    len = list.length,
    sum,
    a = Infinity,
    b = -a;
  for (sum = i = 0; i < len; i++) {
    sum += list[i];
    a = Math.min(a, list[i]);
    b = Math.max(b, list[i]);
  }
  mean = sum / len;
  for (sum = i = 0; i < len; i++) {
    sum += (list[i] - mean) * (list[i] - mean);
  }
  sd = Math.sqrt(sum / (len - 1));
  return {
    mean: mean,
    sd: sd,
    range: [a, b]
  };
}

function forceDescriptives(list, mean, sd) {
  // transfom a list to have an exact mean and sd
  var oldDescriptives = descriptives(list),
    oldMean = oldDescriptives.mean,
    oldSD = oldDescriptives.sd,
    newList = [],
    len = list.length,
    i;
  for (i = 0; i < len; i++) {
    newList[i] = sd * (list[i] - oldMean) / oldSD + mean;
  }
  return newList;
}

Limitations

Note that, due to precision limits in floating-point arithmetic, the demo sometimes putes the exact mean and sd to deviate slightly (like an sd of 2.0000000000000004 instead of 2). Also note that, depending on the desired mean and sd, it may not be possible to generate a list of numbers within a desired range, as described in this answer on math.stackexchange. This means that the transformed list could be in a very different range than the original list. Also note that it is likely not possible to generate lists of random integers from a given range with a given integer mean and integer sd.

发布评论

评论列表(0)

  1. 暂无评论