Взвешенный алгоритм распределения ресурсов с балансировкой нагрузки - PullRequest
2 голосов
/ 11 сентября 2009

Программное приложение, над которым я работаю, должно иметь возможность назначать задачи группе пользователей в зависимости от того, сколько задач у них в данный момент, где пользователи с наименьшим количеством задач с большей вероятностью получат следующую задачу. Однако текущая нагрузка задачи должна рассматриваться как взвешивание, а не определение абсолютного порядка. IOW, мне нужно реализовать взвешенный алгоритм распределения нагрузки.

Допустим, есть пять пользователей со следующим количеством задач:

A: 4 Б: 5 C: 0 Д: 7 E: 9

Я хочу расставить приоритеты пользователей для следующей задачи в порядке CABDE, где C, скорее всего, получит назначение, а E, наименее вероятно. Здесь следует отметить две важные вещи:

  • Количество пользователей может варьироваться от 2 до десятков.
  • Количество задач, назначаемых каждому пользователю, может варьироваться от 1 до сотен.

На данный момент мы можем рассматривать все задачи как равные, хотя я бы не стал включать задачу в качестве переменной, которую я могу использовать в будущем, - но это просто глазурь на торте.

Идеи, которые я выдвинул до сих пор, не очень хороши в некоторых ситуациях. Они могут взвешивать пользователей слишком близко друг к другу, если существует большое количество пользователей, или они могут потерпеть неудачу, если у пользователя нет текущих задач, или ....

Я пытался ковыряться в Интернете, но мне не повезло. Может кто-нибудь дать мне краткое описание алгоритма, который будет работать хорошо? Мне не нужна реальная реализация - я сделаю эту часть - просто хорошее описание. Альтернатива, есть ли хороший веб-сайт, который находится в свободном доступе?

Кроме того, хотя я, конечно, ценю качество, это не обязательно должно быть статистически идеально. Так что, если вы можете придумать хорошую, но не отличную технику, мне интересно!

1 Ответ

7 голосов
/ 11 сентября 2009

Как вы указали, это проблема балансировки нагрузки. На самом деле это не проблема планирования, поскольку вы ничего не пытаетесь свести к минимуму (общее время, количество работающих одновременно и т. Д.). Особых ограничений нет (продолжительность работы, столкновения во времени, наборы навыков для сопоставления и т. Д.). Таким образом, ваша проблема сводится к выбору подходящей весовой функции.

Вы говорите, что есть некоторые ситуации, которые вы хотите избежать, например, взвешивание пользователя, которое слишком близко друг к другу. Можете ли вы предоставить более подробную информацию? Например, что плохого в том, чтобы сделать возможность назначения прямо пропорциональной текущей рабочей нагрузке, нормированной рабочей нагрузкой других работников? Вы можете визуализировать это как последовательность блоков разной длины (задачи), упакованных в наборы бинов (рабочих), где вы пытаетесь сохранить общую высоту бункеров как можно более равномерной.

Имея больше информации, мы могли бы дать конкретные рекомендации относительно функций, которые могли бы работать для вас.

Редактировать: пример функций балансировки нагрузки

Основываясь на ваших комментариях, вот несколько примеров простых функций, которые могут дать вам другое поведение балансировки. Основной вопрос - хотите ли вы детерминированного или вероятностного поведения. Я приведу пару примеров каждого из них.

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

Дело в том, что количество способов сделать это практически неограниченно. Какая весовая функция вы используете, зависит от конкретного поведения, которое вы пытаетесь включить. Надеюсь, что это дало вам некоторые идеи, которые вы можете использовать в качестве отправной точки.

...