2

My mathematical knowledge might be limited to solve this myself. I've found a similar question, however, with focus on center and not borders.

I would like to create random numbers with max and min but with focus on the max and min, so numbers closer to max and min's should appear more frequent than the ones in between.

I remember that in mathematics there is a function to create a parabola curve: enter image description here

And using this online tool i kind of generated the function I am looking for, which should be like

y = 0.05 * x^2

This is my basic idea and trying to turn it into javascript i ended up with this:

for (let i = 0; i < 100; i++) {
  // Create random x with ^ 2 with max=100 and min=0
  let x = Math.pow(Math.floor(Math.random() * (100 - 0 + 1)) + 0, 2);
  // log the random number in the console
  console.log(0.05 * x);
}

But of course this doesn't make any real sense as I also can see in the console (I ordered them so it's more clear to see)

> 0 0
> 0.05
> 0.05
> 0.2
> 0.2
> 0.8
> 2.45
> 3.2
> 3.2
> 3.2
> 4.05
> 4.05
> 4.05
> 6.05
> 8.45
> 8.45
> 14.45
> 16.2
> 16.2
> 16.2 20 20
> 22.05
> 22.05
> 22.05
> 26.45
> 28.8
> 28.8
> 31.25
> 33.8
> 36.45
> 39.2
> 42.05
> 48.05
> 48.05
> 48.05
> 51.2
> 57.8
> 57.8
> 57.8
> 64.8
> 64.8
> 64.8
> 68.45
> 76.05
> 88.2
> 88.2
> 92.45
> 92.45
> 92.45
> 96.8
> 101.25
> 105.8
> 110.45 125
> 130.05
> 130.05
> 135.2
> 140.45
> 140.45
> 145.8
> 145.8
> 145.8
> 156.8
> 162.45
> 162.45
> 162.45 180 180
> 198.45
> 204.8
> 204.8
> 224.45
> 231.2
> 231.2
> 231.2
> 231.2
> 238.05
> 238.05
> 259.2 320 320
> 328.05
> 344.45
> 352.8
> 352.8
> 361.25
> 369.8
> 387.2
> 387.2
> 423.2
> 423.2
> 432.45
> 451.25
> 460.8
> 470.45
> 470.45
> 490.05
> 490.05

Anybody who maybe has an idea?

Advena
  • 1,664
  • 2
  • 24
  • 45

2 Answers2

3

To generate randoms with needed distribution, one might use Smirnov's transform (inverse sampling).

To get parabolic distribution, just use uniform random generator for range 0..1 and apply square root. Example should generate values in range 0..100 with more density near ends.

for (let i = 0; i < 20; i++) {
  let x = Math.floor(50 * (Math.pow(Math.Random(), 0.5));
  if (Math.Random() < 0.5) 
      x = 50 - x
  else
      x = 50 + x;
   ...
}
MBo
  • 77,366
  • 5
  • 53
  • 86
  • Nice approach and thanks for the Smirnov's transform. It's getting close to the solution, however, I'm looking for only positive numbers and moreover, this has only one limitation input and reverse it then based on the limitation input. Still, thanks for this cool approach! – Advena Sep 24 '18 at 15:04
  • I've added range shift to get 0..100 range with min at 50 – MBo Sep 24 '18 at 15:07
  • Thanks, i did some changes to your answer if that is okay. Btw, how would you proceed if the focus should be more on one end, as e.g. minimum? – Advena Sep 24 '18 at 19:31
0

Eventough @MBo rejected my edit (but has the correct answer), I'm still gonna share a working example based on a min and max variable (only positive numbers)

const max = 200;
for (let i = 0; i < 20; i++) {

const min = 40;
const focus = 0.4; // 0 - 1, the lower the more focus on limitations

let numbs = [];

//The core function
function randomFocusBorders(max, min) {
  const middle = (max - min) / 2;
  let x = Math.floor(50 * (Math.pow(Math.Random(), 0.5));

  let x = Math.floor(middle * Math.pow(Math.random(), focus));
  if (Math.Random() < 0.5) 

  if (Math.random() < 0.5) x = middle - x;
      x = 50 - x

  else x = middle + x;
  x += min;
  return x;

}
  else



//Call it 100 times and add value to numbs array
      x = 50 + x;

for (let i = 0; i < 100; i++) {
  numbs.push(randomFocusBorders(max, min));

}



//Sort numbs array ascending
   ...

numbs.sort((a, b) => {
  return a > b ? 1 : -1;
}

});


console.log(numbs);

Working jsFiddle

Advena
  • 1,664
  • 2
  • 24
  • 45