PHP 的 shuffle 函数有多随机?

发布于 2024-11-01 21:31:47 字数 106 浏览 1 评论 0原文

有谁知道PHP的shuffle()函数的随机性是什么?它取决于操作系统吗? 它使用 PHP 自己的播种器吗?

是否可以使用 mt_rand() 作为生成器?

Does anyone know what's the randomness of PHP's shuffle() function? Does it depend on the operating system?
Does it use PHP's own seeder?

Is it possible to use mt_rand() as generator?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

假面具 2024-11-08 21:31:47

shuffle() 函数与 rand() 基于相同的生成器,它是基于 线性同余算法。这是一个快速生成器,但或多或​​少具有随机性。从 PHP 4.2.0 开始,随机生成器会自动播种,但如果需要,您可以使用 srand() 函数来播种。

mtrand() 基于Mersenne Twister 算法,它是以下之一可用的最佳伪随机算法。要使用该生成器对数组进行洗牌,您需要编写自己的洗牌函数。例如,您可以查看 Fisher-Yates 算法。编写自己的 shuffle 函数将产生更好的随机性,但会比内置 shuffle 函数慢。

shuffle() function is based on the same generator as rand(), which is the system generator based on linear congruential algorithm. This is a fast generator, but with more or less randomness. Since PHP 4.2.0, the random generator is seeded automatically, but you can use srand() function to seed it if you want.

mtrand() is based on Mersenne Twister algorithm, which is one of the best pseudo-random algorithms available. To shuffle an array using that generator, you'd need to write you own shuffle function. You can look for example at Fisher-Yates algorithm. Writing you own shuffle function will yield to better randomness, but will be slower than the builtin shuffle function.

影子是时光的心 2024-11-08 21:31:47

PHP 7.1 更新

由于 PHP 7.1 实现了 rng_fixes rfc,因此 shuffle 的实现 现在使用 Mersenne Twister PRNG(即它使用 mt_rand 并受到调用 mt_srand 的影响)。

旧系统 PRNG (rand) 不再可用;函数 randsrand 实际上是它们的 mt_ 等效函数的别名。

Update for PHP 7.1

Since the rng_fixes rfc was implemented for PHP 7.1, the implementation of shuffle now utilizes the Mersenne Twister PRNG (i.e. it uses mt_rand and is affected by calling mt_srand).

The legacy system PRNG (rand) is no longer available; the functions rand and srand are in fact aliased to their mt_ equivalents.

小巷里的女流氓 2024-11-08 21:31:47

根据 Mirouf 的回答(非常感谢您的贡献)...我对其进行了一些改进,以消除冗余的数组计数。为了我自己的理解,我还对变量进行了稍微不同的命名。

如果你想像 shuffle() 一样使用它,你可以修改要通过引用传递的参数,即 &$array,然后确保将 return 更改为简单的:“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;
}

Based on Mirouf's answer (thank you so much for your contribution)... I refined it a little bit to take out redundant array counting. I also named the variables a little differently for my own understanding.

If you want to use this exactly like shuffle(), you could modify the parameter to be passed by reference, i.e. &$array, then make sure you change the return to simply: "return;" and assign the resulting random array back to $array as such:
$array = $randArr; (Before the return).

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;
}
醉酒的小男人 2024-11-08 21:31:47

就像rand()一样,它是随机的;

作为 PHP 风格,你不需要播种

It's random just like rand();

And as PHP style you don't need to seed

挽袖吟 2024-11-08 21:31:47
mt_rand()

生成一个随机数。

shuffle()

随机化数组。它还在数组中生成新的键,而不仅仅是重新排列旧的键。

如果您想在 PHP 中播种,您可以使用 mt_strand()

但是,由于 PHP 4.2.0,当您调用 mt_rand 时,PHP 中会自动完成播种。

mt_rand()

Generates a random number.

shuffle()

Randomizes an array. It also generates new keys in the array rather than just rearranging the old ones.

If you want to seed in PHP you would have used mt_strand().

However, since PHP 4.2.0 seeding is done automatically in PHP when you call mt_rand.

深居我梦 2024-11-08 21:31:47

适用于关联数组和数值数组:

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);

在此处输入图像描述

Works with associative and numeric arrays:

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

天涯沦落人 2024-11-08 21:31:47

我创建了一个对数组进行随机排序的函数。

/**
 * 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 时,它​​总是以相同的顺序返回随机数组。如果这可以帮助某人,我会很高兴!

I've created a function who sort my array randomly.

/**
 * 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;
}

It's not the best way to do that but when I've used the function shuffle, it was always returning a random array in the same order. If this could help someone, I will be happy !

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文