谁知道PHP的shuffle()
函数有多随机?它是否取决于操作系统?它是否使用PHP自己的种子生成器?
可以将mt_rand()
用作生成器吗?
shuffle()
函数基于与 rand()
相同的生成器,即基于线性同余算法的系统生成器。这是一个快速的生成器,但其随机性更多或更少。自PHP 4.2.0起,随机生成器会自动初始化种子,但如果您需要,可以使用 srand()
函数进行手动初始化。
mtrand()
基于Mersenne Twister算法,是可用的最佳伪随机算法之一。要使用该生成器对数组进行洗牌,您需要编写自己的shuffle函数。你可以参考Fisher-Yates算法的示例。编写自己的shuffle函数将产生更好的随机性,但比内置的shuffle函数慢。
自从针对PHP 7.1实施了rng_fixes rfc,shuffle
的实现现在使用梅森旋转算法伪随机数生成器(即它使用mt_rand
并受到调用mt_srand
的影响)。
传统系统的伪随机数生成器(rand
)不再可用;函数rand
和srand
实际上被别名为它们的mt_
等效函数。
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的风格,你不需要进行种子设置。
mt_rand()
生成一个随机数。
shuffle()
随机化一个数组。它会生成新的键而不仅仅是重新排列旧的键。
如果你想在PHP中播种,你可以使用mt_strand()
。
然而,自从PHP 4.2.0以后,在调用mt_rand时,PHP会自动进行播种。
可以处理关联数组和数字数组:
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);
/**
* 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函数时,它总是以相同的顺序返回随机数组。 如果这能帮助到某人,我会很高兴!