使用嵌套数组中的权重对一个或多个数组进行混洗的好算法是什么?
示例:
$array = array(
array("name"=>"John", "rank"=>3),
array("name"=>"Bob", "rank"=>1),
array("name"=>"Todd", "rank"=>8),
array("name"=>"Todd", "rank"=>14),
array("name"=>"Todd", "rank"=>4)
);
我希望数组随机改组,但我希望rank
值为权重。因此,排名较低的人更有可能成为榜单的首位。
我已经尝试了一些事情,比如遍历数组并拉出使用mt_rand(mt_rand(0,$value),$value)
选择的数组但我不认为我在正确的轨道上......
答案 0 :(得分:4)
我能够像这样解决这个问题:
function compare($a, $b)
{
$share_of_a = $a['rank'];
$share_of_b = $b['rank'];
return mt_rand(0, ($share_of_a+$share_of_b)) > $share_of_a ? 1 : -1;
}
usort($array, "compare"); // Sort the array using the above compare function when comparing
$array = array_reverse($array);
答案 1 :(得分:2)
您可以尝试这样的事情:
function weightedshuffle ($a, $b) {
return rand(0, $a['rank'] + $b['rank']) <= $a['rank'];
}
usort($data, 'weightedshuffle');
答案 2 :(得分:0)
由于此问题首先出现在Google上,同时搜索 php数组加权随机播放,并且可接受的答案无法解决-这是基于我发现的某些算法的解决方案。
相当快(对于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;
}