Opi1sumu
Описание задачи
Дано одинаковых станков, которые работают параллельно и работ, котороые необходимо выполнить в произвольном порядке на всех станках. Время выполнения каждой работы на любом станке одинаково и равно одному. Для каждой работы известно время, до которого её необходимо выполнить. Необходимо успеть выполнить как можно больше работ.
Описание алгоритма
Отсортируем работы в порядке невозрастания дедлайнов.
| Утверждение: |
Если в оптимальном расписании можно сделать работ, то можно сделать первые работ. |
|
Пусть в оптимальном расписании были сделаны работы . Докажем, что существует оптимальное расписание, в котором сделаны работы . Пусть работы тоже отсортированы в порядке неубывания дедлайна. Тогда . Тогда, если заменить во всём расписании работу на работу , то она, тем более, будет выполнена. |
| Определение: |
| Обозначим за тайм-слот t множество из не более, чем различных чисел — номера работ, которые мы хотим выполнить в момент времени . |
Введем тайм-слот для каждого момента времени от до .
Каждую работу будем пытаться сделать как можно позже. Будет рассматривать работы в порядке невозрастания дедлайнов.
-ю работу попытаемся добавить в тайм-слоты с по .
После добавления некоторые тайм-слоты могли переполниться (тайм-слот переполнился, если в нём уже находилось
работ, и в него добавили -ю).
Для переполнившегося тайм-слота найдём найдем самый правый левее него, который ещё не переполнился и перекинем работу,
которой там еще нет, в него. Так как в нем меньше элементов, то, по принципу Дирихле, это можно сделать.
| Утверждение: |
Следуя этому алгоритму, первый тайм-слот переполнится тогдаи только тогда, когда переполнилнился
нулевой тайм-слот. |
| ? |
Опираясь на это утверждение, можно найти максимальное количество работ, которое можно выполнить. Обозначим его за .
Сведем задачу построения распинания по построенным тайм-слотам к задаче о покрытии двудольного графа минимальным количеством паросочетаний.
Построим двудольный граф. В левой доле вершинам будут соответствоввать работы, в правой — времена. Соответственно, в левой доле будет вершин, в правой — . Ребро между работой и временем будет, если работа есть в тайм-слоте .
Рассмотрим какое-то паросочетание в этом графе. Оно соответствует корректному расписанию работ на одной машине: ни одна работа не выполняется два раза, и ни в один момент времени не выполняется более одной работы.
Тогда, если мы сможем построить множество мощности такое, что каждое ребро находится хотя бы в одном из паросочетаний, то оно будет соответствовать тому, что каждая работа обработана на каждом станке, а значит, составлено корректное расписание для этих работ.
Достроим граф до регулярного степени . Достраивать будем следующим образом. Каждая вершина в левой доле имеет степень , так как каждая работа представлена в тайм-слотах. В правой доле степень каждой вершины не больше , так как в тайм-слоте не может быть больше, чем работ. Значит, в левой доле не больше вершин, чем в правой. Добавим в левую долю фиктивных вершин, чтобы количества вершин в левой и правой долях сравнялись. После чего просто будем добавлять ребра между вершинами, степень которых еще меньше .
Для покрытия этого графа паросочетаниями воспользуемся тем фактом, что регулярный двудольный граф степени можно покрыть паросочетаниями. Значит, этот граф можно покрывать паросочетаниями жадно: найти максимальное паросочетание, удалить его и свести задачу к меньшей. После удаления граф останется регулярым, поэтому так действовать можно.