Perl Cd Bookshelf [Electronic resources]

نسخه متنی -صفحه : 875/ 464
نمايش فراداده

4.18. Randomizing an Array

4.18.1. Problem

You want to randomly shuffle the elements of an array. The obvious application is writing a card game, where you must shuffle a deck of cards, but it is equally applicable to any situation where you want to treat elements of an array in a random order.

4.18.2. Solution

Use the shuffle function from the standard List::Util module, which returns the elements of its input list in a random order.

use List::Util qw(shuffle);
@array = shuffle(@array);

4.18.3. Discussion

Shuffling is a surprisingly tricky process. It''s easy to write a bad shuffle:

sub naive_shuffle {                             # DON''T DO THIS
for (my $i = 0; $i < @_; $i++) {
my $j = int rand @_;                    # pick random element
($_[$i], $_[$j]) = ($_[$j], $_[$i]);    # swap ''em
}
}

This algorithm is biased; the list''s possible permutations don''t all have the same probability of being generated. The proof of this is simple: take the case where we''re passed a three-element list. We generate three random numbers, each of which can have three possible values, yielding 27 possible outcomes. There are only six permutations of the three-element list, though. Because 27 isn''t evenly divisible by 6, some outcomes are more likely than others.

The List::Util module''s shuffle function avoids this bias to produce a more randomly shuffled result.

If all you want to do is pick one random element from the array, use:

$value = $array[ int(rand(@array)) ];

4.18.4. See Also

The rand function in perlfunc(1) and Chapter 29 of Programming Perl; for more on random numbers, see Recipe 2.6, Recipe 2.7, and Recipe 2.8; Recipe 4.20 provides another way to select a random permutation