doulubashang6936 2012-04-01 08:08
浏览 24
已采纳

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

I have the following array

$arr = array(
    "person1" => 10,
    "person2" => 10,
    "person3" => 20,
    "person4" => 25,
    "person5" => 35,                    
);

I would like to write a function that takes $arr as an argument and returns 3 elements of the array based on the values stored in each element.

For example if the returned subset yields

$newArr = array(
    "person5" => 35,  
    "person1" => 10,
    "person4" => 25,                  
);

There was a 35% chance that person5 would be the first element stored in $newArr based on the value stored in $arr['person5'] divided by the sum of values stored in the remaining elements. $arr['person5']/($arr['person5'] + $arr['person4'] + $arr['person3'] + $arr['person2'] + $arr['person1'])

There was a ~15% chance that person1 would be the second element stored in $newArr based on the value stored in $arr['person1'] divided by the sum of values stored in the remaining elements. $arr['person1']/($arr['person4'] + $arr['person3'] + $arr['person2'] + $arr['person1'])

There was a ~45% chance that person4 would be the second element stored in $newArr based on the value stored in $arr['person4'] divided by the sum of values stored in the remaining elements. $arr['person4']/($arr['person4'] + $arr['person3'] + $arr['person2'])

How could I write a function that does this?

  • 写回答

1条回答 默认 最新

  • douwei3172 2012-04-01 08:12
    关注

    You're looking for a roulette wheel selection algorithm, see: 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--;
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog