PHP shuffle с семенем?

Как я могу заставить функцию shuffle php использовать семя, так что, когда я использую одно и то же семя, функция shuffle выведет тот же массив. Я читал, что тасовка автоматически посеяна. Есть ли способ получить семя этого тасования, или как я могу создать/имитировать тасование с помощью специального семени?

Ответ 1

Вы не можете получить семя, которое используется в случайном порядке, но вы можете имитировать тасование и исправить собственное семя:

$array = range(1, 10);

function seededShuffle(array &$array, $seed) {
    mt_srand($seed);
    $size = count($array);
    for ($i = 0; $i < $size; ++$i) {
        list($chunk) = array_splice($array, mt_rand(0, $size-1), 1);
        array_push($array, $chunk);
    }
}

$seed = date('Ymd');
seededShuffle($array, $seed);
var_dump($array);

Это будет устанавливать разные семена каждый день, но в течение дня он будет использовать одно и то же семя и перетасовать массив в том же порядке; завтра будет другая случайная перетасовка сегодня

На сегодняшний день (6 июня 2015 года) последовательность должна быть

3, 6, 9, 2, 7, 1, 8, 5, 10, 4

Ответ 2

PHP не имеет перетасовки с посевом, но вы можете сделать это вместо:

$an_array = array('a','b','c','d');
$indices = array(0,1,2,3);

// shuffle the indices and use them as shuffling seed
shuffle($indices);

// then whenever you want to produce exactly same shuffle use the pre-computed shuffled indices
function shuffle_precomputed($a, $shuffled_indices)
{
     $b = $a; // copy array
     foreach ($shuffled_indices as $i1=>$i2) $a[$i2] = $b[$i1];
     return $a;
}

используйте следующее:

$shuffled_array = shuffle_precomputed($an_array, $indices);

Вы можете даже использовать факторную систему чисел, чтобы преобразовать массив $shuffled_indices в/из уникального целочисленного числа, которое может использоваться как уникальное семя, а затем просто вычислить перетасовку из факториала, который будет использоваться в функции shuffle_precomputed.

Для дополнительных shuffle вариантов для PHP вы можете захотеть увидеть: