如何根据元素中存储的概率%编写一个返回元素子集的函数?

时间:2012-04-01 08:08:56

标签: php

我有以下数组

$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'])

我怎么能写一个这样做的函数?

1 个答案:

答案 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--;
}