为什么用Perl的List :: Util :: shuffle会得到不好的随机分布?

时间:2019-03-07 01:37:02

标签: arrays perl shuffle

我收集了数百个黑胶唱片,由目录ID字符串按字母数字顺序组织。我编写了一个脚本,该脚本通过对随机排列的目录ID数组进行采样,从我的收藏集中随机选择20条记录。但是,我发现它为我选择的记录常常分布不佳。通常,它会选择2个具有顺序目录ID的记录,和/或几组彼此靠近的记录。从800条记录中选择20条记录时,这种情况很少发生。

我将目录ID的列表存储在$(function(){ $("#storInfoTB").edatagrid({}); }); 数组中,并从该数组中随机抽取20个项目的样本,我从混洗后的数组中分配前20个项目:

@selection

无奈之下,我尝试使用这种丑陋的技术来试图增强随机性,但似乎没有任何区别:

@selection = (shuffle @selection)[0 .. 19];

1 个答案:

答案 0 :(得分:5)

有C(800,20)= 3.73×10 39 从800个中选择20个标题的方法。

有C(781,20)= 2.29×10 39 从800个中没有两个相邻的标题中选择20个标题的方法。 [1]

因此,选择一个不包含相邻标题的集的机会为(2.29×10 39 )/(3.73×10 39 )= 61.4%。 >

因此,选择包含相邻标题的集的可能性为1-61.4%= 38.6%。

现在我们知道该期待什么了,让我们shuffle进行测试。

测试:

#!/usr/bin/perl
use strict;
use warnings;
use List::Util qw( shuffle );

my $num_tests = 100_000;
my $N = 800;
my @titles = 0..($N-1);
my $has_adjacent_titles = 0;
for (1..$num_tests) {
   my @shuffled_selection = ( shuffle(@titles) )[0..19];
   my @ordered = sort { $a <=> $b } @shuffled_selection;
   ++$has_adjacent_titles if grep { $ordered[$_-1]+1 == $ordered[$_] } 1..$#ordered;
}

printf "%.1f%%\n", $has_adjacent_titles / $num_tests * 100;

输出:

>a.pl
38.6%

>a.pl
38.8%

>a.pl
38.5%

似乎shuffle运作良好。


  1. 请参见Combinatorial restriction on choosing adjacent objects