Randomize a PHP array with a seed?
The problem you have is that PHP comes with two random number generators built in.
The shuffle()
command does not use the mt_rand()
random number generator; it uses the older rand()
random number generator.
Therefore, if you want shuffle()
to use a seeded number sequence, you need to seed the older randomiser, using srand()
rather than mt_srand()
.
In most other cases, you should use mt_rand()
rather than rand()
, since it is a better random number generator.
Sorry, but accordingly to the documentation the shuffle function is seeded automatically.
Normally, you shouldn't try to come up with your own algorithms to randomize things since they are very likely to be biased. The Fisher-Yates algorithm is known to be both efficient and unbiased though:
function fisherYatesShuffle(&$items, $seed)
{
@mt_srand($seed);
for ($i = count($items) - 1; $i > 0; $i--)
{
$j = @mt_rand(0, $i);
$tmp = $items[$i];
$items[$i] = $items[$j];
$items[$j] = $tmp;
}
}
Example (PHP 5.5.9):
php > $original = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
php > $shuffled = (array)$original;
php > fisherYatesShuffle($shuffled, 0);
php > print_r($shuffled);
Array
(
[0] => 6
[1] => 0
[2] => 7
[3] => 2
[4] => 9
[5] => 3
[6] => 1
[7] => 8
[8] => 5
[9] => 4
)
php > $shuffled = (array)$original;
php > fisherYatesShuffle($shuffled, 0);
php > print_r($shuffled);
Array
(
[0] => 6
[1] => 0
[2] => 7
[3] => 2
[4] => 9
[5] => 3
[6] => 1
[7] => 8
[8] => 5
[9] => 4
)
You can use array_multisort
to order the array values by a second array of mt_rand
values:
$arr = array(1,2,3,4,5,6);
mt_srand('123');
$order = array_map(create_function('$val', 'return mt_rand();'), range(1, count($arr)));
array_multisort($order, $arr);
var_dump($arr);
Here $order
is an array of mt_rand
values of the same length as $arr
. array_multisort
sorts the values of $order
and orders the elements of $arr
according to the order of the values of $order
.