用种子随机化PHP数组?

2022-08-30 13:20:47

我正在寻找一个函数,我可以在PHP中传递数组和种子,并得到一个“随机”数组。如果我再次传递相同的数组和相同的种子,我将得到相同的输出。

我试过这个代码

//sample array
$test = array(1,2,3,4,5,6);
//show the array
print_r($test);

//seed the random number generator
mt_srand('123');
//generate a random number based on that
echo mt_rand();
echo "\n";

//shuffle the array
shuffle($test);

//show the results
print_r($test);

但它似乎没有奏效。对最好的方法有什么想法吗?

这个问题围绕着这个问题跳舞,但它很古老,没有人提供关于如何做到这一点的实际答案:我可以通过提供种子来随机化数组并获得相同的顺序吗? - “是” - 但如何?

更新

到目前为止,答案适用于 PHP 5.1 和 5.3,但不适用于 5.2。碰巧的是,我想运行这个的机器正在使用5.2。

任何人都可以在不使用mt_rand的情况下举个例子吗?它在 php 5.2 中被“破坏”,因为它不会基于相同的种子给出相同的随机数序列。请参阅 php mt_rand页面bug 跟踪器来了解此问题。


答案 1

很抱歉,但根据文档,随机播放功能是自动播种的。

通常,你不应该试图提出自己的算法来随机化事物,因为它们很可能是有偏见的。众所周知,Fisher-Yates算法既高效又无偏见:

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

示例 (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
)

答案 2

您可以使用array_multisort按第二个mt_rand值数组对数组值进行排序:

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

下面是一个长度与 相同长度的值的数组。 对 的值进行排序,并根据 的值的顺序对 的元素进行排序。$ordermt_rand$arrarray_multisort$order$arr$order