процент вероятности rand(+)

berkut

Новичок
процент вероятности rand(+)

Нужно вывести случайный эл-т массива, но с определённой долей вероятности.:eek:
Первое что пришло в голову, находится ниже, но алгоритм очень не оптимальный.
PHP:
$arr = array('red', 'green', 'blue'); //массив эл-ов
$per = array(1, 70, 29);//процент вероятности для каждого эл-а масс. $arr
$s = $q = sizeof($per);
for ($i=0; $i<$s; $i++) {
    $arrg = array_merge($arrg, array_fill($q, $per[$i], $arr[$i]));
    $q+= $per[$i];
}
//shuffle($arrg);
$rand = rand(0, sizeof($arrg) - 1);
$random_elem = $arrg[$rand];
 

neko

tеam neko
знаешь как можно сделать!
задать вероятности промежутками, и после генерации числа найти в какой оно входит
вот так

а что делает твой код я, честно говоря, не понял :)
 

TuBu

Guest
То что и сказал neko

Код:
$arr = array('red', 'green', 'blue'); //массив эл-ов
$per = array(1, 70, 29);//процент вероятности для каждого эл-а масс. $arr
$intervals = array();
$i = 0;
foreach ($per as $count){
    $intervals[] = array($i, $i+$count);
    $ i+= $count;
}
$rand = rand(0, $i-1);
$found = false;
foreach ($intervals as $i => $interval){
    if ($rand >= $interval[0] && $rand < $interval[1]){
        $found = $i;
        break;
   }
}
$random_elem = $arr[$found];
Код не тестировался, но идея должна быть ясна
 

Black.ice.wizard

Новичок
Код такой программы:

PHP:
<?php
$arr = array('red', 'green', 'blue');
$per = array(1, 70, 29);

print arrayRandByFactor($arr, $per);

/**
 * @param array $variants
 * @param array $factors
 * @return mixed
 * @throws Exception
 */
function arrayRandByFactor(array $variants, array $factors)
{
    $randNumber = rand(1, array_sum($factors));
    $currentLimit = 0;
    $previousLimit = 0;
    foreach ($factors as $key => $factor) {
        $currentLimit += $factor;
        if ($randNumber > $previousLimit && $randNumber <= $currentLimit) {
            if(!isset($variants[$key])) {
                throw new Exception('Keys of variants and factors are not the same');
            }
            return $variants[$key];
        }
        $previousLimit += $factor;
    }
}
Думаю дополнительные комментарии не нужны.

Тестирующий код:

PHP:
$statistic = ['red' => 0, 'green' => 0, 'blue' => 0];
for($i = 0; $i < 1000000; $i++) {
    $statistic[arrayRandByFactor($arr, $per)] ++;
}
print "red   => ".($statistic['red']   / 1000000)."\n";
print "green => ".($statistic['green'] / 1000000)."\n";
print "blue  => ".($statistic['blue']  / 1000000)."\n";
Вывод на экран:
Код:
red   => 0.010066
green => 0.700115
blue  => 0.289819
PS: Я в курсе, что этому посту почти 15 лет.
 

Black.ice.wizard

Новичок
@Black.ice.wizard, ты спецом 14 лет терпел или как?
Я к теме особого отношения не имею. Просто попал сюда по поисковому запросу из гугла. Если я попал, значит и другие попадут. Возможно кому-то полезно будет это решение. А возможно и нет. Просто что-то зацепило и написал ответ
 
Сверху