2

我在数据库表中有超过 200 个条目,我想为每个条目生成一个随机值,但最后,条目值的总和必须等于 100。是否可以使用 for 循环和 rand( ) 在 PHP 中?

4

5 回答 5

3

您可以简单地标准化一组数字,例如:

$numbers = array();
for ($i = 0; $i < 200; $i += 1) {
  $numbers[] = rand();
}

$sum = array_sum($numbers);

// divide $sum by the target sum, to have an instant result, e.g.:
// $sum = array_sum($numbers) / 100;
// $sum = array_sum($numbers) / 42;
// ...

$numbers = array_map(function ($n) use($sum) {
  return $n / $sum;
}, $numbers);

print_r($numbers);
print_r(array_sum($numbers)); // ~ 1

演示:http ://codepad.viper-7.com/RDOIvX

于 2013-06-03T20:34:40.603 回答
1

您的问题的解决方案是将数字从 0 到 200,然后放入数组中,然后对这些值求和,然后除以 200。循环遍历元素并将每个元素除以先前等式的结果,它会给你答案

$sum = 0;
$max = 100; //max value to be sumed
$nr_of_records = 200; // number of records that should sum to $max
$arr = array();
for($i=0;$i<$nr_of_records;++$i)
{
   $arr[$i] = rand(0,$max);
}

$div = array_sum($arr) / $max;


for($i=0;$i<$nr_of_records;++$i)
{
  $arr[$i] /= $div;
  echo $arr[$i].'<br>';
}

echo array_sum($arr);

创造了活生生的例子

于 2013-06-03T20:26:41.740 回答
1

100 到底有多准确?只是好奇,因为所有提示都以使用浮点值结束,这往往是不准确的。

我建议使用分数...假设 10000 个分数,每个分数为 1/100 点(10000 * 1/100 = 100 点)。使用整数将 10000 个点分配给 200 个元素 - 并且绝对确定,所有整数除以 10000 的总和为 100。不需要浮点数,只要想想就在拐角处……

于 2013-06-03T20:51:22.697 回答
1

做多/少:

$size = 200;
$sum = 100;
$places = 3;

$base = round($sum/$size, $places);

$values = array_fill(0, $size, $base);

for($i=0; $i<$size; $i+=2) {
    $diff = round((rand()/getrandmax()) * $base, $places);
    $values[$i]   += $diff;
    $values[$i+1] -= $diff;
}

//optional: array_shuffle($values);

$sum = 0;

foreach($values as $item) {
    printf("%0.3f ", $item);
    $sum += $item;
}

echo $sum;

输出:

0.650 0.350 0.649 0.351 0.911 0.089 0.678 0.322 0.566 0.434 0.563 0.437 0.933 0.067 0.505 0.495 0.503 0.497 0.752 0.248 0.957 0.043 0.856 0.144 0.977 0.023 0.863 0.137 0.766 0.234 0.653 0.347 0.770 0.230 0.888 0.112 0.637 0.363 0.716 0.284 0.891 0.109 0.549 0.451 0.629 0.371 0.501 0.499 0.652 0.348 0.729 0.271 0.957 0.043 0.769 0.231 0.767 0.233 0.513 0.487 0.647 0.353 0.612 0.388 0.509 0.491 0.925 0.075 0.797 0.203 0.799 0.201 0.588 0.412 0.788 0.212 0.693 0.307 0.688 0.312 0.847 0.153 0.903 0.097 0.843 0.157 0.801 0.199 0.538 0.462 0.954 0.046 0.541 0.459 0.893 0.107 0.592 0.408 0.913 0.087 0.711 0.289 0.679 0.321 0.816 0.184 0.781 0.219 0.632 0.368 0.839 0.161 0.568 0.432 0.914 0.086 0.991 0.009 0.979 0.021 0.666 0.334 0.678 0.322 0.705 0.295 0.683 0.317 0.869 0.131 0.837 0.163 0.792 0.208 0.618 0.382 0.606 0.394 0.574 0.426 0.927 0.073 0.661 0.339 0.986 0.014 0.759 0.241 0.547 0.453 0.804 0.196 0.681 0.319 0.960 0.040 0.708 0.292 0.558 0.442 0.605 0.395 0.986 0.014 0.621 0.379 0.992 0.008 0.622 0.378 0.937 0.063 0.884 0.116 0.840 0.160 0.607 0.393 0.765 0.235 0.632 0.368 0.898 0.102 0.946 0.054 0.794 0.206 0.561 0.439 0.801 0.199 0.770 0.230 0.843 0.157 0.681 0.319 0.794 0.206 100

如果您不使用像 100 和 200 这样的漂亮数字,则舍入会变得有点模糊,但不会超过 0.1。

于 2013-06-03T22:50:08.443 回答
-2

昨天的原始问题正好有 200 个条目,总和“不大于 100”。我昨天的原始答案:

确保使用不大于 0.5 的随机数。

或者,根据这些数字需要有多“随机”(允许多少相关性),您可以保持一个运行总数,如果它变得不成比例地高,您可以混合一堆较小的值。

编辑:

改变问题的方式,让我看起来很愚蠢并被否决。

要获得精确的总和,您必须进行标准化,并更好地使用精确分数而不是浮点数以避免舍入错误。

于 2013-06-03T20:25:17.627 回答