Jump to content

array_rand question.


Samuz

Recommended Posts

Hey guys, quick question.

 

The array_rand() function. How random is it?

 

I'm building an app in codeigniter where i'd need to return 2/6 keys from an array and store them in a DB. I don't want it to return a key that has already been returned.

 

I'm sure logically there's always a chance that I could get back something that has already been returned.

 

Also i'm using the function at the same time, so it isn't over any period of time or within different methods.

 

Are there any other recommendations apart from array_rand() ?

 

Thanks!

Link to comment
Share on other sites

Well, I ran some tests and it doesn't seem to be very random at all. When I had a small number of array elements the results 'appeared' to be fairly random - some combinations appeared only one time and others appeared many. But, when I increased the number of array elements to a large set (2,000) the results were evenly distributed, but definitely not random.

 

Here are a couple of examples:

 

I ran an array with 10 elements (0 - 9) through 10,000 iterations picking 3 "random" entries each time using array_rand(). There were results for every possible combination and the count of each result looked something like this

    [000-001-002] => 83
    [000-001-003] => 87
    [000-001-004] => 121
    [000-001-005] => 62
    [000-001-006] => 93
    [000-001-007] => 101
    [000-001-008] => 87
    [000-001-009] => 89
    [000-002-003] => 98
    [000-002-004] => 100
    [000-002-005] => 85
    [000-002-006] => 94
    [000-002-007] => 69

That 'looks' fairly random.

 

But, when I increased the array count to 200 items (0 - 199) for 10,000 occurrences the results were very odd. There were only 217 unique combinations and each one had almost the same number of occurrences. And, even though some of the combinations in the results changed each time I ran the script there was ALWAYS 217 combinations. Here is part of a sample result.

    [000-170-193] => 46
    [001-006-011] => 47
    [001-012-050] => 46
    [001-019-066] => 47
    [001-050-145] => 46
    [001-095-197] => 46
    [002-056-160] => 46
    [002-066-164] => 46
    [002-102-154] => 46
    [002-112-127] => 46
    [003-006-037] => 46
    [003-019-038] => 46

The fact that there was only one combination with the zero value and that all the combinations has 46 or 47 occurrences is definitely not random.

Link to comment
Share on other sites

Below is what I ran. I also changed it to use the method you suggested (see the commented lines) and the results were much more in line with what I would expect. I even ran it out to 200K iterations. And it "looked" fairly random.

$array_count = 200;
$iterations = 10000;

$range = range(0, $array_count-1);
$results = array();
for ($i = 0; $i < $iterations; $i++)
{

    $random_pick = array_rand($range, 3);
    //shuffle($range);
    //$random_pick = array($range[0], $range[1], $range[2]);

    foreach($random_pick as $key => $value) { $random_pick[$key] = str_pad($value, 3, '0', STR_PAD_LEFT); }
    sort($random_pick);
    $pick_idx = implode('-', $random_pick);

    if(!isset($results[$pick_idx]))
    {
        $results[$pick_idx] = 0;
    }
    $results[$pick_idx]++;
}
ksort($results);
echo count($results);
echo "<pre>";
print_r($results);
echo "</pre>";

Link to comment
Share on other sites

array_rand() has a history of not being terribly random, with the problem getting worse as the size of the array or the number of samples increases. I believe they adjusted the logic a while back (like in the 5.2 tree) so recent versions of PHP should be fine. Like I ran your code on a 5.3 and it worked as expected; if I still had a 4.4 and 5.2 around I'd try on those too.

Link to comment
Share on other sites

Seems it's a platform thing.  The code on my linux box produces a pretty spread out/random result where as when run on my windows system it is more condensed.  A note on the rand() page says window's rand max is 32767, may have something to do with it.  Or maybe a difference in the system implementation of rand.

 

 

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.