#!/usr/bin/env perl
use warnings;
use strict;
die "perl $0 <样本总个数> <样本子集组合> <样本子集>\n
e.g. perl $0 96 100 2 > 96.txt \n
" unless @ARGV eq 3;
my $sample = $ARGV[0]; # 样本数目
my $n = $ARGV[1]; # 取出样本的子集数目
my $ex_samp = $ARGV[2]; # 取出样本的个数
my $fac_samp = &fac($sample);
my $fac_ex_samp = &fac($ex_samp);
die "不可能取出比样本数目还要多的情况!!!" if($sample < $ex_samp);
my $c = $fac_samp / ($fac_ex_samp * &fac($sample - $ex_samp));
die "这是一个取出有放回且子集不重复的组合,取出的子集组合不能大于全集所有可能的排列组合!!!" if($n > $c);
my %hash;
for(my $i = 0;$i < $n; $i ++)
{
my @sub;
for(my $j = 0; $j < $ex_samp; $j ++)
{
push @sub, int(rand($sample) + 1);
}
my $str = join "-", sort @sub;
my $repeat;
my %rep;
foreach my $k(@sub)
{
$rep{$k} ++;
if($rep{$k} eq 2)
{
$repeat = 1;
last;
}
}
if(exists $hash{$str} or $repeat eq 1)
{
$n ++;
}else{
$hash{$str} = 0;
print "$str\n";
}
}
#print "$n\n";
sub fac(){
if($_[0] eq 1)
{
return 1;
}elsif($_[0] eq 0){
return 1; #可以写0,不过1更好,因为涉及到组合的公式~
}else{
return ($_[0] * &fac($_[0] - 1));
}
}
总的来说,满足等概率取出样本,并且组合形式不重复,涉及到了一些高中的知识,还好没忘。。。
perl 取出放回且子集不重复的组合情况
最新推荐文章于 2022-08-31 23:02:02 发布