【问题标题】:Random Function With Probability [closed]具有概率的随机函数
【发布时间】:2014-05-19 10:53:19
【问题描述】:

我有一个包含以下数据的数组:

(
    [Blue] => 15.3
    [Red] => 64.7
    [Green] => 20.0
)

蓝色被选中的概率为15.3%,红色被选中的概率为64.7%,绿色为20%强>机会。

我需要创建一个函数来随机选择其中一种颜色,同时还要考虑概率。

【问题讨论】:

  • 提示:如果您生成一个介于 0 和 1000 之间的随机整数(可以使用常见的 rand() 函数和模运算符来完成),您可以简单地说一些值映射到蓝色,其他映射到红色等
  • 一般解决方案请查看stackoverflow.com/questions/13635448/…

标签: php arrays random


【解决方案1】:

我很确定这个函数应该可以为您解决问题,如果需要,您可以将其调整为小数点后的点:

编辑:进行了一些实际测试并稍微修改了代码(以及添加大量输出以供您查看发生了什么:

<?php 
function chance($input=array())
{
    echo 'The Max Value can be: '.(array_sum($input)*10).'<br>';
    $number=rand(0,array_sum($input)*10);
    echo 'Checking for: '.$number.'<br>';
    $starter=0;
    foreach($input as $key => $val)
    {
        $starter+=$val*10;
        echo 'Current value being tested against is: '.$starter.' which is '.$key.'<br>';
        if($number<=$starter)
        {
            $ret=$key;
            break;
        }

    }

    return $ret;
}

$array=array('Blue' => 15.3, 'Red' => 64.7, 'Green' => 20.0);

for($i=0;$i<10;$i++)
{
    echo chance($array).'<br><br>';
}
?>

示例输出:

The Max Value can be: 1000
Checking for: 355
Current value being tested against is: 153 which is Blue
Current value being tested against is: 800 which is Red
Red

The Max Value can be: 1000
Checking for: 63
Current value being tested against is: 153 which is Blue
Blue

The Max Value can be: 1000
Checking for: 692
Current value being tested against is: 153 which is Blue
Current value being tested against is: 800 which is Red
Red

The Max Value can be: 1000
Checking for: 803
Current value being tested against is: 153 which is Blue
Current value being tested against is: 800 which is Red
Current value being tested against is: 1000 which is Green
Green

The Max Value can be: 1000
Checking for: 360
Current value being tested against is: 153 which is Blue
Current value being tested against is: 800 which is Red
Red

The Max Value can be: 1000
Checking for: 174
Current value being tested against is: 153 which is Blue
Current value being tested against is: 800 which is Red
Red

The Max Value can be: 1000
Checking for: 117
Current value being tested against is: 153 which is Blue
Blue

The Max Value can be: 1000
Checking for: 769
Current value being tested against is: 153 which is Blue
Current value being tested against is: 800 which is Red
Red

The Max Value can be: 1000
Checking for: 462
Current value being tested against is: 153 which is Blue
Current value being tested against is: 800 which is Red
Red

The Max Value can be: 1000
Checking for: 418
Current value being tested against is: 153 which is Blue
Current value being tested against is: 800 which is Red
Red

【讨论】:

  • 数组不按值排序怎么办?
  • @AndreschSerj 没有区别,随机值在 0 和 sum 之间——一旦 $number 大于等于该值,就会返回 key。键中的值越大,随机数落入的概率越大?
  • 啊,我的错误。现在我看到了。不错!
  • 非常感谢这个详细的回答。这正是我想要的。
  • @mmmbaileys 不用担心,我喜欢潜伏并找到像这样解决的问题,然后尝试为它们找到一个优雅的解决方案。比遇到另一个问题更有趣的是有人在他们的代码中忘记了"...
【解决方案2】:

使用mt_rand,您可以选择最小值和最大值。 例如,您使用 0 到 100。

$randomValue = (mt_rand ( 0 , 1000 ) / 10)

然后,只需选择适合您的百分比的违规行为,如下所示:

if($randomValue <= 15.3) { $pick = 'Blue';}
elseif($randomValue <= 64.7) { $pick = 'Red';}
else { $pick = 'Green';}

使用您的数组,您可以在函数中轻松实现这一点。 只需按值对数组进行排序,然后适当处理。

function getRandomColor($colorsWithProbability) {
  sort($colorsWithProbability);
  $last = '';

  foreach($colorsWithProbability as $color => $probability) {
    $last = $color;
    if($randval <= $probability) {
      return $color;
    }
  }
  return $last;
}

【讨论】:

  • 他想要一个小数点后的概率。考虑做这样的事情:$randomValue = mt_rand(0,1000) / 10;
  • @ViktorSvensson OP 没有说明它应该是一位小数,OP 也没有说明性别;-p
  • 好吧,因为概率用小数表示(例如 15.3)。使用上面的代码,概率是 15.0 还是 15.1 无关紧要,被“选中”的概率仍然相同(小数部分无关紧要)。不过关于你的性别,我不知道OP是男性还是女性! :-)
  • She-male ;-D 感谢大家的贡献
  • @ViktorSvensson 你对那个小数问题是对的!我编辑了我的答案。现在我们也知道性别了。这一天被保存了:D
猜你喜欢
  • 2017-05-16
  • 2012-02-11
  • 1970-01-01
  • 2015-06-08
  • 1970-01-01
  • 2011-03-07
  • 2012-10-06
相关资源
最近更新 更多