Как вы указали, это проблема балансировки нагрузки. На самом деле это не проблема планирования, поскольку вы ничего не пытаетесь свести к минимуму (общее время, количество работающих одновременно и т. Д.). Особых ограничений нет (продолжительность работы, столкновения во времени, наборы навыков для сопоставления и т. Д.). Таким образом, ваша проблема сводится к выбору подходящей весовой функции.
Вы говорите, что есть некоторые ситуации, которые вы хотите избежать, например, взвешивание пользователя, которое слишком близко друг к другу. Можете ли вы предоставить более подробную информацию? Например, что плохого в том, чтобы сделать возможность назначения прямо пропорциональной текущей рабочей нагрузке, нормированной рабочей нагрузкой других работников? Вы можете визуализировать это как последовательность блоков разной длины (задачи), упакованных в наборы бинов (рабочих), где вы пытаетесь сохранить общую высоту бункеров как можно более равномерной.
Имея больше информации, мы могли бы дать конкретные рекомендации относительно функций, которые могли бы работать для вас.
Редактировать: пример функций балансировки нагрузки
Основываясь на ваших комментариях, вот несколько примеров простых функций, которые могут дать вам другое поведение балансировки. Основной вопрос - хотите ли вы детерминированного или вероятностного поведения. Я приведу пару примеров каждого из них.
Чтобы использовать пример в вопросе - в настоящее время назначено 4 + 5 + 0 + 7 + 9 = 25 рабочих мест. Вы хотите выбрать, кто получает работу 26.
1) Простая ферма задач. Для каждого задания всегда выбирайте работника с наименьшим количеством ожидающих заданий в данный момент. Быстрые работники получают больше работы, но все заканчивают примерно в одно и то же время.
2) Гарантируйте справедливую рабочую нагрузку. Если рабочие работают с разной скоростью, и вы не хотите, чтобы некоторые выполняли больше, чем другие, то отследите количество выполненных + ожидающих заданий для каждого работника. Назначьте следующее задание, чтобы это число равномерно распределилось (работники получают бесплатные перерывы).
3) Базовая линейная нормализация. Выберите максимальное количество заданий, которое может выполнять каждый работник. Рабочая нагрузка каждого работника нормируется на это число. Например, если максимальное количество рабочих мест на одного работника составляет 15, то можно добавить еще 50 рабочих мест, прежде чем вы достигнете емкости. Таким образом, для каждого работника вероятность назначения следующей работы составляет
P(A) = (15 - 4)/50 = 0.22
P(B) = (15 - 5)/50 = 0.2
P(C) = (15 - 0)/50 = 0.3
P(D) = (15 - 7)/50 = 0.16
P(E) = (15 - 9)/50 = 0.12
Если вы не хотите использовать конкретный максимальный порог, вы можете использовать в качестве предела работника с наибольшим текущим числом ожидающих заданий. В данном случае это работник E, поэтому вероятности будут
P(A) = (9 - 4)/20 = 0.25
P(B) = (9 - 5)/20 = 0.2
P(C) = (9 - 0)/20 = 0.45
P(D) = (9 - 7)/20 = 0.1
P(E) = (9 - 9)/20 = 0
Обратите внимание, что в этом случае нормализация гарантирует, что работнику E не могут быть назначены какие-либо задания - он уже на пределе. Кроме того, тот факт, что С не имеет ничего общего, не означает, что ему гарантированно дадут новую работу (это просто более вероятно).
Вы можете легко реализовать функцию выбора, сгенерировав случайное число r между 0 и 1 и сравнив его с этими границами. Поэтому, если r <0,25, А получает работу, 0,25 <<em> р <0,45, В получает работу и т. Д. </p>
4) Нелинейная нормализация. Использование лог-функции (вместо линейного вычитания) для взвешивания ваших чисел - это простой способ получить нелинейную нормализацию. Вы можете использовать это, чтобы искажать вероятности, например, значительно повысить вероятность того, что работникам, не имеющим много рабочих мест, дается больше.
Дело в том, что количество способов сделать это практически неограниченно. Какая весовая функция вы используете, зависит от конкретного поведения, которое вы пытаетесь включить. Надеюсь, что это дало вам некоторые идеи, которые вы можете использовать в качестве отправной точки.