简体   繁体   English

使用平均值X生成范围[M ... N]中的随机数

[英]Generate random number in range [M…N] with mean X

Generating a random number in the range [M..N] is easy enough. 生成[M..N]范围内的随机数很容易。 I however would like to generate a series of random numbers in that range with mean X (M < X < N). 然而,我希望在该范围内生成一系列随机数,其中平均值为X(M <X <N)。

For example, assume the following: M = 10000 N = 1000000 X = 20000 I would like to generate (a large amount of) random numbers such that the entire range [M..N] is covered, but in this case numbers closer to N should become exceedingly more rare. 例如,假设如下:M = 10000 N = 1000000 X = 20000我想生成(大量)随机数,以便覆盖整个范围[M..N],但在这种情况下数字更接近N应该变得非常罕见。 Numbers closer to M should be more common to ensure that the mean converges to X. 接近M的数字应该更常见,以确保平均值收敛于X.

The intended target language is PHP, but this is not a language question per se. 预期的目标语言是PHP,但这本身并不是语言问题。

There are many ways to accomplish this, and it would differ very much depending on your demands on precision. 有很多方法可以实现这一点,根据您对精度的要求,它会有很大不同。 The following code uses the 68-95-99.7 rule , based on the normal distribution, with a standard deviation of 15% of the mean. 以下代码使用68-95-99.7规则 ,基于正态分布,标准偏差为平均值的15%。

It does not: 它不是:

  • ensure exact precision. 确保准确的精度。 If you need this you have to calculate the real mean and compensate for the missing amount. 如果您需要这个,您必须计算实际平均值并补偿缺失的金额。
  • created a true normal distributed curve dynamically, as all the three chunks (68-95-99.7) are considered equal within their groups. 动态创建一个真正的正态分布曲线,因为所有三个块(68-95-99.7)在其组内被认为是相等的。

It does however give 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 it helps! 希望能帮助到你!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM