【问题标题】:php percentage chancephp 百分比机会
【发布时间】:2012-01-10 15:43:08
【问题描述】:

这实际上是一个方法问题,但我在 php 中呈现它。

假设我们有一个列表,其中包含一个给定事件将在迭代中发生的四个百分比。

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

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

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

目前我有类似的东西:

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

但这需要将百分比映射到值范围(50-100% 会听音乐,0-25% 会遛狗,25-50% 会看报纸),因为该迭代的“价值”计算为0 到 1 之间的浮点数。这种方式改变了需要记录百分比的方式。

是否有任何方法可以将值的同一性保留为应该选择它们的真实概率而不是范围?它肯定会使代码更可配置,因为我必须使这些值可调。如果我太含糊,请告诉我。

【问题讨论】:

  • 顺便说一句,您的列表中有 4 项,而不是 3 项。

标签: php probability strategy-pattern


【解决方案1】:

我会这样做:

$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";
    }
}

【讨论】:

    【解决方案2】:

    您是否考虑过使用百分比值作为累积数字?

    $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。排序也无关紧要...

    【讨论】:

      【解决方案3】:
      $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;
      }
      

      删除了键值为0的那些,并将键值乘以100使其更具可读性。

      【讨论】:

      • 这是我或多或少想要应用的,但问题是从列表中选择正确的一个。由于任何一个循环通过都有四个潜在事件(如果我们打折咖啡,则为 3 个,因为在此配置中它被设置为零)。
      • 这些键的总和是否总是100(或1)
      • 是的,添加到列表中的新列表会降低其他列表出现的可能性。加在一起它们将始终等于 1(如果按该比例计算,则为 100。)
      • 我认为你可能有一个拼写错误,将 $k 换成 $v,但是确实有效。
      • 如果连随机数都不用,生成随机数有什么意义?
      【解决方案4】:

      您可以重构数组,使事件以递减的概率存储(为了性能),并且对应于事件的值是该特定事件的概率加上前一个元素的值(这意味着最后一个元素的值始终为 1。)。

      然后您只需遍历数组并返回其值大于 $rand 的事件。

      【讨论】:

        猜你喜欢
        • 2015-03-05
        • 1970-01-01
        • 1970-01-01
        • 2021-01-19
        • 2022-01-20
        • 2016-10-17
        • 1970-01-01
        • 2012-09-25
        相关资源
        最近更新 更多