Основной вопрос состоит из двух частей. Один о том, как перемешать. Другой вопрос о том, как добавить к нему случайность.
Простое решение
Это, наверное, самый простой ответ на главный вопрос. Это достаточно для большинства случаев в сценариях PHP. Но не все (см. Ниже).
function /*array*/ seedShuffle(/*one dimentional array*/ $array, /*integer*/ $seed) {
$tmp = array();
for ($rest = $count = count($array);$count>0;$count--) {
$seed %= $count;
$t = array_splice($array,$seed,1);
$tmp[] = $t[0];
$seed = $seed*$seed + $rest;
}
return $tmp;
}
Приведенный выше метод подойдет, даже если он не производит настоящие случайные тасовки для всех возможных комбинаций начальных чисел. Однако, если вы действительно хотите, чтобы он был сбалансированным и все такое, я думаю, PHP не будет вашим выбором.
Более полезное решение для продвинутых программистов
Как заявил Андре Ласло, рандомизация - сложное дело. Обычно лучше всего позволить выделенному объекту обрабатывать его. Я хочу сказать, что вам не нужно беспокоиться о случайности, когда вы пишете функцию перемешивания. В зависимости от того, какой степени случайности вы хотели бы использовать в случайном порядке, у вас может быть несколько объектов PseudoRandom на выбор. Таким образом, приведенное выше может выглядеть так:
abstract class PseudoRandom {
protected abstract function /*integer*/ nextInt();
public function /*integer*/ randInt(/*integer*/ $limit) {
return $this->nextInt()%$limit;
}
}
function /*array*/ seedShuffle($array, /*PseudoRandom Object*/ $rnd) {
$tmp = array();
$count = count($array);
while($count>0) {
$t = array_splice($array,$rnd->randInt($count--),1);
$tmp[] = $t[0];
}
return $tmp;
}
Теперь, за это решение я бы проголосовал. Он отделяет случайные коды от кодов рандомизации. В зависимости от того, какой случайный тип вам нужен, вы можете создать подкласс PseudoRandom, добавить необходимые методы и предпочитаемые формулы.
И, поскольку одна и та же функция случайного выбора может использоваться со многими случайными алгоритмами, один случайный алгоритм может использоваться в разных местах.