523066680 写了:我先抛个砖头,随机取n次,逐次缩减范围。
缺点:由于范围逐次递减,会呈现越往后数值越小的趋势。our $R = 56;
our $n = 5; # the number you need
our $m = 60;
grep { test() } (1 .. 10);
sub test
{
my $get;
my $left = $m;
my @poss;
for ( my $t = $n; $t > 1; $t-- )
{
$get = int(rand($left-$t))+1;
push @poss, $get;
$left -= $get;
}
push @poss, $left;
printf "%s\n", join(",", @poss);
}
输出示例:29,9,15,1,6
32,16,3,4,5
51,2,2,3,2
29,6,13,8,4
38,17,2,1,2
23,13,18,3,3
35,6,1,12,6
45,9,3,1,2
54,1,2,1,2
40,16,1,1,2
可以看到每一个都有明显特征
显然, 解组合中数值的分布频率肯定不是每个数都一样的, 比如 56, 只在一个解组合 {56,1,1,1,1} 里出现, 而 55 只在 {55,2,1,1,1} 中出现, 粗略地, 偏离频率分布最高的数值越大的数出现的可能性越低, 频率分布的高峰猜测为12
如何判断一个算法是否足够随机, 最自然的方式显然是所有解组合都有一样的概率出现, 而不是每种数值都是均等概率出现.
此算法输出示例中, 每轮第1次生成的随机数最小都是 23, 不知更大的样本中, 是否小数也一样均等的在第1次出现(第1次生成的随机数不同于后面生成的随机数被前面出现的随机数进一步减小数值可能性范围)