<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=217.66.156.102&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=217.66.156.102&amp;*"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/217.66.156.102"/>
		<updated>2026-06-11T14:17:56Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=P2precpi1Lmax&amp;diff=25615</id>
		<title>P2precpi1Lmax</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=P2precpi1Lmax&amp;diff=25615"/>
				<updated>2012-06-18T08:25:12Z</updated>
		
		<summary type="html">&lt;p&gt;217.66.156.102: /* Ссылки */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Описание задачи==&lt;br /&gt;
Даны два одинаковых станка, на которых необходимо обработать &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; деталей. &lt;br /&gt;
Каждую деталь можно обрабатывать на любом станке. Время, необходимое для обработки любой детали, &lt;br /&gt;
одинаково и равно одному. Для каждой детали известны момент времени, до&lt;br /&gt;
которого необходимо закончить работу над этой деталью — &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt;, а также номера деталей, &lt;br /&gt;
зависимых от нее. Необходимо минимизировать максимальное опоздание, где опоздание рассчитывается как&lt;br /&gt;
разность между временем, когда была закончена обработка детали, и временем дедлайна для этой&lt;br /&gt;
детали.&lt;br /&gt;
&lt;br /&gt;
==Описание алгоритма==&lt;br /&gt;
Полагаем, что ребра в графе ориентированы от работы, к работам, зависимым от нее.&lt;br /&gt;
Введем понятие ''вынужденного'' дедлайна &amp;lt;tex&amp;gt;d'_i&amp;lt;/tex&amp;gt; {{---}} максмальное время, до которого необходимо выполнить &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ую работу, чтобы успеть&lt;br /&gt;
выполнить все работы из &amp;lt;tex&amp;gt;S(i)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;S(i)&amp;lt;/tex&amp;gt; — множество работ, зависящих (не обязательно непосредственно) от &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ой работы.&lt;br /&gt;
Заметим, что эта величина может принимать отрицательные значения.&lt;br /&gt;
Обозначим через &amp;lt;tex&amp;gt;g(i, d)&amp;lt;/tex&amp;gt; количество работ &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;S(i)&amp;lt;/tex&amp;gt;,&lt;br /&gt;
таких что &amp;lt;tex&amp;gt;d'_k \le d&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Пусть уже посчитаны работы для всех &amp;lt;tex&amp;gt;j \in S(i)&amp;lt;/tex&amp;gt;. Тогда, если &amp;lt;tex&amp;gt;j \in S(i)&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ая работа&lt;br /&gt;
должна быть закончена до &amp;lt;tex&amp;gt;d'_j - \lceil \frac{g(i, d'_j)}{2} \rceil&amp;lt;/tex&amp;gt;. &lt;br /&gt;
|proof=Рассмотрим все работы &amp;lt;tex&amp;gt;k \in S(i)&amp;lt;/tex&amp;gt;, для которых &amp;lt;tex&amp;gt;d'_k \le d'_j&amp;lt;/tex&amp;gt;. Все эти работы будут выполнены после &lt;br /&gt;
окончания обработки детали с номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;. Для них &amp;lt;tex&amp;gt;d'_k \le d'_j&amp;lt;/tex&amp;gt;. Пусть работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; закончили выполнять в &lt;br /&gt;
момент времени &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;. Нужно до момента времени &amp;lt;tex&amp;gt;d'_j&amp;lt;/tex&amp;gt; выполнить ещё &amp;lt;tex&amp;gt;g(i, d'_j)&amp;lt;/tex&amp;gt; работ. &lt;br /&gt;
Так как в нашем распоряжении находятся две машины, то время их выполнения будет не менее, чем &amp;lt;tex&amp;gt;\lceil \frac{g(i, d'_j)}{2} \rceil&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Поскольку необходимо выполнить все эти работы до &amp;lt;tex&amp;gt;d'_j&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ая работа должна быть закончена до момента времени&lt;br /&gt;
&amp;lt;tex&amp;gt;d'_j - \lceil \frac{g(i, d'_j)}{2} \rceil&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Тогда финально получаем формулу для вычисления «вынужденного» дедлайна для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ой работы: &lt;br /&gt;
&amp;lt;tex&amp;gt;d'_i = \min\{d_i, \min\{d'_j - \lceil \frac{g(i, d'_j)}{2} \rceil\}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;j \in S(i)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Для вершин, исходящая степень которых равна нулю, по определению вынужденного дедлайна, считаем его равным обычному дедлайну.&lt;br /&gt;
Для подсчета вынужденных дедлайнов будем поддерживать список &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, содержащий вершины, отсортированные в порядке &lt;br /&gt;
неубывания ''дедлайнов''. ''Дедлайн'' равен вынужденному дедлайну, если он уже посчитан, и обычному {{---}} в противном случае. &lt;br /&gt;
Будем рассматривать вершины в порядке, обратном топологической сортировке графа, то есть, начиная с вершин нулевой исходящей степени.&lt;br /&gt;
Пусть на текущем шаге мы рассматриваем работу с &lt;br /&gt;
номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;. Перебирая вершины из &amp;lt;tex&amp;gt;S(i)&amp;lt;/tex&amp;gt; в порядке списка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, пересчитываем вынужденный дедлайн для&lt;br /&gt;
&amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ой вершины по формуле, указанной выше, после чего обновляем дедлайн этой вершины в списке &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
После подсчета вынужденных дедлайнов, оптимальное расписание считается жадным алгоритмом.&lt;br /&gt;
На каждом шаге на для обработки на станках выбираются работы с минимальным вынужденным дедлайном, для которых все необходимые &lt;br /&gt;
работы уже выполнены. Одновременно с этим считается максимальное опоздание. &lt;br /&gt;
&lt;br /&gt;
==Доказательство корректности==&lt;br /&gt;
{{Утверждение &lt;br /&gt;
|about=#1&lt;br /&gt;
|statement= В расписании с обычными дедлайнами нет опозданий тогда и только тогда, когда нет опозданий в расписании с&lt;br /&gt;
вынужденными дедлайнами.&lt;br /&gt;
|proof= &lt;br /&gt;
&amp;lt;tex&amp;gt;\Leftarrow&amp;lt;/tex&amp;gt; Поскольку вынужденный дедлайн не нарушен, то, больший его обычный дедлайн, также не будет нарушен.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\Rightarrow&amp;lt;/tex&amp;gt; По определению вынужденного дедлайна, &amp;lt;tex&amp;gt;d'_i&amp;lt;/tex&amp;gt; {{---}} максимальное время окончания работы &lt;br /&gt;
&amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, при котором&lt;br /&gt;
ещё можно успеть выполнить все работы из &amp;lt;tex&amp;gt;S(i)&amp;lt;/tex&amp;gt;. Значит, если для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; был нарушен вынужденный дедлайн, &lt;br /&gt;
то не все работы из &amp;lt;tex&amp;gt;S(i)&amp;lt;/tex&amp;gt; выполнены вовремя, то есть&lt;br /&gt;
был нарушен хотя бы один обычный дедлайн, что противоречит условию. &lt;br /&gt;
&lt;br /&gt;
Более формально, пусть был нарушен вынужденный дедлайн. Найдём работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; с нарушенным вынужденным дедлайном, &lt;br /&gt;
такую, что &amp;lt;tex&amp;gt;\forall k \in S(i) : d'_k &amp;lt;/tex&amp;gt; {{---}} не нарушено. Это всегда можно сделать в силу ацикличности графа.&lt;br /&gt;
Рассмотрим формулу для подсчёта вынужденного дедлайна: &lt;br /&gt;
&amp;lt;tex&amp;gt;d'_i = \min\{d_i, \min\{d'_j - \lceil \frac{g(i, d'_j)}{2} \rceil\}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;j \in S(i)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Минимум достигся либо на &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt;, что невозможно в силу того, что обычные дедлайны не нарушены, либо на каком-то&lt;br /&gt;
&amp;lt;tex&amp;gt;j \in S(i)&amp;lt;/tex&amp;gt;. В этом случае, &amp;lt;tex&amp;gt;d'_i = d'_j - \lceil\frac{g(i, d'_j)}{2}\rceil&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Значит, если &amp;lt;tex&amp;gt;d'_i&amp;lt;/tex&amp;gt; нарушено, то будет также нарушен вынужденный дедлайн для какого-то &amp;lt;tex&amp;gt;k \in S(i)&amp;lt;/tex&amp;gt;, &lt;br /&gt;
так как осталось меньше, чем &amp;lt;tex&amp;gt;d'_j - d'_i &amp;gt; \lceil \frac{g(i, d'_j)}{2} \rceil&amp;lt;/tex&amp;gt; единиц времени. Это &lt;br /&gt;
противоречит условии выбора &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение &lt;br /&gt;
|about=#2&lt;br /&gt;
|statement= Если существует расписание без опоздание, то приведенный выше алгоритм найдет такое расписание.&lt;br /&gt;
|proof= Пусть &amp;lt;tex&amp;gt;x(1), x(2),...,x(n)&amp;lt;/tex&amp;gt; {{---}} расписание, построенное этим алгоритмом, где &amp;lt;tex&amp;gt;x(i)&amp;lt;/tex&amp;gt; {{---}} время &lt;br /&gt;
начала обработки &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ой детали. Пусть в этом расписании существует работа, опаздывающая по обычным дедлайнам. Согласно &lt;br /&gt;
утверждению 1, в этом расписании также существует работа, опаздывающая по &amp;quot;вынужденным&amp;quot; дедлайнам. Пусть &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; {{---}} такая работа с &lt;br /&gt;
минимальным временем начала, то есть, удолетворяющая следующему условию: &amp;lt;tex&amp;gt;d'_i &amp;lt; x(i) + 1&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Следуя алгоритму, в каждый момент времени &lt;br /&gt;
&amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, такой что &amp;lt;tex&amp;gt;t &amp;lt; x(i)&amp;lt;/tex&amp;gt;, хотя бы одна работа с номером &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;d'_j \le d'_i&amp;lt;/tex&amp;gt; должна &lt;br /&gt;
быть выполнена, так как, иначе, по алгоритму, вместо &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; на этом шаге была бы выбрана работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, имеющая меньшее &lt;br /&gt;
&amp;lt;tex&amp;gt;d'&amp;lt;/tex&amp;gt; и, по построению модифицированных дедлайнов, независимая от &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Рассмотрим два случая.&lt;br /&gt;
&lt;br /&gt;
'''Первый случай''': в какой-то момент времени только одна работа с номером &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;d'_k \le d'_i&amp;lt;/tex&amp;gt; выполнена.&lt;br /&gt;
Выберем максимальное время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, такое что &amp;lt;tex&amp;gt;t &amp;lt; x(i)&amp;lt;/tex&amp;gt;, обладающее таким свойством. Тогда для всех работ c номером&lt;br /&gt;
&amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, которые выполнялись в момент времени с &amp;lt;tex&amp;gt;t+1&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;x(i)&amp;lt;/tex&amp;gt; выполняется &amp;lt;tex&amp;gt;d'_j \le d'_i&amp;lt;/tex&amp;gt;, кроме того, &lt;br /&gt;
ни один станок не простаивал в течении этого периода. Все работы &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, выполненные в период &amp;lt;tex&amp;gt;[t+1; x(i)]&amp;lt;/tex&amp;gt;, а также, &lt;br /&gt;
работа &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, должны быть зависимы от &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, потому что, иначе, только &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; должна быть выполнена до &lt;br /&gt;
момента времени &amp;lt;tex&amp;gt;t+1&amp;lt;/tex&amp;gt;. Так как было опоздание, &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\left\lceil \frac{g'(k, d'_i)}{2} \right\rceil \ge \left\lceil\frac{2(x(i) - t) - 1}{2} \right\rceil = x(i) - t&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Из определения вынужденных дедлайнов, &lt;br /&gt;
&amp;lt;tex&amp;gt;d'_k \le d'_i - \left\lceil \frac{g(k, d'_i)}2 \right\rceil&amp;lt;/tex&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\le d'_i - x(i) + t &amp;lt; x(i) + 1 - x(i) + t = t + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значит, работа &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; тоже опоздала, что противоречит минимальности выбора &amp;lt;tex&amp;gt;x(i)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Второй случай''': в каждый момент времени такой, что &amp;lt;tex&amp;gt;0 \le t &amp;lt; x(i)&amp;lt;/tex&amp;gt; выполняются две работы. По написанному выше,&lt;br /&gt;
для всех этих работ &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, выполняется &amp;lt;tex&amp;gt;d'_j \le d'_i&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда есть хотя бы &amp;lt;tex&amp;gt;2x(i) + 1&amp;lt;/tex&amp;gt; работ таких, что &amp;lt;tex&amp;gt;d'_j \le d'_i &amp;lt; x(i) + 1&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Их невозможно сделать за &amp;lt;tex&amp;gt;x(i)&amp;lt;/tex&amp;gt; времени, а значит, в каждом таком расписании есть опоздание.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=#3&lt;br /&gt;
|statement=При сдвиге всех &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;d'_i&amp;lt;/tex&amp;gt; сдвинутся также на это число.&lt;br /&gt;
|proof=&lt;br /&gt;
Для работ, от которых ничего не зависит, по определению &amp;lt;tex&amp;gt;d'_i = d_i&amp;lt;/tex&amp;gt;, а, значит, для них утверждение верно.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим остальные в порядке топологической сортировки. Тогда, по индукции, для всех потомков рассматриваемой вершины&lt;br /&gt;
утверждение будет верно. Также, так как &amp;lt;tex&amp;gt;d'_k + l \le d'_j + l \iff d'_k \le d'_j&amp;lt;/tex&amp;gt;, &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;(d_i + l)' = \min\{d_i + l, \min\{d'_j + l - \lceil\frac{g(i, d'_j)}{2}\rceil\}\}&amp;lt;/tex&amp;gt; для &amp;lt;tex&amp;gt;j \in S(i)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вынеся за минимум общее слагаемое, по определению вынужденных дедлайнов, получим искомую формулу &amp;lt;tex&amp;gt;(d_i + l)' = d'_i + l&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=Алгоритм строит оптимальное расписание&lt;br /&gt;
|proof=&lt;br /&gt;
Пускай каким-то образом было вычислено оптимальное значение &amp;lt;tex&amp;gt;l_{max}&amp;lt;/tex&amp;gt;. Тогда, по второму утверждению, если сдвинуть все&lt;br /&gt;
дедлайны на &amp;lt;tex&amp;gt;l_{max}&amp;lt;/tex&amp;gt;, то алгоритм получит для них оптимальное расписание. &lt;br /&gt;
&lt;br /&gt;
По третьему утверждению, для любого сдвига будет получено расписание с одним и тем же опозданием. Значит, &lt;br /&gt;
для сдвига на &amp;lt;tex&amp;gt;l_{max}&amp;lt;/tex&amp;gt; оно также будет оптимальным. &lt;br /&gt;
&lt;br /&gt;
В силу того, что для любого сдвига будет построено оптимальное расписание, алгоритм находит оптимальное расписание. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Сложность алгоритма==&lt;br /&gt;
В алгоритме требуется знать для двух произвольных работ, зависит ли, возможно, не непосредственно, одна от другой. Для этого нужно транзитивно замкнуть граф по отношению зависимости. Это можно сделать несколькими способами. Первый и самый простой {{---}} за &amp;lt;tex&amp;gt;O(n^3)&amp;lt;/tex&amp;gt; алгоритмом Флойда-Уоршалла. Второй {{---}} при помощи метода четырех русских за &amp;lt;tex&amp;gt;O(\frac{n^3}{\log n})&amp;lt;/tex&amp;gt;. Третий {{---}} применить алгоритм Фишера-Мейера для построения замыкания графа за &amp;lt;tex&amp;gt;O(n^{\log_2 7})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При подсчете вынужденных дедлайнов, за &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; считается вынужденный дедлайн одной работы. Так как всего работ &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, суммарное время подсчета вынужденных дедлайнов {{---}} &amp;lt;tex&amp;gt;O(n^2)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При, непосредственно, составлении расписания, на каждом шаге за &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; обрабатываются одна или две работы. Значит, все работы будут обработаны также за &amp;lt;tex&amp;gt;O(n^2)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итоговая сложность {{---}} &amp;lt;tex&amp;gt;O(TrCl + n^2)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
[http://rjlipton.files.wordpress.com/2009/10/matrix1971.pdf Алгоритм Фишера-Мейера]&lt;/div&gt;</summary>
		<author><name>217.66.156.102</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=P2precpi1Lmax&amp;diff=25613</id>
		<title>P2precpi1Lmax</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=P2precpi1Lmax&amp;diff=25613"/>
				<updated>2012-06-18T08:22:42Z</updated>
		
		<summary type="html">&lt;p&gt;217.66.156.102: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Описание задачи==&lt;br /&gt;
Даны два одинаковых станка, на которых необходимо обработать &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; деталей. &lt;br /&gt;
Каждую деталь можно обрабатывать на любом станке. Время, необходимое для обработки любой детали, &lt;br /&gt;
одинаково и равно одному. Для каждой детали известны момент времени, до&lt;br /&gt;
которого необходимо закончить работу над этой деталью — &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt;, а также номера деталей, &lt;br /&gt;
зависимых от нее. Необходимо минимизировать максимальное опоздание, где опоздание рассчитывается как&lt;br /&gt;
разность между временем, когда была закончена обработка детали, и временем дедлайна для этой&lt;br /&gt;
детали.&lt;br /&gt;
&lt;br /&gt;
==Описание алгоритма==&lt;br /&gt;
Полагаем, что ребра в графе ориентированы от работы, к работам, зависимым от нее.&lt;br /&gt;
Введем понятие ''вынужденного'' дедлайна &amp;lt;tex&amp;gt;d'_i&amp;lt;/tex&amp;gt; {{---}} максмальное время, до которого необходимо выполнить &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ую работу, чтобы успеть&lt;br /&gt;
выполнить все работы из &amp;lt;tex&amp;gt;S(i)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;S(i)&amp;lt;/tex&amp;gt; — множество работ, зависящих (не обязательно непосредственно) от &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ой работы.&lt;br /&gt;
Заметим, что эта величина может принимать отрицательные значения.&lt;br /&gt;
Обозначим через &amp;lt;tex&amp;gt;g(i, d)&amp;lt;/tex&amp;gt; количество работ &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;S(i)&amp;lt;/tex&amp;gt;,&lt;br /&gt;
таких что &amp;lt;tex&amp;gt;d'_k \le d&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Пусть уже посчитаны работы для всех &amp;lt;tex&amp;gt;j \in S(i)&amp;lt;/tex&amp;gt;. Тогда, если &amp;lt;tex&amp;gt;j \in S(i)&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ая работа&lt;br /&gt;
должна быть закончена до &amp;lt;tex&amp;gt;d'_j - \lceil \frac{g(i, d'_j)}{2} \rceil&amp;lt;/tex&amp;gt;. &lt;br /&gt;
|proof=Рассмотрим все работы &amp;lt;tex&amp;gt;k \in S(i)&amp;lt;/tex&amp;gt;, для которых &amp;lt;tex&amp;gt;d'_k \le d'_j&amp;lt;/tex&amp;gt;. Все эти работы будут выполнены после &lt;br /&gt;
окончания обработки детали с номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;. Для них &amp;lt;tex&amp;gt;d'_k \le d'_j&amp;lt;/tex&amp;gt;. Пусть работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; закончили выполнять в &lt;br /&gt;
момент времени &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;. Нужно до момента времени &amp;lt;tex&amp;gt;d'_j&amp;lt;/tex&amp;gt; выполнить ещё &amp;lt;tex&amp;gt;g(i, d'_j)&amp;lt;/tex&amp;gt; работ. &lt;br /&gt;
Так как в нашем распоряжении находятся две машины, то время их выполнения будет не менее, чем &amp;lt;tex&amp;gt;\lceil \frac{g(i, d'_j)}{2} \rceil&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Поскольку необходимо выполнить все эти работы до &amp;lt;tex&amp;gt;d'_j&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ая работа должна быть закончена до момента времени&lt;br /&gt;
&amp;lt;tex&amp;gt;d'_j - \lceil \frac{g(i, d'_j)}{2} \rceil&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Тогда финально получаем формулу для вычисления «вынужденного» дедлайна для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ой работы: &lt;br /&gt;
&amp;lt;tex&amp;gt;d'_i = \min\{d_i, \min\{d'_j - \lceil \frac{g(i, d'_j)}{2} \rceil\}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;j \in S(i)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Для вершин, исходящая степень которых равна нулю, по определению вынужденного дедлайна, считаем его равным обычному дедлайну.&lt;br /&gt;
Для подсчета вынужденных дедлайнов будем поддерживать список &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, содержащий вершины, отсортированные в порядке &lt;br /&gt;
неубывания ''дедлайнов''. ''Дедлайн'' равен вынужденному дедлайну, если он уже посчитан, и обычному {{---}} в противном случае. &lt;br /&gt;
Будем рассматривать вершины в порядке, обратном топологической сортировке графа, то есть, начиная с вершин нулевой исходящей степени.&lt;br /&gt;
Пусть на текущем шаге мы рассматриваем работу с &lt;br /&gt;
номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;. Перебирая вершины из &amp;lt;tex&amp;gt;S(i)&amp;lt;/tex&amp;gt; в порядке списка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, пересчитываем вынужденный дедлайн для&lt;br /&gt;
&amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ой вершины по формуле, указанной выше, после чего обновляем дедлайн этой вершины в списке &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
После подсчета вынужденных дедлайнов, оптимальное расписание считается жадным алгоритмом.&lt;br /&gt;
На каждом шаге на для обработки на станках выбираются работы с минимальным вынужденным дедлайном, для которых все необходимые &lt;br /&gt;
работы уже выполнены. Одновременно с этим считается максимальное опоздание. &lt;br /&gt;
&lt;br /&gt;
==Доказательство корректности==&lt;br /&gt;
{{Утверждение &lt;br /&gt;
|about=#1&lt;br /&gt;
|statement= В расписании с обычными дедлайнами нет опозданий тогда и только тогда, когда нет опозданий в расписании с&lt;br /&gt;
вынужденными дедлайнами.&lt;br /&gt;
|proof= &lt;br /&gt;
&amp;lt;tex&amp;gt;\Leftarrow&amp;lt;/tex&amp;gt; Поскольку вынужденный дедлайн не нарушен, то, больший его обычный дедлайн, также не будет нарушен.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\Rightarrow&amp;lt;/tex&amp;gt; По определению вынужденного дедлайна, &amp;lt;tex&amp;gt;d'_i&amp;lt;/tex&amp;gt; {{---}} максимальное время окончания работы &lt;br /&gt;
&amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, при котором&lt;br /&gt;
ещё можно успеть выполнить все работы из &amp;lt;tex&amp;gt;S(i)&amp;lt;/tex&amp;gt;. Значит, если для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; был нарушен вынужденный дедлайн, &lt;br /&gt;
то не все работы из &amp;lt;tex&amp;gt;S(i)&amp;lt;/tex&amp;gt; выполнены вовремя, то есть&lt;br /&gt;
был нарушен хотя бы один обычный дедлайн, что противоречит условию. &lt;br /&gt;
&lt;br /&gt;
Более формально, пусть был нарушен вынужденный дедлайн. Найдём работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; с нарушенным вынужденным дедлайном, &lt;br /&gt;
такую, что &amp;lt;tex&amp;gt;\forall k \in S(i) : d'_k &amp;lt;/tex&amp;gt; {{---}} не нарушено. Это всегда можно сделать в силу ацикличности графа.&lt;br /&gt;
Рассмотрим формулу для подсчёта вынужденного дедлайна: &lt;br /&gt;
&amp;lt;tex&amp;gt;d'_i = \min\{d_i, \min\{d'_j - \lceil \frac{g(i, d'_j)}{2} \rceil\}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;j \in S(i)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Минимум достигся либо на &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt;, что невозможно в силу того, что обычные дедлайны не нарушены, либо на каком-то&lt;br /&gt;
&amp;lt;tex&amp;gt;j \in S(i)&amp;lt;/tex&amp;gt;. В этом случае, &amp;lt;tex&amp;gt;d'_i = d'_j - \lceil\frac{g(i, d'_j)}{2}\rceil&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Значит, если &amp;lt;tex&amp;gt;d'_i&amp;lt;/tex&amp;gt; нарушено, то будет также нарушен вынужденный дедлайн для какого-то &amp;lt;tex&amp;gt;k \in S(i)&amp;lt;/tex&amp;gt;, &lt;br /&gt;
так как осталось меньше, чем &amp;lt;tex&amp;gt;d'_j - d'_i &amp;gt; \lceil \frac{g(i, d'_j)}{2} \rceil&amp;lt;/tex&amp;gt; единиц времени. Это &lt;br /&gt;
противоречит условии выбора &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение &lt;br /&gt;
|about=#2&lt;br /&gt;
|statement= Если существует расписание без опоздание, то приведенный выше алгоритм найдет такое расписание.&lt;br /&gt;
|proof= Пусть &amp;lt;tex&amp;gt;x(1), x(2),...,x(n)&amp;lt;/tex&amp;gt; {{---}} расписание, построенное этим алгоритмом, где &amp;lt;tex&amp;gt;x(i)&amp;lt;/tex&amp;gt; {{---}} время &lt;br /&gt;
начала обработки &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ой детали. Пусть в этом расписании существует работа, опаздывающая по обычным дедлайнам. Согласно &lt;br /&gt;
утверждению 1, в этом расписании также существует работа, опаздывающая по &amp;quot;вынужденным&amp;quot; дедлайнам. Пусть &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; {{---}} такая работа с &lt;br /&gt;
минимальным временем начала, то есть, удолетворяющая следующему условию: &amp;lt;tex&amp;gt;d'_i &amp;lt; x(i) + 1&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Следуя алгоритму, в каждый момент времени &lt;br /&gt;
&amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, такой что &amp;lt;tex&amp;gt;t &amp;lt; x(i)&amp;lt;/tex&amp;gt;, хотя бы одна работа с номером &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;d'_j \le d'_i&amp;lt;/tex&amp;gt; должна &lt;br /&gt;
быть выполнена, так как, иначе, по алгоритму, вместо &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; на этом шаге была бы выбрана работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, имеющая меньшее &lt;br /&gt;
&amp;lt;tex&amp;gt;d'&amp;lt;/tex&amp;gt; и, по построению модифицированных дедлайнов, независимая от &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Рассмотрим два случая.&lt;br /&gt;
&lt;br /&gt;
'''Первый случай''': в какой-то момент времени только одна работа с номером &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;d'_k \le d'_i&amp;lt;/tex&amp;gt; выполнена.&lt;br /&gt;
Выберем максимальное время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, такое что &amp;lt;tex&amp;gt;t &amp;lt; x(i)&amp;lt;/tex&amp;gt;, обладающее таким свойством. Тогда для всех работ c номером&lt;br /&gt;
&amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, которые выполнялись в момент времени с &amp;lt;tex&amp;gt;t+1&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;x(i)&amp;lt;/tex&amp;gt; выполняется &amp;lt;tex&amp;gt;d'_j \le d'_i&amp;lt;/tex&amp;gt;, кроме того, &lt;br /&gt;
ни один станок не простаивал в течении этого периода. Все работы &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, выполненные в период &amp;lt;tex&amp;gt;[t+1; x(i)]&amp;lt;/tex&amp;gt;, а также, &lt;br /&gt;
работа &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, должны быть зависимы от &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, потому что, иначе, только &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; должна быть выполнена до &lt;br /&gt;
момента времени &amp;lt;tex&amp;gt;t+1&amp;lt;/tex&amp;gt;. Так как было опоздание, &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\left\lceil \frac{g'(k, d'_i)}{2} \right\rceil \ge \left\lceil\frac{2(x(i) - t) - 1}{2} \right\rceil = x(i) - t&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Из определения вынужденных дедлайнов, &lt;br /&gt;
&amp;lt;tex&amp;gt;d'_k \le d'_i - \left\lceil \frac{g(k, d'_i)}2 \right\rceil&amp;lt;/tex&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\le d'_i - x(i) + t &amp;lt; x(i) + 1 - x(i) + t = t + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значит, работа &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; тоже опоздала, что противоречит минимальности выбора &amp;lt;tex&amp;gt;x(i)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Второй случай''': в каждый момент времени такой, что &amp;lt;tex&amp;gt;0 \le t &amp;lt; x(i)&amp;lt;/tex&amp;gt; выполняются две работы. По написанному выше,&lt;br /&gt;
для всех этих работ &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, выполняется &amp;lt;tex&amp;gt;d'_j \le d'_i&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда есть хотя бы &amp;lt;tex&amp;gt;2x(i) + 1&amp;lt;/tex&amp;gt; работ таких, что &amp;lt;tex&amp;gt;d'_j \le d'_i &amp;lt; x(i) + 1&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Их невозможно сделать за &amp;lt;tex&amp;gt;x(i)&amp;lt;/tex&amp;gt; времени, а значит, в каждом таком расписании есть опоздание.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=#3&lt;br /&gt;
|statement=При сдвиге всех &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;d'_i&amp;lt;/tex&amp;gt; сдвинутся также на это число.&lt;br /&gt;
|proof=&lt;br /&gt;
Для работ, от которых ничего не зависит, по определению &amp;lt;tex&amp;gt;d'_i = d_i&amp;lt;/tex&amp;gt;, а, значит, для них утверждение верно.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим остальные в порядке топологической сортировки. Тогда, по индукции, для всех потомков рассматриваемой вершины&lt;br /&gt;
утверждение будет верно. Также, так как &amp;lt;tex&amp;gt;d'_k + l \le d'_j + l \iff d'_k \le d'_j&amp;lt;/tex&amp;gt;, &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;(d_i + l)' = \min\{d_i + l, \min\{d'_j + l - \lceil\frac{g(i, d'_j)}{2}\rceil\}\}&amp;lt;/tex&amp;gt; для &amp;lt;tex&amp;gt;j \in S(i)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вынеся за минимум общее слагаемое, по определению вынужденных дедлайнов, получим искомую формулу &amp;lt;tex&amp;gt;(d_i + l)' = d'_i + l&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=Алгоритм строит оптимальное расписание&lt;br /&gt;
|proof=&lt;br /&gt;
Пускай каким-то образом было вычислено оптимальное значение &amp;lt;tex&amp;gt;l_{max}&amp;lt;/tex&amp;gt;. Тогда, по второму утверждению, если сдвинуть все&lt;br /&gt;
дедлайны на &amp;lt;tex&amp;gt;l_{max}&amp;lt;/tex&amp;gt;, то алгоритм получит для них оптимальное расписание. &lt;br /&gt;
&lt;br /&gt;
По третьему утверждению, для любого сдвига будет получено расписание с одним и тем же опозданием. Значит, &lt;br /&gt;
для сдвига на &amp;lt;tex&amp;gt;l_{max}&amp;lt;/tex&amp;gt; оно также будет оптимальным. &lt;br /&gt;
&lt;br /&gt;
В силу того, что для любого сдвига будет построено оптимальное расписание, алгоритм находит оптимальное расписание. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Сложность алгоритма==&lt;br /&gt;
В алгоритме требуется знать для двух произвольных работ, зависит ли, возможно, не непосредственно, одна от другой. Для этого нужно транзитивно замкнуть граф по отношению зависимости. Это можно сделать несколькими способами. Первый и самый простой {{---}} за &amp;lt;tex&amp;gt;O(n^3)&amp;lt;/tex&amp;gt; алгоритмом Флойда-Уоршалла. Второй {{---}} при помощи метода четырех русских за &amp;lt;tex&amp;gt;O(\frac{n^3}{\log n})&amp;lt;/tex&amp;gt;. Третий {{---}} применить алгоритм Фишера-Мейера для построения замыкания графа за &amp;lt;tex&amp;gt;O(n^{\log_2 7})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При подсчете вынужденных дедлайнов, за &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; считается вынужденный дедлайн одной работы. Так как всего работ &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, суммарное время подсчета вынужденных дедлайнов {{---}} &amp;lt;tex&amp;gt;O(n^2)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При, непосредственно, составлении расписания, на каждом шаге за &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; обрабатываются одна или две работы. Значит, все работы будут обработаны также за &amp;lt;tex&amp;gt;O(n^2)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итоговая сложность {{---}} &amp;lt;tex&amp;gt;O(TrCl + n^2)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
[http://rjlipton.files.wordpress.com/2009/10/matrix1971.pdf| Алгоритм Фишера-Мейера]&lt;/div&gt;</summary>
		<author><name>217.66.156.102</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Opi1sumu&amp;diff=25610</id>
		<title>Opi1sumu</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Opi1sumu&amp;diff=25610"/>
				<updated>2012-06-18T08:00:28Z</updated>
		
		<summary type="html">&lt;p&gt;217.66.156.102: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Описание задачи==&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; одинаковых станков, которые работают параллельно и &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ, котороые необходимо выполнить&lt;br /&gt;
в произвольном порядке на всех станках. Время выполнения каждой работы на любом станке одинаково и равно одному. &lt;br /&gt;
Для каждой работы известно время, до которого её необходимо выполнить. Необходимо успеть выполнить как можно больше работ. &lt;br /&gt;
&lt;br /&gt;
==Описание алгоритма==&lt;br /&gt;
Отсортируем работы в порядке невозрастания дедлайнов. &lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Если в оптимальном расписании можно сделать &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ, то можно сделать первые &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ.&lt;br /&gt;
|proof=Пусть в оптимальном расписании были сделаны работы &amp;lt;tex&amp;gt;i_1, i_2, \ldots, i_k&amp;lt;/tex&amp;gt;. Докажем, что существует &lt;br /&gt;
оптимальное расписание, в котором сделаны работы &amp;lt;tex&amp;gt;1, 2, \ldots, k&amp;lt;/tex&amp;gt;. Пусть работы &amp;lt;tex&amp;gt;i_1, i_2, \ldots, i_k&amp;lt;/tex&amp;gt;&lt;br /&gt;
тоже отсортированы в порядке неубывания дедлайна. Тогда &amp;lt;tex&amp;gt;d_{i1} \le d_1, d_{i2}\le d_2, \ldots, d_{ik}\le d_{k}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Тогда, если заменить во всём расписании работу &amp;lt;tex&amp;gt;i_j&amp;lt;/tex&amp;gt; на работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, то она, тем более, будет выполнена.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=Обозначим за ''тайм-слот t'' множество из не более, чем &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; различных чисел {{---}} &lt;br /&gt;
номера работ, которые мы хотим выполнить в момент времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Введем тайм-слот для каждого момента времени от &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;d_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Каждую работу будем пытаться сделать как можно позже. Будет рассматривать работы в порядке невозрастания дедлайнов. &lt;br /&gt;
&amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ю работу попытаемся добавить в тайм-слоты с &amp;lt;tex&amp;gt;d_i - m + 1&amp;lt;/tex&amp;gt; по &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt;. &lt;br /&gt;
После добавления некоторые тайм-слоты могли переполниться (тайм-слот переполнился, если в нём уже находилось&lt;br /&gt;
&amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; работ, и в него добавили &amp;lt;tex&amp;gt;m+1&amp;lt;/tex&amp;gt;-ю). &lt;br /&gt;
Для переполнившегося тайм-слота найдём найдем самый правый левее него, который ещё не переполнился и перекинем работу, &lt;br /&gt;
которой там еще нет, в него. Так как в нем меньше элементов, то, по принципу Дирихле, это можно сделать. &lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Следуя этому алгоритму, расписания не существует тогда и только тогда, когда&lt;br /&gt;
переполнился нулевой тайм-слот.&lt;br /&gt;
|proof=&lt;br /&gt;
&amp;lt;tex&amp;gt;\Rightarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
Расписания не существует, а значит, никакой алгоритм его не найдет.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\Leftarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
Пусть при добавлении &amp;lt;tex&amp;gt;k+1&amp;lt;/tex&amp;gt;-й работы произошло переполнение нулевого тайм-слота.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим алгоритм добавления в тайм-слоты: работа &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;добавляется в тайм-слоты &amp;lt;tex&amp;gt;[d_i - m + 1; d_i]&amp;lt;/tex&amp;gt;, после чего из переполнившихся работы перебрасываются в более ранние. Временно разрешим хранить в тайм-слоте сколь угодно много работ: отменим перебрасывание. Посмотрим на то, что получилось. Так как работу нельзя выполнять одновременно на двух станках, то ни одну единицу работы отсрочить нельзя.  Будем рассматривать тайм-слоты в порядке уменьшения времени. Если в очередном тайм-слоте &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; в данный момент больше, чем &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; работ, то остаток нужно перекинуть на какие-то более ранние тайм-слоты. Заметим, что выгоднее перекинуть на наиболее поздние тайм-слоты: более ранние тайм-слоты могут понадобиться для перекидываний с тайм-слотов, идущих раньше просматриваемого. .&lt;br /&gt;
&lt;br /&gt;
Также заметим, что алгоритм перекидывания работ таков, что итоговое распределение количеств работ в соответствующих тайм-слотах не зависит от того, в каком порядке обрабатывались переполнившиеся тайм-слоты. &lt;br /&gt;
&lt;br /&gt;
При рассмотрении очередного переполнившегося тайм-слота мы необходимо должны куда-то перекинуть несколько работ из него. Так как перекидывание происходит в тайм-слот с наибольшим допустимым временем, то то, что неоходимо перекинуть что-то из нулевого, влечет то, что не существует расписания, в котором можно успеть выполнить все эти работы&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Опираясь на это утверждение, можно найти максимальное количество работ, которое можно выполнить. Обозначим его за &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сведем задачу построения распинания по построенным тайм-слотам к задаче о покрытии двудольного графа минимальным &lt;br /&gt;
количеством паросочетаний.&lt;br /&gt;
&lt;br /&gt;
Построим двудольный граф. В левой доле вершинам будут соответствоввать работы, в правой {{---}} времена. Соответственно, в левой доле будет &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин, в правой {{---}} &amp;lt;tex&amp;gt;d_{max}&amp;lt;/tex&amp;gt;. Ребро между работой &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и временем &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; будет, если работа &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; есть в тайм-слоте &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим какое-то паросочетание &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; в этом графе. Оно соответствует корректному расписанию работ на одной машине: ни одна работа не выполняется два раза, и ни в один момент времени не выполняется более одной работы.&lt;br /&gt;
&lt;br /&gt;
Тогда, если мы сможем построить множество мощности &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; такое, что каждое ребро находится хотя бы в одном из паросочетаний, то оно будет соответствовать тому, что каждая работа обработана на каждом станке, а значит, составлено корректное расписание для этих &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ.&lt;br /&gt;
&lt;br /&gt;
Достроим граф до регулярного степени &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;. Достраивать будем следующим образом. Каждая вершина в левой доле имеет степень &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;, так как каждая работа представлена в &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; тайм-слотах. В правой доле степень каждой вершины не больше &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;, так как в тайм-слоте не может быть больше, чем &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; работ. Значит, в левой доле не больше вершин, чем в правой.&lt;br /&gt;
Добавим в левую долю фиктивных вершин, чтобы количества вершин в левой и правой долях сравнялись. После чего просто будем добавлять ребра между вершинами, степень которых еще меньше &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;. Для покрытия этого графа паросочетаниями воспользуемся тем фактом, что регулярный двудольный граф степени &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; можно покрыть &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; паросочетаниями. &lt;br /&gt;
&lt;br /&gt;
При помощи построения паросочетаний было построено расписание для тех &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ, которые можно успеть сделать. Так как остальные работы уже нельзя успеть, расписание для них можно составить произвольное. Например, выполнять их по очереди после выполнения первых &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ.&lt;br /&gt;
&lt;br /&gt;
==Оценка сложности алгоритма==&lt;br /&gt;
Рассмотрим добавление очередной работы в тайм-слоты. За &amp;lt;tex&amp;gt;O(t)&amp;lt;/tex&amp;gt; найдём переполнившийся тайм-слот и за &amp;lt;tex&amp;gt;O(m)&amp;lt;/tex&amp;gt; перекинем из него элемент. Так как &amp;lt;tex&amp;gt;t=O(nm)&amp;lt;/tex&amp;gt;, итоговая сложность этой части {{---}} &amp;lt;tex&amp;gt;O(n^2m)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Достроение графа до регулярного делается за &amp;lt;tex&amp;gt;O(E)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; {{---}} количество ребер в нем. Количество ребер в регулярном двудольном графе &amp;lt;tex&amp;gt;E = Vd&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; {{---}} количество вершин в одной из долей, а &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; {{---}} степень. Количество вершин в правой доле {{---}} &amp;lt;tex&amp;gt;O(t) = O(nm)&amp;lt;/tex&amp;gt;. Значит, граф будет построен за &amp;lt;tex&amp;gt;O(nm^2)&amp;lt;/tex&amp;gt;, так как степень каждой вершины {{---}} &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сложность последней фазы зависит от того, каким алгоритмом граф разбивается на паросочетания. Использовав, например, алгоритм Куна, можно добиться сложности &amp;lt;tex&amp;gt;O(m \cdot M) = O(m \cdot n^3m^3)&amp;lt;/tex&amp;gt;. Итоговая сложность алгоритма {{---}} &amp;lt;tex&amp;gt;O(n^3m^4)&amp;lt;/tex&amp;gt;.&lt;/div&gt;</summary>
		<author><name>217.66.156.102</name></author>	</entry>

	</feed>