假设我有一个数字,例如100,我希望生成5个不同的随机数,但它们都必须加起来100,我该怎么做? (最好是PHP。对于数学向导/统计学家,我不需要真正随机的数字,但看起来是随机的)。
所以这个函数会产生这样的东西:
5,51,9,18,19 = 100 34,52,3,7,4 = 100
等等。
理想情况下,需要5,100并产生其余的东西:
generateRandom(100,5)
答案 0 :(得分:4)
a = RandomInteger[{1, 96}]
b = RandomInteger[{1, 97 - a}]
c = RandomInteger[{1, 98 - a - b}]
d = RandomInteger[{1, 99 - a - b - c}]
e = 100 - a - b - c - d
样品:
{34,25,26,3,12,Sum =,100}
{90,5,1,1,3,Sum =,100}
{29,16,21,9,25,Sum =,100}
{4,13,71,10,2,Sum =,100}
当然,数字并不均匀分布。
修改
这是一个更均匀的分布:
a = RandomInteger[{1, 20}];
b = RandomInteger[{1, 40 - a}];
c = RandomInteger[{1, 60 - a - b}];
d = RandomInteger[{1, 80 - a - b - c}];
e = 100 - a - b - c - d;
输出:
{5,33,2,8,52,Sum =,100}
{14,9,50,5,22,Sum =,100}
{3,23,12,34,28,Sum =,100}
{1,16,4,5,74,Sum =,100}
{6,28,6,9,51,Sum =,100}
{11,25,7,1,56,Sum =,100}
{4,34,12,18,32,Sum =,100}
{6,13,25,26,30,Sum =,100}
{8,27,14,5,46,Sum =,100}
{17,13,23,25,22,Sum =,100}
以下是数字的频率:
修改
也许是更好的一个:
a = Max[#, 1] & /@ Evaluate[RandomInteger[{1, 20}, 5] - 1];
b = 100 - Total@a;
c = Mod[b, 5];
d = (b - c)/ 5;
a = a + d + {c, 0, 0, 0, 0};
分布:
修改强>
在Mathematica中,您可以轻松生成所有5个元组,这些元组加起来为:
IntegerPartitions[100, {5}]
有38225种不同的野兽,不计算排列
Length@IntegerPartitions[100, {5}]
(* -> 38225 *)
这些五胞胎中每个数字的频率为:
Histogram@Flatten@IntegerPartitions[100, {5}]
如果将排列考虑在内,曲线非常相似:
t = Tally@Flatten@(Permutations[#] & /@ IntegerPartitions[100, {5}]);
ListLinePlot@SortBy[t, #[[1]] &][[All, 2]]
答案 1 :(得分:1)
沿着belisarius:
// Generates an array (of $elements elements) full of random numbers whose
// total is equal to the $total_sum
function generate_random_array($elements = 5, $total_sum = 100)
{
// build result array
$result = Array();
// iterate over all elements (except for the last, last will be the delta)
for ($_ = 0; $_ < ($elements - 1); $_++)
{
// typical low value (non-zero)
$low_value = 1;
// high value, skewed to have high results first
//$high_value = ($total_sum - ($elements - $_) - array_sum($result));
// high value, non-skewed
$step = (int)floor($total_sum / $elements); // give "not-to-exceed" ranges
$high_value = (($_ + 1) * $step) - array_sum($result);
// produce the result and add it
$result[] = rand($low_value,$high_value);
//$result[] = rand(1,65535) % $high_value + 1; // alternate to make rand a little smoother
}
// add the final result as the remainder
$result[] = $total_sum - array_sum($result);
// now return it
return $result;
}