БлогNot. PHP: распределить веса так, чтобы в сумме было 100%

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 [3301 просмотр]


теги: random php числа алгоритм

К этой статье пока нет комментариев, Ваш будет первым