PHP的百分比概率

3

这实际上更多是一个方法问题,但我会用PHP来呈现。

假设我们有一个四个百分比的列表,表示在迭代过程中发生某种事件的概率。

array=('walk the dog'=>.25,'read the paper'=>.25,'drink coffee'=>.0,'listen to music'=>.50)

(键只是测试 - 在实践中,这将用于应用不同方法于一个对象的策略模式,使用call_user_func()

在循环中,选择其中一种事件的最佳方法是通过随机调整选择考虑它们各自的权重(例如,对于这个特定的配置,会听很多音乐而不喝很多咖啡)

目前我有类似这样的代码:

for($i=1;$i<=3;$i++){
  $rand = 1/rand(1,10);
  //choose from the list
}

但这需要将百分比映射到值范围(50-100%变成听音乐,0-25%遛狗,25-50阅读报纸),因为该迭代的“值”被计算为0到1之间的浮点数。 这种改变了记录百分比的方式。
是否有任何方法可以保持值的身份,作为应该选择的真实概率,而不是范围? 这肯定会使代码更可配置,因为我必须让这些值可调整。 如果我表述得太模糊,请告诉我。

你的列表中有4个项目,而不是三个。 - MrGlass
4个回答

5
我会这样做:

我会像这样做:

$arr = array (
    'walk the dog'    =>  array('min' =>  0, 'max' =>  25),
    'read the paper'  =>  array('min' => 25, 'max' =>  50),
    'drink coffee'    =>  array('min' =>  0, 'max' =>   0),
    'listen to music' =>  array('min' => 50, 'max' => 100),
);

$rnd = rand(1,100);
foreach($arr as $k =>$v) {
    if ($rnd > $v['min'] && $rnd <= $v['max']) {
        echo $k,"\n";
    }
}

3
您是否考虑过使用百分比值作为累积数?
$array = array('walk the dog'=>.25,'read the paper'=>.25,'drink coffee'=>.0,'listen to music'=>.50);

$rand = rand();
$cur = 0;
foreach ($key=>$val in $array) {
  $cur += $val;
  if ($rand <= $cur)
    return $key;
}

这假设数组中的值总和为1。顺序也不重要...

1
$arr = array('walk the dog'=>25,'read the paper'=>25,'listen to music'=>50);
$rand = rand(1,100);
$sum = 0;
$action = '';

foreach ($arr as $k => $v) {
    $sum .= $k;
    if ($sum <= $k)
        $action = $v;
}

移除那些键值为零的项,并将键值乘以100,使其更易读。


这大致是我想要应用的,但问题在于从列表中选择正确的一个。由于对于任何一个循环通行证,存在四个潜在事件(如果我们不考虑咖啡因,因为它在此配置中设置为零),所以这是个问题。 - DeaconDesperado
这些键的总和是否始终为100(或1)? - OptimusCrime
是的,添加到列表中的新项目会降低其他项目出现的概率。它们的总和始终等于1(或在该比例上计算时等于100)。 - DeaconDesperado
我认为您可能在交换$k和$v时打错了一个字母,但是这确实有效。 - DeaconDesperado
4
如果随机数并未被使用,那么生成它的意义何在? - dukevin

0

你可以重构数组,使得事件按照概率递减的方式存储(以提高性能),而与事件对应的值是该特定事件的概率加上前一个元素的值(这意味着最后一个元素的值始终为1)。

然后,你只需要遍历数组并返回其值大于 $rand 的事件即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接