./fisher_yates.pl : after 5000 trials shuffling arrays of size 1000:
List::Util::shuffle : 1693 successes, mean:0.0105896962736892, stdev:0.00900688731621982
BUK : 1685 successes, mean:0.010799062825769, stdev:0.00921403469412604
tybalt89 : 1622 successes, mean:0.0102906705829024, stdev:0.00843760632828801
####
./fisher_yates.pl : after 5000 trials shuffling arrays of size 1000:
BUK : 1696 successes, mean:0.0104235933728858, stdev:0.00897497055761236
List::Util::shuffle : 1690 successes, mean:0.0106133000677379, stdev:0.00908235156157047
tybalt89 : 1614 successes, mean:0.0100835174626996, stdev:0.00897955319759652
####
./fisher_yates.pl : after 5000 trials shuffling arrays of size 1000:
List::Util::shuffle : 1690 successes, mean:0.0104611128054915, stdev:0.00886345338184372
BUK : 1658 successes, mean:0.0102429744950854, stdev:0.00848038138137249
tybalt89 : 1652 successes, mean:0.0105683142305418, stdev:0.00899061563593633
####
#!/usr/bin/env perl
use strict;
use warnings;
use Statistics::Histogram;
use Statistics::Autocorrelation;
use Statistics::Descriptive;
use List::Util qw/shuffle/;
my $N = 1000;
my $trials = 50;
my %mins = ();
for(1..$trials){
my $res = assess_once();
if( exists $mins{$res->[0]} ){
push(@{$mins{$res->[0]}}, $res->[1]->[1]);
} else {
$mins{$res->[0]} = [$res->[1]->[1]];
}
}
print "$0 : after $trials trials shuffling arrays of size $N:\n";
foreach (keys %mins){
my @re = @{$mins{$_}};
my $stats = Statistics::Descriptive::Full->new();
$stats->add_data(@re);
print $_." : ".scalar(@re)." successes, mean:".$stats->mean().", stdev:".$stats->standard_deviation()."\n";
}
sub assess_once {
my %results = ();
my @array = 1..$N;
shuffleAry_1( \@array );
$results{'BUK'} = [
histo_of_differences(\@array),
corello_abs(\@array)
];
@array = List::Util::shuffle(1..$N);
$results{'List::Util::shuffle'} = [
histo_of_differences(\@array),
corello_abs(\@array)
];
@array = 1..$N;
@array = @{shuffleAry_2( \@array )};
$results{'tybalt89'} = [
histo_of_differences(\@array),
corello_abs(\@array)
];
my @keys_sorted_autocor_desc =
sort { $results{$a}->[1] <=> $results{$b}->[1] } keys %results;
foreach (@keys_sorted_autocor_desc){
my $hist = $results{$_}->[0];
my $autocor = $results{$_}->[1];
print $_.") Autocorrelation coefficient: ".$autocor."\n";
print $_.") Histogram of the differences of consecutive elements:\n".$hist."\n";
print "--------------------------\n\n\n";
}
foreach (@keys_sorted_autocor_desc){
my $hist = $results{$_}->[0];
my $autocor = $results{$_}->[1];
print $_.") Autocorrelation coefficient: ".$autocor."\n";
}
print "assess() : minimum autocorrelation coeff is "
.$results{$keys_sorted_autocor_desc[0]}->[1]
." for ".$keys_sorted_autocor_desc[0]
."\n";
print "assess() : done\n";
return [$keys_sorted_autocor_desc[0], $results{$keys_sorted_autocor_desc[0]}]
}
exit(0);
sub shuffleAry_2 {
my $arr = $_[0];
return [
map $_->[0],
sort { $a->[1] <=> $b->[1] }
map [ $_, rand ], @{$arr}
]
}
sub shuffleAry_1 {
die 'Need array reference' unless ref( $_[0] ) eq 'ARRAY';
our( @aliased, $a, $b ); local( *aliased, $a, $b ) = $_[0];
$a = $_ + rand @aliased - $_,
$b = $aliased[ $_ ],
$aliased[ $_ ] = $aliased[ $a ],
$aliased[ $a ] = $b
for 0 .. $#aliased;
return;
}
sub corello_abs {
my $arr = $_[0];
my $acorr = Statistics::Autocorrelation->new();
return abs(
$acorr->coefficient(
data => $arr,
lag=>1
)
)
}
sub histo_of_differences {
my $arr = $_[0];
my $N = $#$arr;
my @diffs = (0)x($N);
for(1..$N){
$diffs[$_-1] = abs($arr->[$_] - $arr->[$_-1]);
}
return Statistics::Histogram::get_histogram(\@diffs);
}