Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737 Форумы портала PHP.SU :: Расчет шансов (спорный вопрос) [2]
Покинул форум
Сообщений всего: 378
Дата рег-ции: Сент. 2014
Помог: 10 раз(а)
[+]
Да не, сделано криво, все верно. Выглядит, как "хотели как лучше, получилось как всегда". Не выеживался бы с контролем распределения - не попал бы.
----- self-banned
DeepVarvar
Отправлено: 22 Октября, 2015 - 10:09:18
Активный участник
Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008 Откуда: Альфа Центавра
Помог: 353 раз(а)
Вчера мне эта задача не давала покоя.
Ну, в каком смысле -- мне не нравится ни реализация ТС, ни постановка задачи.
За вчера я прикинул разных вариантов.
Пришел вот к чему:
1) При "приведении" дробей в десятичную систему исчисления, мы теряем точность.
И даже может случиться так, что при малом значении $precision диапазон ранжа элемента вообще не будет добавлен в таблицу.
Я мог бы реализовать и максимальную точность, но мне влом лопатить циклы для нахождения НОК и НОД (+ подробности в п.4).
2) Почему собираю индексы в массив?
Потому что необходимо "запоминать" состояние "случайной" генерации.
В таком виде будет достаточно сдвигать курсор в массиве.
А при достижении конца массива, шафлануть его еще раз, и гнать по кругу.
Еще:
Паноптик указал мне, что запиливать массив и двигать в нем курсор некошерно.
Предложил такой вариант:
Цитата:
ты берешь допустим сумму всех коэфициентов и делаешь рандом число
рандом число в пределах суммы
и к примеру для чисел 1/2 1/3 1/4 - сумма будет 12
делаешь ранд от 1 до 12
ретурн получается следующий
если ранд < 12*1/2 ретурн ключ 1/2
если ранд < 12*(1/2+1/3) ретуран 1/3
сумма не важно какая
это может быть хоть статическое число
1000 например
главное чтобы распределить эту 1000 на равные куски которые соответствуют сумме всех коэфициентов
то есть для чисел 1/2 1/3 1/4 это будет примерно соотношение 0,5+0,33+0,25 = 1,08
коеф1/2 = 0,5/1,08 ~ 46%
коеф1/3 = 0,33/1,08 ~ 30%
коеф1/4 = 0,25/1,08 ~ 23%
соотвественно если рандом число входит в промежуток от 0 до коеф1 - то результат 1
если от коеф1 до коеф2 - результат 2 и тд
Но ранд может надолго засесть, например, в коэффе 46% и выдать не корректное кол-во вариантов в заданном диапазоне.
Т.е. условие задачи будет нарушено.
3) Для конкретного примера можно подзабить на ресурсы.
В реальной же задаче можно было бы написать свой псевдослучайный алгоритм с обходом ранжа без повторов, который позволил бы не создавать этот монстрячий массив.
4) Даже для моего примера, если приводить к точным кол-вам попыток, то получается что сумма этих трех дробей больше еденицы.
Так же, неизвестно что делать и при сумме вариантов меньше еденицы.
Мне что, нуллы выдавать через раз, если например передано array('a' => '1/4', 'b' => '1/4')?
А если нуллы выдавать не положено, то, какие ж это нахрен 1/4 ?
Покинул форум
Сообщений всего: 378
Дата рег-ции: Сент. 2014
Помог: 10 раз(а)
[+]
Тут или случайная выдача с разной вероятностью или точная выдача в пропорциях. Третьего не дано. Просто по определению случайного числа ;)
Но, к слову, в условии задачи ничего про случайность не сказано. А с этой точки зрения - она сделана правильно.
----- self-banned
DeepVarvar
Отправлено: 22 Октября, 2015 - 13:21:46
Активный участник
Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008 Откуда: Альфа Центавра
Помог: 353 раз(а)
MiksIr пишет:
в условии задачи ничего про случайность не сказано
Цитата:
следующие требования:
- при многократном вызове функции ключи массива должны возвращаться с пропорциями, указанными в значениях.
Цитата:
с пропорциями указанными в значениях
Цитата:
с пропорциями
Цитата:
указанными в значениях
Цитата:
a=>1/8, b=>1/2, при запуске функции большое количество раз, в 20% случаев должен вернуться ключ a, в остальных – b
Цитата:
в 20% случаев
Цитата:
случаев
(Добавление)
MiksIr пишет:
или случайная выдача с разной вероятностью или точная выдача в пропорциях
Автор вопроса сам не понял что ему надо -- вдоль или поперек.
Я расписал вариант который может сделать и вдоль и попререк (случайность в заданных пропорциях), но с условием, что сумма дробей поданных на вход должна быть равной еденице.
Иначе он на двух стульях не усидит.
Покинул форум
Сообщений всего: 378
Дата рег-ции: Сент. 2014
Помог: 10 раз(а)
[+]
Ты надеяшься, что от частого повтора слов условия задачи где-то сможешь увидеть слово "случайное"? ;)
Продолжай ;)
PS: на случай, если русский - не твой родной. "случай" в данном контексте несет смысл случившегося события, некого факта вызова функции. И отношения к слову "случайное" не имеет ;)
Покинул форум
Сообщений всего: 378
Дата рег-ции: Сент. 2014
Помог: 10 раз(а)
[+]
Скорее всего задача все же на случайное. И вероятность получения 19% вместо 20% на малом числе интераций - допустима. И в этом случае нужно просто привести классическое решение поиска на отрезке (ну типа того, что под спойлером).
Но в общем да, условие задачи безумное ;)
Твое тоже ничего, но если ты уже наговнокодил что-то вроде $v = explode('/', $v);, вместо того, что бы просто писать 1/2 * $точность, то и считай необходимую точность сам, в чем проблема ;) Наменьшее общее кратное называется ;)
----- self-banned
DeepVarvar
Отправлено: 22 Октября, 2015 - 13:44:31
Активный участник
Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008 Откуда: Альфа Центавра
Помог: 353 раз(а)
MiksIr пишет:
Наменьшее общее кратное называется
Ты как-то плохо прочитал тот мой пост "подгоревшего пукана" -- там есть и про НОК и про НОД. (Добавление)
Короче, если бы условия задачи были такими, что на вход нужно было подавать так: array('a' => 20, 'b' => 65) то да, вычислить размер ранжа можно было бы из суммы значений.
А так -- полная лажа.
Покинул форум
Сообщений всего: 378
Дата рег-ции: Сент. 2014
Помог: 10 раз(а)
[+]
Ну да, много написано всего было, извини ;)
----- self-banned
DeepVarvar
Отправлено: 22 Октября, 2015 - 14:06:08
Активный участник
Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008 Откуда: Альфа Центавра
Помог: 353 раз(а)
MiksIr пишет:
извини
Да было б за что.
Пока я тот пост писал, мой пукан превратился в головешку, а под ним стул поплавился.
Со стула потек жидкий пластик и залил ковер.
Вот не знаю что теперь делать.
Не обращать так сильно внимание на тупые вопросы работодателей?
Покинул форум
Сообщений всего: 378
Дата рег-ции: Сент. 2014
Помог: 10 раз(а)
[+]
Думаю, что наиболее простой и вменяемый вариант тут - приведение дробей к общему знаменателю, потом его отбрасывание и работа уже с отрезком из целых чисел.
----- self-banned
DeepVarvar
Отправлено: 22 Октября, 2015 - 14:28:24
Активный участник
Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008 Откуда: Альфа Центавра
Помог: 353 раз(а)
Тогда:
1) отпадает смысл входного формата ака дробь (мб только хотели видеть как решающий бут с дробями работать, но, это не известно).
Кстати, это в моем примере дроби как дроби.
А в условии задачи сразу деление, т.е. сразу флоаты.
В любом случае я решил задачу пропорционального распределения случайностей (таблица или кастом генератор).
Но, домножение флоатов до целого числа, где множитель зависит от максимальной заполненности разрядов одного из флоатов, ИМХО, приведет сразу к тому, что мы упремся в PHP_INT_MAX.
Вот и приплыли -- при малой точности выпадают варианты, а при большой упираемся в ограничения.
Ну да -- давай gmp_* прикрутим ))
2) работа с отрезком челых чисел, где размер отрезка равен их сумме, противоречит условию пропорций поставленному в задаче.
И вносит двойную неточность:
а) сумма безосновательно болтающихся "на хвосте абстрактного коня в вакууме" чисел.
б) рандом который может надолго залипнуть в некотором сегменте отрезка.
Все гости форума могут просматривать этот раздел. Только зарегистрированные пользователи могут создавать новые темы в этом разделе. Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.