./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); }