Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Question about JavaScript Math.random() and basic logic

I wrote a simple piece of code to compare random array difference and found something ... that I don't quite understand.

  1. I generate 2 arrays filled with random numbers
  2. Add up the differences between the random numbers
  3. Print out the average difference

I would have expected the result to be random number close to 0.5 but in practice, it is 0.3333.

Why does the random number array home in on 0.3 and not 0.5?

const result = document.getElementById('result');  const generateRandomNrArray = (nrNumbers) => {  	let i;  	let result = [];  	for (i = 0; i < nrNumbers; i++) {  		result.push(Math.random());  	}  	return result;  }  const getArrayDiff = (arr1, arr2) => {    var diff = 0;    arr1.forEach(function (v1, index) {        diff += Math.abs(v1 - arr2[index]);    });    return diff;  }  const run = (nr) => {    const arr1 = generateRandomNrArray(nr);    const arr2 = generateRandomNrArray(nr);    const totalDiff = getArrayDiff(arr1, arr2);         result.innerHTML = "Average difference:" + (totalDiff / nr);  }
button {font-size: 2em;}
<div id="result"></div>  <button id="run" onclick="run(1500)">Click Me</button>
like image 312
Rainer Plumer Avatar asked Jun 02 '19 17:06

Rainer Plumer


People also ask

What is the use of Math random () in JavaScript?

The Math. random() function returns a floating-point, pseudo-random number in the range 0 to less than 1 (inclusive of 0, but not 1) with approximately uniform distribution over that range — which you can then scale to your desired range.

What algorithm does Math random use?

In most browsers, Math. random() is implemented using a pseudo-random number generator (PRNG). This means that the random number is derived from an internal state, mangled by a deterministic algorithm for every new random number.

Which function is used to get a random number in JavaScript?

Math. random() is a built-in method that can be used to generate random numbers in JavaScript. The function returns a value between 0 (inclusive) and 1 (exclusive), but we can use another function called Math. floor() to turn our number into a whole random number.

What is the argument in a Math random ()?

The Math. random() function is used to return a floating-point pseudo-random number between range [0,1) , 0 (inclusive) and 1 (exclusive).


2 Answers

This basically boils down to a limit and it makes sense. Consider the combinations of numbers between 0 and 10 and count the various differences you can make.

For example, there is one combination with a difference of 9 — (0, 9). There are 5 with a difference of 5:

[0, 5],   [1, 6],  [2, 7],  [3, 8],  [4, 9] 

But there are nine combinations with a difference of 1:

[1, 2],  [2, 3],   ...  [8, 9] 

With 0 - 10 the counts are:

{1: 9, 2: 8, 3: 7, 4: 6, 5: 5, 6: 4, 7: 3, 8: 2, 9: 1} 

There are 45 combinations and the average difference of the those combinations is 3.6666 not 5 because there are more smaller differences than larger ones.

When you increase the granularity from 0 - 10 to 0 - 100 the same pattern holds. There are 99 combinations that result in a difference 1 and only 50 with a difference of 50 for an average of 33.6666.

As you increase the number of significant digits the opposite directions the opposite direction with finer and finer divisions between 0 and 1, you find the same process as the limit approaches 1/3. There are many more smaller difference than larger ones pulling the average difference down. For 0-1 in 0.1 intervals you'll see 9 with a difference of 0.1 and 5 with a difference of 0.5, at 0.01 there will be 99 with a difference 0.01, and 50 with a difference of 0.5. As the interval approaches 0 the average of the differences approaches 1/3.

like image 72
Mark Avatar answered Sep 17 '22 15:09

Mark


(As a matter of fact, you are not looking at the differences, but at the absolute differences between your random numbers. There is a difference. (Pardon the pun.))

If you have two independent uniformly distributed random variables X, Y ~ U[0,1], then their absolute difference |X-Y| will follow a triangular distribution with expectation 1/3. Everything is as it should be. This distributional result, as well as calculating the expectation, is a fairly standard homework problem in probability theory. The intuition directly follows Mark's argument.

Here are histograms of the absolute and the non-absolute differences. On the left, you see how there is more mass for smaller absolute differences, which pulls the expectation down.

triangles

R code:

set.seed(1) xx <- runif(1e5) yy <- runif(1e5) par(mfrow=c(1,2)) hist(abs(xx-yy),main="|X-Y|",col="grey",xlab="") hist(xx-yy,main="X-Y",col="grey",xlab="") 

(Incidentally, our sister site CrossValidated is a wonderful resource if you have a probability/statistics question.)

like image 35
Stephan Kolassa Avatar answered Sep 19 '22 15:09

Stephan Kolassa