Generate a random number in the range [M .... N] with average X

Creating a random number in the range [M..N] is quite simple. However, I would like to create a series of random numbers in this range with a mean X (M <X <N).

For example, suppose the following: M = 10,000 N = 1,000,000 X = 20,000 I would like to generate (a large number) of random numbers to cover the entire [M..N] range, but in this case, numbers close to N should become extremely rare . Numbers close to M should be more common to make sure the average converges to X.

The intended target language is PHP, but it is not a matter of language as such.

+5
source share
1 answer

There are many ways to achieve this, and this will vary greatly depending on your accuracy requirements. The following code uses rule 68-95-99.7 , based on the normal distribution, with a standard deviation of 15% from the mean.

No:

  • provide accurate accuracy. If you need it, you need to calculate the real average value and compensate for the missing amount.
  • dynamically generates a true normal distributed curve, since all three pieces (68-95-99.7) are considered equal within their groups.

However, it gives you a start:

<?php $mean = (int)$_GET['mean']; // The mean you want $amnt = (int)$_GET['amnt']; // The amount of integers to generate $sd = $mean * 0.15; $numbers = array(); for($i=1;$i<$amnt;$i++) { $n = mt_rand(($mean-$sd), ($mean+$sd)); $r = mt_rand(10,1000)/10; // For decimal counting if($r>68) { if(2==mt_rand(1,2)) // Coin flip, should it add or subtract? { $n = $n+$sd; } else { $n = $n-$sd; } } if($r>95) { if(2==mt_rand(1,2)) { $n = $n+$sd; } else { $n = $n-$sd; } } if($r>99.7) { if(2==mt_rand(1,2)) { $n = $n+$sd; } else { $n = $n-$sd; } } $numbers[] = $n; } arsort($numbers); print_r($numbers); // Echo real mean to see how far off you get. Typically within 1% /* $sum = 0; foreach($numbers as $val) { $sum = $sum + $val; } echo $rmean = $sum/$amnt; */ ?> 

Hope this helps!

+1
source

Source: https://habr.com/ru/post/1238556/


All Articles