Это действительно вопрос подхода, но я представляю его в 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. Этот вид изменяет способ учета процентов.
Существует ли какой-либо подход, который бы сохранил идентичность значений как реальную вероятность их выбора, а не диапазонов? Это определенно сделает код более настраиваемым, поскольку я должен настроить эти значения. Пожалуйста, дайте мне знать, если я слишком расплывчата.
Я бы сделал что-то вроде:
$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.