我有以下数组
$arr = array(
"person1" => 10,
"person2" => 10,
"person3" => 20,
"person4" => 25,
"person5" => 35,
);
我想编写一个函数,它将$arr
作为参数,并根据存储在每个元素中的值返回数组的3个元素。
例如,如果返回的子集产生
$newArr = array(
"person5" => 35,
"person1" => 10,
"person4" => 25,
);
根据$newArr
中存储的值除以存储在其余元素中的值之和,person5将成为存储在$arr['person5']
中的第一个元素的概率为35%。
$arr['person5']/($arr['person5'] + $arr['person4'] + $arr['person3'] + $arr['person2'] + $arr['person1'])
根据$newArr
中存储的值除以存储在其余元素中的值之和,person1将成为$arr['person1']
中存储的第二个元素的概率约为15%。
$arr['person1']/($arr['person4'] + $arr['person3'] + $arr['person2'] + $arr['person1'])
根据$newArr
中存储的值除以存储在其余元素中的值之和,person4将成为$arr['person4']
中存储的第二个元素的概率约为45%。
$arr['person4']/($arr['person4'] + $arr['person3'] + $arr['person2'])
我怎么能写一个这样做的函数?
答案 0 :(得分:1)
您正在寻找轮盘赌选择算法,请参阅:http://en.wikipedia.org/wiki/Fitness_proportionate_selection
$count = 3;
$arr = array(
"person1" => 10,
"person2" => 10,
"person3" => 20,
"person4" => 25,
"person5" => 35,
);
$result = array();
// sort from low to high
asort($arr);
// loop 3 times (based on count)
while ($count > 0){
// get the sum of all persons
$sum = 0;
foreach ($arr as $rank){
$sum += $rank;
}
// get a random value between 0 and sum
$delta = rand(0, $sum);
$current = 0;
// keep looping over each item, increasing rank untill $sum has surpassed delta
// see each item as as person containing a portion of the slice. The bigger the value, the greater the change of being selected
$current = 0;
foreach ($arr as $name => $rank){
$current += $rank;
if ($delta <= $current){
$result[$name] = $rank;
break;
}
}
unset($arr[$name]);
$count--;
}