FWIW. To the best of my ability to test it, and walking on the shoulders of those better versed in statistics than I, my implementation of Fisher-Yates algorithm compares favourably with that given in the FAQ.
#!/usr/bin/perl -w
use strict;
use vars qw/$size $iter/;
use Benchmark qw(cmpthese);
use Data::Dumper;
$size ||= 1000;
$iter ||= 1000;
sub FAQ_FY {
my $array = shift;
my $i;
for ($i = @$array; --$i; ) {
my $j = int rand ($i+1);
next if $i == $j;
@$array[$i,$j] = @$array[$j,$i];
}
}
sub shuffl (\@) {
my $r=pop;
$a = $_ + rand @{$r} - $_ and @$r[$_, $a] = @$r[$a, $_]
for (0..$#{$r});
}
my @array = 1 .. $size;
cmpthese(-1, {
FAQ_FY => sub { FAQ_FY \@array },
shuffl => sub { shuffl @array },
});
my (%buckets, %d, @temp);;
my @set = qw(A B C D);
for (1 .. $iter ) {
@temp=@set; FAQ_FY \@temp; $buckets{"@temp"}{FAQ_FY}++;
@temp=@set; shuffl @temp; $buckets{"@temp"}{shuffl}++;
}
print "\npermutation | FAQ_FY | shuffl \n";
print "----------------------------------\n";
for my $key (sort keys %buckets) {
printf "%8.8s: | %4d | %4d \n", $key,
$buckets{$key}{FAQ_FY},
$buckets{$key}{shuffl},
$d{FAQ_FY}{Ex} += $buckets{$key}{FAQ_FY}; $d{FAQ_FY}{Ex2} += $buck
+ets{$key}{FAQ_FY}**2;
$d{shuffl}{Ex} += $buckets{$key}{shuffl}; $d{shuffl}{Ex2} += $buck
+ets{$key}{shuffl}**2;
}
print "------------------------------------------------------\n";
printf "Std. Dev. | %0.3f | %0.3f \n",
sqrt( ($d{FAQ_FY}{Ex2} - ($d{FAQ_FY}{Ex}**2/24))/23 ),
sqrt( ($d{shuffl}{Ex2} - ($d{shuffl}{Ex}**2/24))/23 );
__END__