Процентный шанс php
Это действительно больше вопрос подхода, но я представляю это в php.
Предположим, у нас был список из четырех процентов, что на итерации будет происходить событие Give.
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 ответа
Я бы сделал что-то вроде:
$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";
}
}
Рассматривали ли вы использование процентных значений в качестве кумулятивного числа?
$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. Порядок также не имеет значения...
$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, чтобы сделать его более читабельным.
Вы можете реструктурировать массив таким образом, чтобы события сохранялись с уменьшающейся вероятностью (для производительности), а значение, соответствующее событию, является вероятностью этого конкретного события плюс значение предыдущего элемента (что означает, что последний элемент будет всегда иметь значение 1).
Затем вы просто перебираете массив и возвращаете событие, для которого его значение больше $rand.