note 54299 deleted from function.mt-rand by bjori

From: Date: Sun, 16 Apr 2006 12:37:39 +0000
Subject: note 54299 deleted from function.mt-rand by bjori
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-108267@lists.php.net to get a copy of this message
Note Submitter: trojjer at gmail dot com ---- To test the "randomisationality" or whatever it's called for this, I tried to devise a simple ol' "Coin Flip Simulator", thus: <?php $trials=($argv[1] >= 1) ? $argv[1] : 100000; $repeats=($argv[2] > 1) ? $argv[2] : 1; # command line attributes and their default values $max=100; # change if necessary -- "bug" on my PC; can't use the var-name in mt_rand()??? function getRnd() { mt_srand(); return mt_rand(0, 100); } # Rules out possible WinXP bug by re-seeding each time # (no, I haven't got around to trying any PC alt-OS's yet, ahem.) $heads=$tails=array(0); # they're arrays in order to keep track of repeated cycles, if necessary -- see below: while($repeats > 0) { # sets up countdown from $argv[2] for($n=0; $n<$trials; $n++) { $rnd=getRnd(); while($rnd==$max) {$rnd=getRnd();} # if it's the max number, fetch it again randomly until it's not if($rnd >= 0 && $rnd < $max/2) {$heads[$repeats]++;} } # "If it's less than the mid-value, add one to the Heads." $tails[$repeats]=$trials-$heads[$repeats]; #get remaining 'Tail-count' by difference echo "$repeats:\\n". "{$heads[$repeats]} [". round($heads[$repeats]/$trials*100, 4) ."%] heads\\n". "{$tails[$repeats]} [". round($tails[$repeats]/$trials*100, 4) ."%] tails ($trials trials)\\n\\n"; $repeats--; } ?> I'm not sure whether or not it's the easiest or most correct way to do it, but it seems to present fairly random results, especially with high numbers of trials. I tried it at 1000000 and beyond, but you don't need any more than the default 100000 to see a "decent" distribution, I think. It'll be "humanly clear" with quite a bit less than that, even. The $max value doesn't seem to affect the pseudo-random function data, really -- I noticed about the same distributions when using the range of mt_rand(0,2). [0 <= 1 for Head, of course.] Also, does anyone know why it wouldn't let me substitute the variable into the mt_rand() call? I'm using PHP5... I tried casting it as an integer to no avail; in the end I just typed in mt_rand(0, 100) as you can see. Otherwise, it must've been returning null or something -- it was reporting 100.001% Heads, damnit. Example command line and output: >php cointoss.php - 3 1000 3: 49895 [49.895%] heads 50105 [50.105%] tails (100000 trials) 2: 50123 [50.123%] heads 49877 [49.877%] tails (100000 trials) 1: 50000 [50%] heads 50000 [50%] tails (100000 trials) (As you can see, I presume, the $repeat attribute is just in case you wish to compare results. The arrays are assigned in reverse too, and they stop at index [1]. And I swear I witnissed that genuine output for number 1 -- complete 50:50 distribution! lol, it's a good generator all right... Has anyone else stumbled across that moment? Is it more common than I thought for a "pseudo-random" gen?)

« previous php.notes (#108267) next »