В последнем своем проекте мне было необходимо написать простой и быстрый, но управляемый генератор случайных чисел. Писал сразу после прохождения codecademy и почти уверен, что он кривой. Заменить кучу if на case не получилось. Его вообще можно заменить чем-то более адекватным?
Итак. Есть range от $min до $max. Необходимо создать генератор, выдающий числа в определенных границах в соответствии с настройками пользователя. Если $min == 1, a $max == 80, функция должна иметь возможность генерировать, N чисел от 1 до 10, M от 10 до 20 и так далее.
<?php $counts = array ( //например, до 10 - 65 раз из 100 '10' => array ('count' => 0, 'ratio' => 0.65), //до 20 - 5 из 100 '20' => array ('count' => 0, 'ratio' => 0.05), '30' => array ('count' => 0, 'ratio' => 0.05), //count - счетчик срабатываний '40' => array ('count' => 0, 'ratio' => 0.05), '50' => array ('count' => 0, 'ratio' => 0.05), '60' => array ('count' => 0, 'ratio' => 0.05), '70' => array ('count' => 0, 'ratio' => 0.05), '80' => array ('count' => 0, 'ratio' => 0.05), //total - общий счетчик 'total' => 1 ); //функция проверки на превышение частоты появления function check($count_to_check) { global $counts; if ($counts[$count_to_check]['count']/$counts['total'] < $counts[$count_to_check]['ratio']) return True; else return False; } //функция корректировки счетчиков function plus($count_to_plus) { global $counts; $counts[$count_to_plus]['count']++; $counts['total']++; } //сам генератор function gen_price($min,$max) { global $counts; $gen_p = rand($min,$max); if ($gen_p<10) { if (check('10')) { plus('10'); return $gen_p; }} else if ($gen_p<20) { if (check('20')) { plus('20'); return $gen_p; }} else if ($gen_p<30) { if (check('30')) { plus('30'); return $gen_p; }} else if ($gen_p<40) { if (check('40')) { plus('40'); return $gen_p; }} else if ($gen_p<50) { if (check('50')) { plus('50'); return $gen_p; }} else if ($gen_p<60) { if (check('60')) { plus('60'); return $gen_p; }} else if ($gen_p<70) { if (check('70')) { plus('70'); return $gen_p; }} else if ($gen_p<=80) { if (check('80')) { plus('80'); return $gen_p; }} } //проверяем $min = 1; $max = 80; for ($tries = 0; $tries < 100; $tries++) { $price_gen = 0; //без while иногда пропуски были while (!$price_gen) $price_gen = gen_price($min,$max); echo $price_gen . " "; } ?>
Если вероятности в сумме составляют 1, то генератор работает крайне предсказуемо и выдает числа, как только это можно сделать. Для меньшей предсказуемости можно назначить вероятности так, чтобы в сумме было больше еденицы, правила все-равно будут соблюдены.
ссылка на оригинал статьи http://habrahabr.ru/post/194598/
Добавить комментарий