PHP: распределить веса так, чтобы в сумме было 100%
Задача 1 проста - распределить заданное количество процентных весов поровну, точней, "как можно ровнее" и в целых числах.
В сумме должно получиться ровно 100%.
Например, если количество весов $n
равно трём, должно выйти 34% и дважды по 33%.
Вторая чем-то похожая задача - распределение случайного числа по заданным весам. Например, имеется массив $w
с весами [60,30,10]
или [60,30,10,5]
- сумма не обязательно должна быть равна 100 или какой-то другой величине.
Задача состоит в том, чтобы выдать индекс в массиве $w
с вероятностью, пропорциональной весу в соответствующей позиции.
Ниже приводятся функции на PHP и их тесты.
<?php function ps ($n) { $n = abs(intval($n)); if ($n<1 or $n>100) return Array(); $arr = Array(); $div = floor(100/$n); $mod = 100%$n; for ($i=0; $i<$n; $i++) $arr[] = $div; for ($i=0; $i<$mod; $i++) $arr[$i]++; return $arr; } echo 'ps(1)='; print_r (ps(1)); echo '<br>ps(6)='; print_r (ps(6)); echo '<br>ps(100)='; print_r (ps(100)); ?>
<?php function w_index ($w) { $s = 0; $r = mt_rand() / mt_getrandmax() * array_sum($w); $n = count($w); for ($j=0; $j<$n; $j++) { $s += $w[$j]; if ($s >= $r) return $j; } return $n-1; } $w = Array (60,30,10,5); //Веса $s = Array (0,0,0,0); //Подсчёт количества полученных весов for ($j=0; $j<1000; $j++) //Делаем 1000 попыток $s[w_index($w)]++; //Выводим эпмирические веса, они будут близки к теоретическим: $sum = array_sum($s); for ($j=0; $j<4; $j++) echo round($s[$j]/$sum*100.,2).'%<br>'; ?>
22.06.2017, 20:38 [3354 просмотра]