...

суббота, 21 сентября 2013 г.

Код управляемого псевдо-рандома от новичка (изобрел велосипед?)

А давайте вы меня немного полошите…

В последнем своем проекте мне было необходимо написать простой и быстрый, но управляемый генератор случайных чисел. Писал сразу после прохождения 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, то генератор работает крайне предсказуемо и выдает числа, как только это можно сделать. Для меньшей предсказуемости можно назначить вероятности так, чтобы в сумме было больше еденицы, правила все-равно будут соблюдены.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at fivefilters.org/content-only/faq.php#publishers. Five Filters recommends:



Комментариев нет:

Отправить комментарий