由于这个问题首先在谷歌上搜索php array weighted shuffle并且接受的答案没有解决它 - 这是基于我找到的一些算法的解决方案。
相当快(对于 PHP),概率分布也经过测试并且正确
<?php
/**
* Input can be specified as basic array or array of arrays:
* - array = [key1 => weight1, key2 => weight2, ...]
* - array = [[..., weightKey => weight], [..., weightKey2 => weight2], ...]
*
* Usage:
*
* $arr = ['key1' => 1, 'key2' => 2, 'key3' => 3];
* weighted_shuffle($arr);
*
* On average key3 is gonna be the first 50% of the time
*
* @param array $array Array to shuffle
* @param string|null $weight_key Optional weight key if input is array of arrays
*/
function weighted_shuffle(array &$array, $weight_key = null)
{
if($weight_key === null) {
$arr = $array;
} else {
$arr = array_combine(array_keys($array), array_column($array, $weight_key));
}
$max = 1.0 / getrandmax();
array_walk($arr, function (&$v, $k) use($max) {
$v = pow(rand()*$max, 1.0/$v);
});
arsort($arr);
array_walk($arr, function (&$v, $k) use($array) {
$v = $array[$k];
});
$array = $arr;
}