Opi1sumu — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
(Новая страница: «==Описание задачи== Дано <tex>m</tex> одинаковых станков, которые работают параллельно и <tex>n</tex...»)
 
Строка 38: Строка 38:
 
Сведем задачу построения распинания по построенным тайм-слотам к задаче о покрытии двудольного графа минимальным  
 
Сведем задачу построения распинания по построенным тайм-слотам к задаче о покрытии двудольного графа минимальным  
 
количеством паросочетаний.
 
количеством паросочетаний.
 +
 +
Построим двудольный граф. В левой доле вершинам будут соответствоввать работы, в правой {{---}} времена. Соответственно, в левой доле будет <tex>n</tex> вершин, в правой {{---}} <tex>d_{max}</tex>. Ребро между работой <tex>i</tex> и временем <tex>t</tex> будет, если работа <tex>i</tex> есть в тайм-слоте <tex>t</tex>.
 +
 +
Рассмотрим какое-то паросочетание <tex>M</tex> в этом графе. Оно соответствует корректному расписанию работ на одной машине: ни одна работа не выполняется два раза, и ни в один момент времени не выполняется более одной работы.
 +
 +
Тогда, если мы сможем построить множество мощности <tex>m</tex> такое, что каждое ребро находится хотя бы в одном из паросочетаний, то оно будет соответствовать тому, что каждая работа обработана на каждом станке, а значит, составлено корректное расписание для этих <tex>k</tex> работ.
 +
 +
Достроим граф до регулярного степени <tex>m</tex>. Достраивать будем следующим образом. Каждая вершина в левой доле имеет степень <tex>m</tex>, так как каждая работа представлена в <tex>m</tex> тайм-слотах. В правой доле степень каждой вершины не больше <tex>m</tex>, так как в тайм-слоте не может быть больше, чем <tex>m</tex> работ. Значит, в левой доле не больше вершин, чем в правой.
 +
Добавим в левую долю фиктивных вершин, чтобы количества вершин в левой и правой долях сравнялись. После чего просто будем добавлять ребра между вершинами, степень которых еще меньше <tex>m</tex>.
 +
 +
Для покрытия этого графа паросочетаниями воспользуемся тем фактом, что регулярный двудольный граф степени <tex>d</tex> можно покрыть <tex>d</tex> паросочетаниями.
 +
Значит, этот граф можно покрывать паросочетаниями жадно: найти максимальное паросочетание, удалить его и свести задачу к меньшей. После удаления граф останется
 +
регулярым, поэтому так действовать можно.

Версия 01:20, 18 июня 2012

Описание задачи

Дано [math]m[/math] одинаковых станков, которые работают параллельно и [math]n[/math] работ, котороые необходимо выполнить в произвольном порядке на всех станках. Время выполнения каждой работы на любом станке одинаково и равно одному. Для каждой работы известно время, до которого её необходимо выполнить. Необходимо успеть выполнить как можно больше работ.

Описание алгоритма

Отсортируем работы в порядке невозрастания дедлайнов.

Утверждение:
Если в оптимальном расписании можно сделать [math]k[/math] работ, то можно сделать первые [math]k[/math] работ.
[math]\triangleright[/math]

Пусть в оптимальном расписании были сделаны работы [math]i_1, i_2, \ldots, i_k[/math]. Докажем, что существует оптимальное расписание, в котором сделаны работы [math]1, 2, \ldots, k[/math]. Пусть работы [math]i_1, i_2, \ldots, i_k[/math] тоже отсортированы в порядке неубывания дедлайна. Тогда [math]d_{i1} \le d_1, d_{i2}\le d_2, \ldots, d_{ik}\le d_{k}[/math].

Тогда, если заменить во всём расписании работу [math]i_j[/math] на работу [math]j[/math], то она, тем более, будет выполнена.
[math]\triangleleft[/math]


Определение:
Обозначим за тайм-слот t множество из не более, чем [math]m[/math] различных чисел — номера работ, которые мы хотим выполнить в момент времени [math]t[/math].


Введем тайм-слот для каждого момента времени от [math]0[/math] до [math]d_n[/math]. Каждую работу будем пытаться сделать как можно позже. Будет рассматривать работы в порядке невозрастания дедлайнов. [math]i[/math]-ю работу попытаемся добавить в тайм-слоты с [math]d_i - m + 1[/math] по [math]d_i[/math]. После добавления некоторые тайм-слоты могли переполниться (тайм-слот переполнился, если в нём уже находилось [math]m[/math] работ, и в него добавили [math]m+1[/math]-ю). Для переполнившегося тайм-слота найдём найдем самый правый левее него, который ещё не переполнился и перекинем работу, которой там еще нет, в него. Так как в нем меньше элементов, то, по принципу Дирихле, это можно сделать.

Утверждение:
Следуя этому алгоритму, первый тайм-слот переполнится тогдаи только тогда, когда переполнилнился нулевой тайм-слот.
[math]\triangleright[/math]
?
[math]\triangleleft[/math]

Опираясь на это утверждение, можно найти максимальное количество работ, которое можно выполнить. Обозначим его за [math]k[/math].

Сведем задачу построения распинания по построенным тайм-слотам к задаче о покрытии двудольного графа минимальным количеством паросочетаний.

Построим двудольный граф. В левой доле вершинам будут соответствоввать работы, в правой — времена. Соответственно, в левой доле будет [math]n[/math] вершин, в правой — [math]d_{max}[/math]. Ребро между работой [math]i[/math] и временем [math]t[/math] будет, если работа [math]i[/math] есть в тайм-слоте [math]t[/math].

Рассмотрим какое-то паросочетание [math]M[/math] в этом графе. Оно соответствует корректному расписанию работ на одной машине: ни одна работа не выполняется два раза, и ни в один момент времени не выполняется более одной работы.

Тогда, если мы сможем построить множество мощности [math]m[/math] такое, что каждое ребро находится хотя бы в одном из паросочетаний, то оно будет соответствовать тому, что каждая работа обработана на каждом станке, а значит, составлено корректное расписание для этих [math]k[/math] работ.

Достроим граф до регулярного степени [math]m[/math]. Достраивать будем следующим образом. Каждая вершина в левой доле имеет степень [math]m[/math], так как каждая работа представлена в [math]m[/math] тайм-слотах. В правой доле степень каждой вершины не больше [math]m[/math], так как в тайм-слоте не может быть больше, чем [math]m[/math] работ. Значит, в левой доле не больше вершин, чем в правой. Добавим в левую долю фиктивных вершин, чтобы количества вершин в левой и правой долях сравнялись. После чего просто будем добавлять ребра между вершинами, степень которых еще меньше [math]m[/math].

Для покрытия этого графа паросочетаниями воспользуемся тем фактом, что регулярный двудольный граф степени [math]d[/math] можно покрыть [math]d[/math] паросочетаниями. Значит, этот граф можно покрывать паросочетаниями жадно: найти максимальное паросочетание, удалить его и свести задачу к меньшей. После удаления граф останется регулярым, поэтому так действовать можно.