Насколько случайна функция PHP shuffle?

кто-нибудь знает, что такое случайность PHP ? Зависит ли это от операционной системы? Использует ли он собственный сеялку PHP?

можно использовать mt_rand() в качестве генератора?

7 ответов


shuffle() функция основана на том же генераторе, что и rand(), который является генератором системы на основе линейный конгруэнтный алгоритм. Это быстрый генератор, но с большей или меньшей случайностью. Начиная с PHP 4.2.0, генератор случайных чисел высевается автоматически, но вы можете использовать srand() функция для того чтобы засеять его если вы хотите.

mtrand() на основе алгоритм Мерсенн Твистер, который является одним из лучших псевдо-случайные алгоритмы. Перетасовать массив используя этот генератор, вам нужно будет написать собственную функцию shuffle. Вы можете посмотреть например на алгоритм Фишера-Йейтса. Написание собственной функции shuffle приведет к лучшей случайности, но будет медленнее, чем встроенная функция shuffle.


исходя из ответа Mirouf по (огромное спасибо за Ваш вклад)... Я немного доработал его, чтобы убрать избыточный подсчет массивов. Я назвал переменные немного по-другому для моего собственного понимания.

Если вы хотите использовать это точно так же, как shuffle (), вы можете изменить параметр, который будет передан по ссылке, т. е. & $array, затем убедитесь, что вы измените возврат на просто: "return;" и назначите результирующий случайный массив обратно $ array как таковой: $ array = $randArr; (До возвращения.)

function mt_shuffle($array) {
    $randArr = [];
    $arrLength = count($array);

    // while my array is not empty I select a random position
    while (count($array)) {
        //mt_rand returns a random number between two values
        $randPos = mt_rand(0, --$arrLength);
        $randArr[] = $array[$randPos];

        /* If number of remaining elements in the array is the same as the
         * random position, take out the item in that position,
         * else use the negative offset.
         * This will prevent array_splice removing the last item.
         */
        array_splice($array, $randPos, ($randPos == $arrLength ? 1 : $randPos - $arrLength));
    }

    return $randArr;
}

это случайно так же, как rand();

и как стиль PHP вам не нужно сеять


обновление для PHP 7.1

С rng_fixes rfc был реализован для PHP 7.1, реализация shuffle теперь использует Mersenne Twister PRNG (т. е. он использует mt_rand и зависит от вызова mt_srand).

устаревшая система PRNG (rand) больше не доступен; функции rand и srand на самом деле псевдоним их mt_ эквиваленты.


mt_rand()

генерирует случайное число.

shuffle()

перемешивает массив. Она также генерирует новые ключи в массиве, а не просто переставлять старые.

Если вы хотите сеять в PHP, вы бы использовали mt_strand().

однако, поскольку PHP 4.2.0 заполнение выполняется автоматически в PHP при вызове mt_rand.


работает с ассоциативными и числовых массивов:

function mt_shuffle_array($array) {
    $shuffled_array = [];
    $arr_length = count($array);

    if($arr_length < 2) {
        return $array;
    }

    while($arr_length) {
        --$arr_length;
        $rand_key = array_keys($array)[mt_rand(0, $arr_length)];

        $shuffled_array[$rand_key] = $array[$rand_key];
        unset($array[$rand_key]);
    }

    return $shuffled_array;
}

$array = [-2, -1, 'a' => '1', 'b' => '2', 'c' => '3', 11, 'd' => '4', 22];
$shuffled_array = mt_shuffle_array($array);

enter image description here


Я создал функцию, которая сортирует мой массив случайным образом.

/**
 * Build a random array
 *
 * @param mixed $array
 *
 * @return array
 */
function random_array($array) {
    $random_array = array();
    // array start by index 0
    $countArray = count($array) - 1;

    // while my array is not empty I build a random value
    while (count($array) != 0) {
        //mt_rand return a random number between two value 
        $randomValue = mt_rand(0, $countArray);
        $random_array[] = $array[$randomValue];

        // If my count of my tab is 4 and mt_rand give me the last element, 
        // array_splice will not unset the last item
        if(($randomValue + 1) == count($array)) {
            array_splice($array, $randomValue, ($randomValue - $countArray + 1));
        } else {
            array_splice($array, $randomValue, ($randomValue - $countArray));
        }

        $countArray--;
    }

    return $random_array;
}

это не лучший способ сделать это, но когда я использовал функцию shuffle, он всегда возвращал случайный массив в том же порядке. Если это может помочь кому-то, я буду счастлив !