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

Ken*_*ams 5 php random numbers distribution probability

生成[M..N]范围内的随机数很容易.然而,我希望在该范围内生成一系列随机数,其中平均值为X(M <X <N).

例如,假设如下:M = 10000 N = 1000000 X = 20000我想生成(大量)随机数,以便覆盖整个范围[M..N],但在这种情况下数字更接近N应该变得非常罕见.接近M的数字应该更常见,以确保平均值收敛于X.

预期的目标语言是PHP,但这本身并不是语言问题.

Fre*_*rik 1

有很多方法可以实现这一点,并且根据您对精度的要求而有所不同。以下代码使用基于正态分布的68-95-99.7 规则,标准差为平均值的 15%。

它不是:

  • 确保精确的精度。如果您需要这个,您必须计算实际平均值并补偿缺失的金额。
  • 动态创建了一条真正的正态分布曲线,因为所有三个块 (68-95-99.7) 在其组内被认为是相等的。

然而它确实给了你一个开始:

<?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; 
*/

?>
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你!