Процентный шанс 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.

Другие вопросы по тегам