PHP的array_rand()不是真的随机吗?

Jas*_*ard 5 php random

我正在编写一些代码以随机分配演示文稿列表。相同的演示文稿无法连续播放。

该$d数组将是演示文稿ID的列表以及演示文稿应在循环中播放的次数。

下面的代码可以正常工作,但是结果并不是真正随机的。当我一次又一次地看到相同的模式时,我正在调试。查看以下输出:

ighbajafpbailgjacbiaeldiqjaphafgdjcbapsaebjfdkcknijhbdgecaimabodalkfbgbhacbhnrjeofbdjbfhegmbpdkialmbocnliaebfaimcabchgoecbcdimgepnfjgfbfbohdahdkjgneaebha

ighbajafpbailgjacbiaeldiqjaphafgdjcbapsaebjfdkcknijhbdgecaimabodalkfbgbhacbhnrjeofbdjbfhegmbpdkialmbocnliaebfaimcabchgoecbcdimgepnfjgfbfbohdahdkjgneaebha
Run Code Online (Sandbox Code Playgroud)

这两个分开了4次。它们是相同的。4之后运行,相同的字符串。多运行4次,相同的字符串。实际上,在运行此命令时,我似乎依次得到了相同的4个字符串。

我的代码在下面,有人可以指出我可能已经嘲笑的内容吗?如果我什么都没做,为什么“ rand”不是随机的?我该如何解决?

$d = array(
    array('a', '20'), array('b', '20'), array('c', '10'), array('d', '10'), array('e', '10'), array('f', '10'), array('g', '10'), array('h', '10'), array('i', '10'), array('j', '10'), array('k', '5'), array('l', '5'), array('m', '5'), array('n', '5'), array('o', '5'), array('p', '5'), array('q', '1'), array('r', '1'), array('s', '1'));
$out = randomizeArray($d);
//var_dump($out);

function randomizeArray ($data) {
    // Step 1: Make an array of the id's with repeats for count.
    $rarray = array();
    foreach ($data as $i => $v) {
        while ($data[$i][1] > 0) {
            array_push($rarray, $data[$i][0]);
            $data[$i][1]--;
        }
    }
    // Step 2: Randomize.
    $stat = 1;
    while ($stat == '1') {
        //echo "<br><br>Randomizing Array: <br>";
        $stat = rarr($rarray);
    }
    return $stat;
}
function rarr ($a) {
    $r = array();
    $last = "";
    while ($a) {
        $rand = array_rand($a, 1);
        // Does this value match the last one we got?
        if ($a[$rand] != $last) {
            // Nope. Transfer to our $r array.
            echo $a[$rand];
            array_push($r, $a[$rand]);
            $last = $a[$rand];
            unset($a[$rand]);
        } else {
            // We have a match between our "last" presentation and the one we just selected.
            // We need to scan our array and verify that we still have different values.
            $check = $a[$rand];
            foreach ($a as $c) {
                if ($check != $c) {
                    // We have at least 2 different values in our array still.
                    // Rerun the while loop
                    continue 2;
                }
            }
            // All of the values left in our array are repeats.
            // That's no good, so return an error and rerun.
            return 1;
        }
    }
    // Everything is awesome. Return the randomized array.
    return $r;
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*łek 2

据我所知,解决方案是在第 2 步行之前添加:

shuffle($rarray);
Run Code Online (Sandbox Code Playgroud)

看来还是稍微解决了一点问题。重复精确 47 次。

如果您在 rarr 函数中的 while 之后添加它:

while ($a) {
    shuffle($a);
Run Code Online (Sandbox Code Playgroud)

if 将重复精确 52 次

看来这实际上是 array_rand 函数的问题。将 array_rand 更改为 mt_rand,如下代码所示:

<?php
$d = array(
    array('a', '20'), array('b', '20'), array('c', '10'), array('d', '10'), array('e', '10'), array('f', '10'), array('g', '10'), array('h', '10'), array('i', '10'), array('j', '10'), array('k', '5'), array('l', '5'), array('m', '5'), array('n', '5'), array('o', '5'), array('p', '5'), array('q', '1'), array('r', '1'), array('s', '1'));

    for ($i=0; $i<10000; ++$i) {
        //ho "x";
        $out = randomizeArray($d);
        echo implode('',$out)."<br />";   
    }    


//var_dump($out);

function randomizeArray ($data) {
    // Step 1: Make an array of the id's with repeats for count.
    $rarray = array();
    foreach ($data as $i => $v) {
        while ($data[$i][1] > 0) {
            array_push($rarray, $data[$i][0]);
            $data[$i][1]--;
        }
    }
    // Step 2: Randomize.
    $stat = 1;
    while ($stat == '1') {
        //echo "<br><br>Randomizing Array: <br>";
        $stat = rarr($rarray);
    }
    return $stat;
}
function rarr ($a) {
    $r = array();
    $last = "";
    while ($a) {
        $rand = mt_rand(0,count($a)-1);
        // Does this value match the last one we got?
        if ($a[$rand] != $last) {
            // Nope. Transfer to our $r array.
           // echo $a[$rand];
            array_push($r, $a[$rand]);
            $last = $a[$rand];
            unset($a[$rand]);
            $a = array_values($a);
        } else {
            // We have a match between our "last" presentation and the one we just selected.
            // We need to scan our array and verify that we still have different values.
            $check = $a[$rand];
            foreach ($a as $c) {
                if ($check != $c) {
                    // We have at least 2 different values in our array still.
                    // Rerun the while loop
                    continue 2;
                }
            }
            // All of the values left in our array are repeats.
            // That's no good, so return an error and rerun.
            return 1;
        }
    }
    // Everything is awesome. Return the randomized array.
    return $r;
}
Run Code Online (Sandbox Code Playgroud)

使得琴弦非常独特。

我真的很好奇是否有人可以解释这是一个 PHP 错误或“功能”