@daniil14056

Как упорядочить очередь из разных групп?

К примеру есть сервис, который должен обслужить сотрудников. Сотрудники поделены на несколько групп с разным числом сотрудников. Нужно составить очередь так что бы все сотрудники обслуживались равномерно.
К примеру, есть 3 группы из группа А из 3, Б из 3, С и 6 сотрудников. Вывод должен быть таким A C Б C А C Б C А C Б C .
  • Вопрос задан
  • 70 просмотров
Пригласить эксперта
Ответы на вопрос 2
sergiks
@sergiks Куратор тега Алгоритмы
♬♬
Арифметика расставит элементы каждой группы отдельно на отрезке.
a   a   a
b   b   b
c c c c c c

Найти длину самой длинной группы. Делить её на длину очередной группы — получится шаг для группы.
Назначить каждому элементу свойством его положение на «отрезке».
Сложить все в один массив и отсортировать по этому положению.

Результат недетерменирован. Скажем, в этом примере на позиции 0 сразу три элемента: a, b и c. Какой из них будет на котором из трёх первых мест – ничем не определено.

реализация на JS
const groups = {
  A: ['a', 'a', 'a',],
  B: ['b', 'b', 'b', 'b',],
  C: ['c', 'c', 'c', 'c', 'c', 'c',],
};

const longest = Math.max.apply(null, Object.values(groups).map(a => a.length));
const sortMe = [];
for (let p in groups) {
  const values = groups[p];
  const step = longest / values.length; // 1 and bigger
  values.forEach((v, i) => sortMe.push({w: i * step, v: v}));
}

sortMe.sort((a, b) => a.w - b.w);

const result = sortMe.map(el => el.v);

console.log(result);
// ["a", "b", "c", "c", "b", "a", "c", "b", "c", "a", "c", "b", "c"]
Ответ написан
wataru
@wataru Куратор тега Алгоритмы
Разработчик на С++, экс-олимпиадник.
Делайте жадно. Ставьте в очередь сотрудника той группы, которая меньше всего загружена пока.

Изначально у всех загрузка на 0/k[i] - поэтому выбираем любую случайно или первую по порядку.
Допустим выбрали группу a. Поставили одного сотрудника. У этой группы загрузка стала 1/k[0]. Это больше 0/k[i] для всех остальных групп, поэтому следующим сотрудником вы поставите кого-то другого.

Можно делать тупо - двумя циклами (внешний по общему количеству сотрудников, внутренний по всем группам).
Можно ускорить процесс, если использовать приоритетную очередь на минимум. Изначально кладете в очередь все группы с приоритетами 0. Потом достаете оттуда минимум, сотрудника этой группы ставите на заказ и добавляете в очередь эту группу назад с приоритетом +1/k[i]. Можно не класть в очередь группы, в которых не осталось незадействованных сотрудников. И тогда остановка - когда очередь пуста. Можно просто останавливаться когда у минимальной в очереди группы приоритет (k[i]/k[i]).
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы