Взвешенный случайный выбор в PHP - PullRequest
0 голосов
/ 21 сентября 2019

Мне нужна помощь, чтобы приблизить мои вероятности к результатам тестирования с низким процентом.То, что у меня, похоже, работает для процентов в 1% или выше, но мне нужно, чтобы оно работало с очень низкими процентами, такими как 0,02% (до 4 десятичных знаков).Все, что ниже 1%, имеет тенденцию к вероятности около 1% после запуска тестов при запуске 1000-100000 тестов сразу после того, как результаты будут похожими.

Пример результатов

ID  Odds    Test Total  Test Odds
1   60.0000 301773  60.3546%
2   30.0000 148360  29.672%
3   9.9800  44897   8.9794%
4   0.0200  4970    0.994%

Функция

// $values = [1,2,3,4]
// $weights = [60.0000,30.0000,9.9800,.0200]
private function getRandom($values, $weights)
{
    $count = count($values); 
    $i = 0; 
    $n = 0; 
    $num = mt_rand(0, array_sum($weights)); 
    while($i < $count)
    {
        $n += $weights[$i]; 
        if($n >= $num)
            break; 
        $i++; 
    } 
    return $values[$i]; 
}

1 Ответ

1 голос
/ 21 сентября 2019

mt_rand возвращает целое число, поэтому сравнение его с 0,02 фактически равнозначно сравнению с 1. Следовательно, вы всегда получаете около 1% для весов, которые меньше 1%.Попробуйте вместо этого вычислить $num:

$num = mt_rand(0, array_sum($weights) * 100) / 100; 

Демонстрация на 3v4l.org

...