这实际上是一个方法问题,但我在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之间。这种方式会改变记录百分比的方式。
是否存在任何一种方法可以保留值的身份,因为它们应该被选择而不是范围?它肯定会使代码更具可配置性,因为我必须使这些值可调。如果我太模糊,请告诉我。
答案 0 :(得分:4)
我做的事情如下:
$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";
}
}
答案 1 :(得分: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.排序无关......
答案 2 :(得分: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以使其更具可读性。
答案 3 :(得分:0)
您可以以这样的方式重构数组:事件以降低的概率存储(对于性能),对应于事件的值是此特定事件的概率加上前一个元素的值(这意味着最后一个元素的值总是为1。)。
然后你只需迭代数组并返回其值大于$ rand的事件。