php - 获取 2 个平均值为 `n` 的数字之间的 `x` 随机值

标签 php algorithm random range average

我想获得 1 到 5(包括两者)之间的 n 个随机数(例如 n=16)(整数),以便平均值为 x。

x 可以是 (1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5) 之间的任何值。

我正在使用 PHP。

例如 假设我有平均值 x= 3。

然后要求 1 到 5 之间的 16 个整数(包括两者)。 喜欢 (1,5,3,3,3,3,2,4,2,4,1,5,1,5,3,3)

更新:

如果 x=3.5 意味着 16 个数字的平均值应该在 3.5 到 4 之间。
如果 x=4 意味着 16 个数字的平均值应该在 4 到 4.5 之间
如果 x=5 表示所有数字都是 5

最佳答案

这个答案允许目标平均值的任何值(无论 n 是奇数还是偶数)并且避免使用递归来优化性能。

函数

function getRandomNumbersWithAverage($target_average, $n, $min=1, $max=5)
{

  if($min>$max) list($min, $max) = array($max, $min);
  if($target_average<$min || $target_average>$max) return false;
  else if($target_average==$min) return array_fill(0, $n, $min);
  else if($target_average==$max) return array_fill(0, $n, $max);

  if($n<1) return false;
  else if($n==1) return array($target_average);
  else
  {
    $numbers = array();
    for($i=0;$i<$n;$i++)
    {
      $sum = array_sum($numbers);
      $average = $i ? $sum/($i+1) : ($min+$max)/2;
      $contrived_number = $target_average*($i+1) - $sum;
      // Last one must be contrived
      if($i==$n-1) $new_number = ceil($contrived_number); // Round up
      else
      {
        // The tolerance gets smaller with iteration
        $tolerance = ($max-$min)*(1-($i/($n-1)));
        $temp_min = ($contrived_number-$tolerance);
        if($temp_min<$min) $temp_min = $min;
        $temp_max = ($contrived_number+$tolerance);
        if($temp_max>$max) $temp_max = $max;
        $new_number = mt_rand($temp_min, $temp_max);
      }
      if($new_number==0) $new_number = 0; // Handle -0
      $numbers[] = $new_number;
    }
    // Since the numbers get more contrived towards the end, it might be nice to shuffle
    shuffle($numbers);
    return $numbers;
  }
}


示例输出:

getRandomNumbersWithAverage(1, 12)

produced the numbers: (1,1,1,1,1,1,1,1,1,1,1,1) having an average of: 1


getRandomNumbersWithAverage(1.1, 13)

produced the numbers: (1,1,1,1,1,1,1,4,1,1,1,0,1) having an average of: 1.1538461538462


getRandomNumbersWithAverage(2.7, 14)

produced the numbers: (3,3,2,5,1,2,4,3,3,2,3,3,3,1) having an average of: 2.7142857142857


getRandomNumbersWithAverage(2.7, 15)

produced the numbers: (3,3,4,3,4,2,1,1,3,2,4,1,5,1,4) having an average of: 2.7333333333333


getRandomNumbersWithAverage(3.5, 16)

produced the numbers: (5,5,4,3,1,5,5,1,2,5,3,3,4,4,4,2) having an average of: 3.5


getRandomNumbersWithAverage(3.5, 17)

produced the numbers: (5,2,3,5,4,1,2,3,5,4,5,4,2,3,5,3,4) having an average of: 3.5294117647059


getRandomNumbersWithAverage(4, 18)

produced the numbers: (3,5,5,3,5,5,3,4,4,4,5,2,5,1,5,4,5,4) having an average of: 4


getRandomNumbersWithAverage(4.9, 19)

produced the numbers: (5,5,5,5,7,5,5,5,5,6,5,3,5,5,3,5,5,5,5) having an average of: 4.9473684210526


getRandomNumbersWithAverage(5, 20)

produced the numbers: (5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5) having an average of: 5


getRandomNumbersWithAverage(0.5, 10)

does not produce numbers


getRandomNumbersWithAverage(0, 9)

does not produce numbers


getRandomNumbersWithAverage(-1, 8)

does not produce numbers


getRandomNumbersWithAverage(5.5, 7)

does not produce numbers


getRandomNumbersWithAverage(6, 6)

does not produce numbers


getRandomNumbersWithAverage(6, 5, 1, 7)

produced the numbers: (7,7,2,7,7) having an average of: 6


getRandomNumbersWithAverage(6, 5, 1, 6)

produced the numbers: (6,6,6,6,6) having an average of: 6


getRandomNumbersWithAverage(3, 1)

produced the numbers: (3) having an average of: 3

关于php - 获取 2 个平均值为 `n` 的数字之间的 `x` 随机值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9943619/

相关文章:

php - 如何从 vtiger 5.4.0 中的报价第二页删除标题部分(公司详细信息)

algorithm - 我们可以在小于 O(n*n) ...( nlogn 或 n) 的时间内计算吗

c# - 在没有 Linq 的情况下为 IList 的 IList 删除重复项

java - 用 Java 编写随机答案生成器 - 答案出现在 JFrame 中

r - 使设置随机种子的函数独立

php - PDO 和 MySQL IN/NOT IN 查询的正确格式

PHP Excel - 您尝试打开的文件 .xls 的格式与文件扩展名指定的格式不同

php - Jenkins PHP 模板 - 显示加载消息和 block UI

python - 将 HSV 掩码转换为一组点

random - 自旋验证 - 对随机和随机的 undefined reference