<?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=94.25.229.88&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=94.25.229.88&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/94.25.229.88"/>
		<updated>2026-06-10T19:26:48Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9C%D0%B5%D1%82%D0%BE%D0%B4%D1%8B_%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B7%D0%B0%D0%B4%D0%B0%D1%87_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D1%80%D0%B0%D1%81%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D0%B9&amp;diff=27255</id>
		<title>Методы решения задач теории расписаний</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9C%D0%B5%D1%82%D0%BE%D0%B4%D1%8B_%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B7%D0%B0%D0%B4%D0%B0%D1%87_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D1%80%D0%B0%D1%81%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D0%B9&amp;diff=27255"/>
				<updated>2012-11-16T12:51:10Z</updated>
		
		<summary type="html">&lt;p&gt;94.25.229.88: агрумент -&amp;gt; аргумент&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Сведение к другой задаче ==&lt;br /&gt;
При сведении текущей задачи теории расписаний &amp;lt;tex&amp;gt; S &amp;lt;/tex&amp;gt; к какой-то другой &amp;lt;tex&amp;gt; S' &amp;lt;/tex&amp;gt;(не обязательно задаче теории расписаний) необходимо доказать два пункта:&lt;br /&gt;
# Допустимость расписания, построенного с помощью задачи &amp;lt;tex&amp;gt; S' &amp;lt;/tex&amp;gt;, или существование способа его трансформации в допустимое без нарушения оптимальности.&lt;br /&gt;
# Следствие того, что если мы оптимизируем &amp;lt;tex&amp;gt; S' &amp;lt;/tex&amp;gt;, мы также оптимизируем ответ для &amp;lt;tex&amp;gt; S &amp;lt;/tex&amp;gt;.&lt;br /&gt;
Примечание — если требуется полиномиальное время для решения задачи, требуется, чтобы сведение к другой задаче и трансформация расписания в допустимое также происходили за полиномиальное время.&lt;br /&gt;
&lt;br /&gt;
* Задачи класса Open Shop при условии &amp;lt;tex&amp;gt;p_{ij}=1&amp;lt;/tex&amp;gt;, сводятся к задачам равной длительности на параллельных станках.&lt;br /&gt;
* Задачи класса Flow Shop при условии &amp;lt;tex&amp;gt;p_{ij}=1&amp;lt;/tex&amp;gt;, сводятся к задаче на одном станке. &lt;br /&gt;
* Часто в задачах, в которых допускаются прерывания, оптимальный ответ совпадает с соответствующими задачами без прерываний:&lt;br /&gt;
** &amp;lt;tex&amp;gt; P \mid pmtn \mid \sum w_i C_i &amp;lt;/tex&amp;gt;&lt;br /&gt;
** &amp;lt;tex&amp;gt; F2 \mid pmtn \mid C_{max} &amp;lt;/tex&amp;gt;&lt;br /&gt;
* Многие задачи проверки существования расписания сводятся к задаче поиска максимального потока:&lt;br /&gt;
** &amp;lt;tex&amp;gt; Q \mid pmtn, r_i, d_i \mid - &amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Примеры ===&lt;br /&gt;
==== 1 | intree | Sum(w_i C_i) ====&lt;br /&gt;
Предположим, что мы уже умеем решать [[1outtreesumwc|задачу &amp;lt;tex&amp;gt; S' = 1 \mid outtree \mid \sum w_i C_i &amp;lt;/tex&amp;gt;]]&amp;lt;ref&amp;gt;P. Brucker. Scheduling Algorithms (2006), 5th edition, p. 73 &amp;lt;/ref&amp;gt;. Сведем нашу задачу &amp;lt;tex&amp;gt; S &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;, работа &amp;lt;tex&amp;gt; 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; w_i &amp;lt;/tex&amp;gt; на противоположные &amp;lt;tex&amp;gt; w'_i = - w_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Утверждается, что решив соответствующую задачу &amp;lt;tex&amp;gt; S' &amp;lt;/tex&amp;gt; и развернув полученное расписание, мы получим ответ для текущей задачи.&lt;br /&gt;
# Полученное расписание будет допустимым, так как расписание для &amp;lt;tex&amp;gt; S' &amp;lt;/tex&amp;gt; было допустимым, и в нем никакие две работы не пересекались и не прерывались. Развернув, мы не могли нарушить это свойство. Также из-за того, что мы развернули расписание, мы добились того, что все работы выполняются в правильном порядке (в расписании для &amp;lt;tex&amp;gt; S' &amp;lt;/tex&amp;gt; из-за того, что все ребра были развернуты, порядок был нарушен для всех работ). Таким образом, получили что расписание — допустимое.&lt;br /&gt;
# Пусть с помощью задачи &amp;lt;tex&amp;gt; S' &amp;lt;/tex&amp;gt; мы получили последовательность работ &amp;lt;tex&amp;gt; 1 \dots n &amp;lt;/tex&amp;gt;. Распишем по определению значение целевой функции для &amp;lt;tex&amp;gt; S' &amp;lt;/tex&amp;gt;:&lt;br /&gt;
#: &amp;lt;tex&amp;gt;\sum -w_i C_i = \sum \limits_{i=1}^n ( -w_i \sum \limits_{j=1}^i p_j ) = \\&lt;br /&gt;
\sum\limits_{i=1}^n ( w_i \sum\limits_{j=i+1}^n p_j ) - \sum\limits_{i=1}^n w_i \sum \limits_{i=1}^n p_i = \\&lt;br /&gt;
\sum\limits_{i=1}^n ( w_i \sum\limits_{j=i}^n p_j ) - \sum\limits_{i=1}^n w_i p_i - \sum\limits_{i=1}^n w_i \sum \limits_{i=1}^n p_i &amp;lt;/tex&amp;gt;&lt;br /&gt;
#: Заметим, что первое слагаемое соответствует целевой функции &amp;lt;tex&amp;gt; \sum w_i C_i &amp;lt;/tex&amp;gt; для последовательности &amp;lt;tex&amp;gt; n \dots 1 &amp;lt;/tex&amp;gt;, а второе и третье слагаемые — константы, зависящие только от входных данных и не зависящие от перестановки работ. Таким образом, оптимальное значение для &amp;lt;tex&amp;gt; S' &amp;lt;/tex&amp;gt; также минимизирует &amp;lt;tex&amp;gt; S &amp;lt;/tex&amp;gt;, ч.т.д.&lt;br /&gt;
&lt;br /&gt;
==== R || Sum(C_i) ====&lt;br /&gt;
В этой задаче дано &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; работ и &amp;lt;tex&amp;gt; m &amp;lt;/tex&amp;gt; станков, причем для каждого станка длительность выполнения на нем &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-й работы своя и равна &amp;lt;tex&amp;gt; p_{ij} &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим произвольное допустимое расписание для этой задачи. Рассмотрим какую-то станок &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt;, пусть на нем выполняется &amp;lt;tex&amp;gt;n_j&amp;lt;/tex&amp;gt; работ. Тогда вклад этого станка в целевую функцию (не теряя общности, пронумеруем работы на этом станке от &amp;lt;tex&amp;gt;1 &amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;n_j&amp;lt;/tex&amp;gt;) рассчитывается как:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; \sum\limits_{i=1}^{n_j} (p_ij + \sum\limits_{q=1}^{i-1} p_qj) = n_j p_{1j} + (n_j - 1) p_{2j} + \dots + 2 p_{(n_j-1)j} + p_{n_jj} &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;-й с конца. Понятно, что в различных расписаниях &amp;lt;tex&amp;gt; k &amp;lt;/tex&amp;gt; может принимать значения от &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;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; k &amp;lt;/tex&amp;gt; на станке &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt; с помощью задачи [[Поток минимальной стоимости | mincost-maxflow]]. Поместим в левую долю графа работы, в правую долю — пары из станка и коэффициента и проведем соответствующие ребра пропускной способности &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и стоимости &amp;lt;tex&amp;gt;k p_{ij}&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;. Проведем из стока в левую долю ребра стоимости &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; и пропускной способности &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, из правой доли в сток — также ребра стоимости &amp;lt;tex&amp;gt; 0 &amp;lt;/tex&amp;gt; и пропускной способности &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Найдем в этой сети максимальный поток минимальной стоимости. Утверждается, что если ребро &amp;lt;tex&amp;gt; i \to (j, k) &amp;lt;/tex&amp;gt; насыщено потоком, то работа &amp;lt;tex&amp;gt; i &amp;lt;/tex&amp;gt; в оптимальном расписании должна стоять на станке &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt; в позиции &amp;lt;tex&amp;gt; k &amp;lt;/tex&amp;gt; с конца.&lt;br /&gt;
&lt;br /&gt;
# Целевые функции задачи mincost-maxflow и текущей задачи совпадают, так как у ребер между долями пропускная способность 1, а у дополнительных ребер из истока и в сток нулевая стоимость, и они не могут внести вклад в целевую функцию.&lt;br /&gt;
# Расписание, построенное по вышепредставленному способу действительно будет допустимым.&lt;br /&gt;
## Благодаря ограничениям на поток, входящий в левую долю, каждая работа будет назначена только один раз.&lt;br /&gt;
## Благодаря ограничениям на поток, выходящий из правой доли, на каждую позицию будет назначено не более одной работы.&lt;br /&gt;
## Докажем, что не возникает ситуации такой, что существует такая позиция &amp;lt;tex&amp;gt; l &amp;lt;/tex&amp;gt;, что в этой позиции с конца стоит какая-то работа, а в позиции &amp;lt;tex&amp;gt; l - 1 &amp;lt;/tex&amp;gt; с конца — нет (это противоречит определению &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;-й с конца работы). Такая ситуация означает, что ребро &amp;lt;tex&amp;gt; i \to (j, l) &amp;lt;/tex&amp;gt; оказалось насышено потоком, а ребро &amp;lt;tex&amp;gt;i \to (j, l - 1) &amp;lt;/tex&amp;gt; — не насыщено. Но стоимость ребра &amp;lt;tex&amp;gt; i \to (j, l - 1) &amp;lt;/tex&amp;gt; меньше стоимости ребра &amp;lt;tex&amp;gt; i \to (j, l) &amp;lt;/tex&amp;gt;, поэтому можем переместить поток с ребра &amp;lt;tex&amp;gt; i \to (j, l) &amp;lt;/tex&amp;gt; на ребро &amp;lt;tex&amp;gt; i \to (j, l - 1) &amp;lt;/tex&amp;gt;, не нарушив свойства потока и улучшив целевую функцию, что противоречит оптимальности ответа для mincost-maxflow. Следовательно, такой позиции не возникнет и расписание будет допустимым.&lt;br /&gt;
&lt;br /&gt;
==== O | p_ij=1 | Sum(w_i C_i) ====&lt;br /&gt;
Докажем, что оптимальный ответ для &amp;lt;tex&amp;gt; S &amp;lt;/tex&amp;gt; равен оптимальному ответу к задаче &amp;lt;tex&amp;gt;S' = P \mid p_i=m, pmtn \mid \sum w_i C_i &amp;lt;/tex&amp;gt;, где прерывания позволено делать только в целые моменты времени.&lt;br /&gt;
# Целевые функции задач совпадают, поэтому из оптимальности &amp;lt;tex&amp;gt; S' &amp;lt;/tex&amp;gt; следует оптимальность &amp;lt;tex&amp;gt; S &amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Покажем, как получить из расписания &amp;lt;tex&amp;gt; S' &amp;lt;/tex&amp;gt; допустимое расписание для &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; (в расписании для &amp;lt;tex&amp;gt;S'&amp;lt;/tex&amp;gt; допустимость нарушает то, что на одном станке выполняется несколько блоков одной работы):&lt;br /&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; S' &amp;lt;/tex&amp;gt; претендует на выполнение в момент времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;.&lt;br /&gt;
## Раскрасим ребра этого графа в &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; цветов, из теории графов известно, что это можно сделать.&lt;br /&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;k&amp;lt;/tex&amp;gt;, если соответствующее ребро раскрашено в цвет &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
## После данного преобразования мы не изменим значение целевой функции (так как мы переставляем только элементы работ, выполняющихся в один и тот же момент времени). Также расписание станет допустимым для &amp;lt;tex&amp;gt; S &amp;lt;/tex&amp;gt;, так как по определению реберной раскраски, не будет ни одной работы, два единичных блока которых выполняется на одном станке и во все моменты времени не окажется того, что на один станок назначено две работы.&lt;br /&gt;
Чтобы непосредственно решить эту задачу, воспользуемся теоремой о том, что для задачи &amp;lt;tex&amp;gt; P \mid p_i=m, pmtn \mid \sum w_i C_i &amp;lt;/tex&amp;gt; существует оптимальное расписание без прерываний&amp;lt;ref&amp;gt;P. Brucker. Scheduling Algorithms (2006), 5th edition, p. 121 &amp;lt;/ref&amp;gt;. Известно, что для того, чтобы получить оптимальное расписание для такой задачи без прерываний, надо помещать работы по очереди на станки &amp;lt;tex&amp;gt;1 \dots m &amp;lt;/tex&amp;gt; в порядке убывания весов. Длительности у всех работ совпадают, поэтому расписание будет состоять из &amp;lt;tex&amp;gt; \lfloor \frac{n}{m} \rfloor &amp;lt;/tex&amp;gt; блоков по &amp;lt;tex&amp;gt; m &amp;lt;/tex&amp;gt; работ и, возможно, одного неполного блока из &amp;lt;tex&amp;gt; n \mod m &amp;lt;/tex&amp;gt; работ. Таким образом, аналогично задаче &amp;lt;tex&amp;gt; O \mid p_{ij}=1 \mid C_{max}&amp;lt;/tex&amp;gt;, чтобы получить допустимое расписание, можно не строить раскраску графа, а просто циклически сдвигать последовательности работ внутри каждого блока, что позволяет достичь асимптотики &amp;lt;tex&amp;gt; O(m n) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Построение расписания по нижней оценке ==&lt;br /&gt;
Этот метод обычно применим к задачам, в которых целевая функция — &amp;lt;tex&amp;gt; C_{max}&amp;lt;/tex&amp;gt;. Построим какой-то набор нижних ограничений на произвольное расписание для задачи &amp;lt;tex&amp;gt; S &amp;lt;/tex&amp;gt; и возьмем из них максимальное. Затем построим произвольное допустимое расписание, достигающее этой оценки.&lt;br /&gt;
&lt;br /&gt;
С помощью этого метода решаются:&lt;br /&gt;
* &amp;lt;tex&amp;gt; P \mid pmtn \mid C_{max}&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex&amp;gt; R \mid pmtn \mid C_{max}&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex&amp;gt; O \mid p_{ij}=1 \mid C_{max}&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex&amp;gt; Q \mid pmtn \mid C_{max}&amp;lt;/tex&amp;gt; ([[QpmtnCmax |ссылка]])&lt;br /&gt;
&lt;br /&gt;
=== Примеры ===&lt;br /&gt;
==== P | pmtn | C_max ====&lt;br /&gt;
# В допустимом расписании выполнение всех работ не может завершиться раньше одной из них, поэтому &amp;lt;tex&amp;gt; T \ge p_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; Tm &amp;lt;/tex&amp;gt; работы, то есть &amp;lt;tex&amp;gt; \sum\limits_i p_i \le Tm &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; T \ge \frac1m \sum\limits_i p_i &amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Тогда &amp;lt;tex&amp;gt; T_{min} = \max {(\max\limits_i p_i, \frac1m \sum\limits_i p_i)} &amp;lt;/tex&amp;gt;.&lt;br /&gt;
Построим расписание, подходящее под эту границу: будем по очереди заполнять машины работами в произвольном порядке, и если очередная работа не помещается на текущей машине полностью, перенесем ее выходящую за &amp;lt;tex&amp;gt; T_{min} &amp;lt;/tex&amp;gt; часть на следующую машину. Благодаря первому ограничению никакая работа не будет выполняться одновременно на двух станках, а благодаря второму — не останется работы, которую мы не сможем выполнить.&lt;br /&gt;
&lt;br /&gt;
==== O | p_ij=1 | C_max ====&lt;br /&gt;
# В допустимом расписании на каждом станке надо обработать каждую работу, поэтому &amp;lt;tex&amp;gt; T \ge n &amp;lt;/tex&amp;gt;.&lt;br /&gt;
# В допустимом расписании каждую работу нужно обработать на всех станках, причем ее нельзя обрабатывать на двух станках одновременно, поэтому &amp;lt;tex&amp;gt; T \ge m &amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Тогда &amp;lt;tex&amp;gt; T_{min} = \max {(m, n)} &amp;lt;/tex&amp;gt;&lt;br /&gt;
Оптимальное расписание получается циклическими сдвигами последовательности &amp;lt;tex&amp;gt; 1 \dots n &amp;lt;/tex&amp;gt; и выглядит следующим образом:&lt;br /&gt;
* Для &amp;lt;tex&amp;gt; n &amp;lt; m &amp;lt;/tex&amp;gt;:&lt;br /&gt;
         '''0   1   2   ... n-1 n   n+1 ... m-1 m'''&lt;br /&gt;
  '''M_1'''    1   2   3   ... n-1 n   -   ... -   -&lt;br /&gt;
  '''M_2'''    -   1   2   ... n-2 n-1 n   ... -   -&lt;br /&gt;
  '''.'''      ... ... ... ... ... ... ... ... ... ...&lt;br /&gt;
  '''M_m-1'''  -   -   -   ... ... ... ... ... n   -&lt;br /&gt;
  '''M_m'''    -   -   -   ... ... ... ... ... n-1 n&lt;br /&gt;
* Для &amp;lt;tex&amp;gt; n \ge m &amp;lt;/tex&amp;gt;:&lt;br /&gt;
         '''0     1     2   ... k   k+1 ... n-1 n'''&lt;br /&gt;
  '''M_1'''    1     2     3   ... k   k+1 ... n-1 n&lt;br /&gt;
  '''M_2'''    n     1     2   ... k-1 k   ... n-2 n-1&lt;br /&gt;
  '''.'''      ...   ...   ... ... ... ... ... ... ...&lt;br /&gt;
  '''.'''      ...   ...   ... ... ... ... ... ... ...&lt;br /&gt;
  '''M_m'''    n-m+2 n-m+3 ... ... ... ... ... n-m n-m+1&lt;br /&gt;
&lt;br /&gt;
== Бинарный поиск по ответу ==&lt;br /&gt;
Этот способ часто подходит для задач, в которых надо минимизировать &amp;lt;tex&amp;gt;C_{max} &amp;lt;/tex&amp;gt; (если мы умеем решать соответствующую задачу существования расписания), реже для &amp;lt;tex&amp;gt; \sum w_i U_i &amp;lt;/tex&amp;gt;. Важно помнить, что если требуется полиномиальное по &amp;lt;tex&amp;gt; n &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;
* &amp;lt;tex&amp;gt; O \mid p_{ij} = 1 \mid \sum U_I &amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex&amp;gt; O \mid p_{ij} = 1, r_i \mid C_{max} &amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex&amp;gt; Q \mid pmtn, r_i \mid L_{max} &amp;lt;/tex&amp;gt; ([[QpmtnriLmax |ссылка]])&lt;br /&gt;
&lt;br /&gt;
=== Примеры ===&lt;br /&gt;
==== O | p_ij = 1| Sum(U_i) ====&lt;br /&gt;
Перенумеруем работы по неубыванию их дедлайнов, то есть &amp;lt;tex&amp;gt; d_1 \le d_2 \le \dots d_n &amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=&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;
|proof=&lt;br /&gt;
Действительно, если в допустимом расписании все периоды выполнения &amp;lt;tex&amp;gt; t_{iq} &amp;lt;/tex&amp;gt; работы &amp;lt;tex&amp;gt; i &amp;lt;/tex&amp;gt; заменить на периоды выполнения работы &amp;lt;tex&amp;gt; j &amp;gt; i &amp;lt;/tex&amp;gt;, оно останется допустимым, так как &amp;lt;tex&amp;gt; t_{iq} \le d_i \le d_j &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; O(mn) &amp;lt;/tex&amp;gt;&amp;lt;ref&amp;gt;P. Brucker. Scheduling Algorithms (2006), 5th edition, p. 163 &amp;lt;/ref&amp;gt;). Получили решение за &amp;lt;tex&amp;gt; O(mn\log n ) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Жадное построение расписания ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&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; 1 \mid prec \mid f_{max} &amp;lt;/tex&amp;gt; ([[Правило Лаулера|''Lawler's algorithm]])&lt;br /&gt;
* &amp;lt;tex&amp;gt; 1 \mid outtree \mid \sum w_i C_i &amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex&amp;gt; 1 \mid p_i = 1 \mid \sum w_i U_i &amp;lt;/tex&amp;gt; (''Earliest Due Date rule'')&lt;br /&gt;
* &amp;lt;tex&amp;gt; 1 \mid \mid \sum U_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; S &amp;lt;/tex&amp;gt;. Атомарными изменениями в этом решении &amp;lt;tex&amp;gt; S &amp;lt;/tex&amp;gt; будем получать другие допустимые решения &amp;lt;tex&amp;gt; S' &amp;lt;/tex&amp;gt; и докажем, что &amp;lt;tex&amp;gt; f(S) \le f(S') &amp;lt;/tex&amp;gt;. Тогда решение &amp;lt;tex&amp;gt; S &amp;lt;/tex&amp;gt; — оптимально.&lt;br /&gt;
&lt;br /&gt;
Проблема в этих рассуждениях в том, что ими мы доказываем локальную оптимальность алгоритма в решении &amp;lt;tex&amp;gt; S &amp;lt;/tex&amp;gt;. Получение же глобального минимума может потребовать нескольких атомарных изменений в расписании, поэтому доказать оптимальность таким образом в общем случае невозможно. Как ближайшую аналогию, можно привести '''неправильное''' утверждение для произвольной функции &amp;lt;tex&amp;gt; f(\bar x) &amp;lt;/tex&amp;gt; — «если все частные производные &amp;lt;tex&amp;gt; \frac{\partial f}{\partial x_1} \dots \frac{\partial f}{\partial x_n} &amp;lt;/tex&amp;gt; неотрицательны, то в точке &amp;lt;tex&amp;gt; \bar x &amp;lt;/tex&amp;gt; наблюдается глобальный минимум».&lt;br /&gt;
&lt;br /&gt;
=== Правильно ===&lt;br /&gt;
Правильная стратегия (аргумент замены, ''exchange argument'') заключается в рассмотрении текущего решения &amp;lt;tex&amp;gt; S &amp;lt;/tex&amp;gt; и оптимального решения &amp;lt;tex&amp;gt; O &amp;lt;/tex&amp;gt;. Далее предлагается способ модификации &amp;lt;tex&amp;gt; O &amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt; O'&amp;lt;/tex&amp;gt; так, что:&lt;br /&gt;
# &amp;lt;tex&amp;gt; f(O') \le f(O) &amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt; O' &amp;lt;/tex&amp;gt; также оптимально.&lt;br /&gt;
# &amp;lt;tex&amp;gt; O' &amp;lt;/tex&amp;gt; «более похоже» на &amp;lt;tex&amp;gt; S &amp;lt;/tex&amp;gt;, чем на &amp;lt;tex&amp;gt; O &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если такой способ найден, получаем, что какой-то последовательностью модификаций &amp;lt;tex&amp;gt; O \to O_t' \to \dots \to O_1' \to S &amp;lt;/tex&amp;gt; получим &amp;lt;tex&amp;gt; f(S) \le f(O_1') \le \dots \le f(O_t') \le f(O) &amp;lt;/tex&amp;gt;, из чего следует оптимальность &amp;lt;tex&amp;gt; S &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Отношение «более похоже» должно быть [[Отношение порядка | отношением частичного строгого порядка]]. Часто в качестве него можно выбрать отношение «длина наибольшего общего префикса решения &amp;lt;tex&amp;gt; A &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; S &amp;lt;/tex&amp;gt; меньше наибольшего общего префикса решения &amp;lt;tex&amp;gt; B &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; S &amp;lt;/tex&amp;gt;». Тогда если мы сможем увеличить длину наибольшего общего префикса для оптимального решения, не нарушив оптимальности, мы приблизимся к &amp;lt;tex&amp;gt; S &amp;lt;/tex&amp;gt;. Можно выбирать и более сложные отношения, например, в доказательстве оптимальности алгоритма &amp;lt;tex&amp;gt; P \mid \mid \sum w_i C_i &amp;lt;/tex&amp;gt; для решения задачи &amp;lt;tex&amp;gt; P \mid pmtn \mid \sum w_i C_i &amp;lt;/tex&amp;gt; используется отношение «время последнего прерывания больше или количество прерываний меньше».&lt;br /&gt;
&lt;br /&gt;
== Примечания ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>94.25.229.88</name></author>	</entry>

	</feed>