Код управляемого псевдо-рандома от новичка (изобрел велосипед?)
Задача была такой.
Есть range от $min до $max. Необходимо создать генератор, выдающий числа в определенных границах в соответствии с настройками пользователя. Если $min == 1, a $max == 80, функция должна иметь возможность генерировать, N чисел от 1 до 10, M от 10 до 20 и так далее.
Старое решение было через Ж..пу.
Новый вариант алгоритма предложил Mike, вот решение на его основе:
<?php
//создаем сколько угодно диапазонов, со счетчиком, частотой появления и верхней границей в отношении к верхнему пределу общего рандома
$counts = array (
//например, до 9% от максимум 1 раз из 100
'0' => array ('count' => 0, 'ratio' => 0.01, 'amount' => 0.09),
//до 50% - 20 из 100
'1' => array ('count' => 0, 'ratio' => 0.20, 'amount' => 0.50),
'2' => array ('count' => 0, 'ratio' => 0.50, 'amount' => 0.75),
//count - счетчик срабатываний
'3' => array ('count' => 0, 'ratio' => 0.29, 'amount' => 1),
//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_d = round(rand(0,count($counts)-2),-0.5);
//проверили соответствие нужной частоте появления
if (check($gen_d)) {
plus($gen_d);
//если первый даипазон, генерим от минимума до его предела
if ($gen_d==0) return round(rand($min,$counts[$gen_d]['amount']*$max),-0.5);
//иначе от предела предыдущего диапазона до своего предела
return round(rand($counts[$gen_d-1]['amount']*$max,$counts[$gen_d]['amount']*$max),-0.5);
}
}
//проверяем
$min = 1; $max = 100;
for ($tries = 0; $tries < 100; $tries++) {
$price_gen = 0;
//без while иногда пропуски были, более быстрого решения не придумал
while (!$price_gen) $price_gen = gen_price($min,$max);
echo $price_gen . " ";
}
?>
89 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів