in reply to custom random number generator
Update: Ignore this. It works for my test values, but not for others.
How about:
#! perl -slw use strict; use Data::Dump qw[ pp ]; sub xrand { my( $x, $y ) = @_; my $lo = $x / $y; my $hi = $x * $y; if( rand() < 0.5 ) { my $root = sqrt( $hi - $x ); return rand( $root )**2 + $x; } else { my $root = sqrt( $x - $lo ); return rand( $root )**2 + $lo; } } our $T //= 1000; our $X //= 10; our $Y //= 2; my $min = $X / $Y; my $max = $X * $Y; my( $loCount, $exactX, $hiCount ) = (0) x 3; my %dist; for ( 1 .. $T ) { my $rand = ( xrand( $X, $Y ) + xrand( $X, $Y ) ) / 2; die 'Out of range' unless $rand >= $min and $rand <= $max; if( $rand < $X ) { ++$loCount; } elsif( $rand > $X ) { ++$hiCount; } else { ++$exactX; } ++$dist{ int( $rand ) }; } printf "After $T samples %f%% < %f%% < %f%%\n", $loCount * 100 / $T, $exactX *100 / $T, $hiCount * 100 / $T; pp \%dist; __END__ [16:48:43.26] c:\test>940642 -T=1e5 -X=10 -Y=2 After 1e5 samples 52.650000% < 0.000000% < 47.350000% { 5 => 8052, 6 => 7709, 7 => 11881, 8 => 13451, 9 => 11557, 10 => 12360, 11 => 10501, 12 => 8761, 13 => 5885, 14 => 4549, 15 => 2476, 16 => 1445, 17 => 808, 18 => 436, 19 => 129, }
|
|---|