Команда решила, что каждое утро кто-то должен приносить круассаны для всех. Каждый раз это не должен быть один и тот же человек, поэтому должна существовать система, определяющая, чья очередь за ним. Цель этого вопроса - определить алгоритм решения, чья очередь будет приносить круассаны завтра.
Ограничения, предположения и цели:
- Чья очередь приносить круассаны, определится днем ранее.
- В любой день некоторые люди отсутствуют. Алгоритм должен выбрать кого-то, кто будет присутствовать в этот день. Предположим, что все пропуски известны за день, поэтому покупателя круассана можно определить накануне.
- В целом, большинство людей присутствуют в большинстве дней.
- В интересах справедливости каждый должен покупать круассаны столько раз, сколько другие. (В основном, предположим, что у каждого члена команды есть одинаковая сумма денег, которую можно потратить на круассаны.)
- Было бы неплохо иметь некоторый элемент случайности или, по крайней мере, воспринимаемой случайности, чтобы облегчить скуку реестра. Это не жесткое ограничение: это скорее эстетическое суждение. Однако один и тот же человек не должен выбираться дважды подряд.
- Человек, который приносит круассаны, должен знать заранее. Таким образом, если человек P должен принести круассаны в день D, то этот факт должен быть определен в какой-то предыдущий день, когда присутствует человек P. Например, если средство доставки круассанов всегда определяется накануне, то это должен быть один из людей, присутствующих накануне.
- Количество членов команды достаточно мало, поэтому ресурсы хранения и вычислительные ресурсы практически не ограничены. Например, алгоритм может опираться на полную историю того, кто принес круассаны в прошлом. До нескольких минут вычислений на быстром ПК каждый день будет в порядке.
Это модель реальной проблемы, поэтому вы можете оспорить или уточнить допущения, если считаете, что они лучше моделируют сценарий.
Происхождение: Узнайте, кто собирается купить круассаны от Флориана Маргэйна . Моя переформулировка здесь имеет несколько иные требования.
algorithms
scheduling
Жиль "ТАК - перестань быть злым"
источник
источник
Ответы:
Мне известны две категории решений такого рода проблем: смещенные лотереи и отфильтрованные / сгенерированные случайные последовательности .
Во-первых, давайте обойдемся без простых, но неправильных решений, которые не сохраняют состояния. Любое решение в стиле лотереи, не поддерживающее состояние, будет иметь количество выигрышей в биномиальном распределении, что не соответствует критерию «столько раз». Вы можете выбрать случайную последовательность, которая выбирает всех людей в равной степени (это происходит по списку; перестановки обеспечивают случайность), но как только люди начинают уходить в отпуск, в вашей последовательности появляются дыры. Если вы не отследите, вы снова окажетесь с биномиальными распределениями вместо поддержания равных усилий.
Давайте также обязуемся иметь фактическую случайность. Возможно, вы захотите, чтобы, например, человек не мог планировать свой отпуск на основе детерминистического алгоритма, чтобы он никогда не присутствовал, когда наступает его очередь покупать круассаны (я полагаю, что они не используют все свои дни отпуска) ,
Итак, о двух типах решений.
Чтобы построить смещенную лотерею, сначала обратите внимание, что мы можем выбирать практически из любого непрерывного распределения (с конечным отклонением), чтобы генерировать числа для нашей лотереи. Тогда проигравшим может стать человек с самым низким номером. Тогда самое простое предубеждение - отслеживать, купил ли каждый человек больше или меньше своей доли. Вы можете измерить смещение в единицах круассанов. Вы можете настроить степень случайности, изменив ширину и форму распределения - это также определит, как далеко каждый человек может пройти от «того же количества раз». Гауссианцы легки; они допускают разумное удивление, не имея слишком длинных хвостов («несправедливо»). Таким образом, основная форма решения (в коде Scala)
Вы можете следить за тем, кто купил последний, и давать им огромный пристрастный бонус (например
10*stdev
), чтобы люди не покупали дважды подряд, за исключением крайнего случая, когда структура отпуска позволила всем купить «последний» раз. (то есть вы покупаете, а затем отправляетесь в отпуск). То же самое, что не присутствовать в день, когда они выбраны. (Если кто-то отсутствует через день, он в конечном итоге будет , так как прожигает бонус к уклону; я считаю, что это особенность, а не ошибка).Таким образом, вы собираете список присутствующих сотрудников на день, предлагаете всем участвовать в лотерее, выбираете самых низких и обновляете. Вы можете выбрать, будет ли бонус на покупку равен количеству сотрудников (хорошо, когда стоимость незначительна, но поездка за круассанами обременительна), количеству присутствующих сотрудников (хорошо, если поездка легкая, но затраты обременительны ) или что-то промежуточное (чтобы признать оба бремени). Вероятно, лучше иметь штраф «кушать» только для людей, которые присутствуют, но вы можете сделать это в любом случае, если чувствуете, что простое пребывание в отпуске не дает вам правильного шага в меньшем количестве.
Чтобы построить отфильтрованную случайную последовательность, сначала вам нужно сгенерировать случайную последовательность. Перестановка списка сотрудников - лучший способ начать. Просто просмотрите список, по порядку, изо дня в день. Если кто-то не может купить, потому что его нет или его нельзя сказать или купить раньше, пропустите его. Теперь у вас есть проблема: вы накапливаете пропущенных людей. Это нормально, хотя. Когда вы дойдете до конца своей последовательности, добавьте список пропущенных сотрудников к полному списку, прежде чем перемешивать. Теперь вероятность появления пропорциональна тому, сколько раз вы были пропущены, что поддерживает свойство «то же количество раз».
Если вы используете стандартный случайный порядок, особенно легко определить количество случайностей, когда нет отпусков. Если вы выбрали людей , совершенно случайно, знание о том, кто должен был принести следующий будет содержать битов информации , если были N сотрудников. Вместо этого, однако, только N ! вместо N N возможны возможные последовательности, поэтому информация уменьшается на log 2 [ ( N !журнал2( N) N N! NN бита (для большогоN; дляN=10это1,14).журнал2[ ( N!NN)1 / N] ≈- 1журнал( 2 )+ журнал22 π/ N√N≈ - 1,4 N N= 10 1,14
Лично я предпочитаю предвзятое решение для лотереи, так как контроль над случайностью лучше. С отфильтрованными последовательностями вы можете придумать более сложные способы создания последовательностей. Например, вместо случайной перестановки, выполнить локальные перестановки на определенное расстояние или разрешить выгружать людей из пула целиком (но они попадают в пропущенный список), но эти вещи требуют больших алгоритмических усилий. С помощью лотереи вы просто корректируете стандартное отклонение.
источник
И когда это продолжается вечно, они живут счастливыми, деля одинаково цену на круассан.
Ps: извините за плохой английский, но я не являюсь носителем языка, и уже поздно ... пожалуйста, не стесняйтесь исправлять ошибки (и, возможно, добавьте такие специи в историю ...)
источник
Каждая ваша итерация
Если вы случайно выбрали человека среди людей в списке и исключили предыдущего покупателя, вы достигнете своих целей:
Другие предложенные мной алгоритмы менее случайны или менее справедливы:
Алгоритмы «колоды» не являются случайными в том смысле, что вероятность выплаты не постоянна (1 / N в первом пике, 1 / (N-1) во втором ... 1 в N-м пике - - если он еще не был выбран). Кроме того, если вы выбраны первым, у вас будет ровно ноль шансов быть выбранным в течение следующих N раз. Система легко ломается, входя редко, пока не выбрана, а затем постоянно.
«Компенсационные» алгоритмы, которые пытаются активно заставить всех получать одинаковое количество круассанов вместо того, чтобы полагаться на свойства случайных чисел, не могут быть случайными или справедливыми (или и тем, и другим).
источник