<?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=Qradimir</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=Qradimir"/>
		<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/Qradimir"/>
		<updated>2026-05-19T14:44:02Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=RSumCi&amp;diff=55042</id>
		<title>RSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=RSumCi&amp;diff=55042"/>
				<updated>2016-06-10T10:38:45Z</updated>
		
		<summary type="html">&lt;p&gt;Qradimir: /* Описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi=&amp;quot;200&amp;quot;&amp;gt;R \mid \mid \sum C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=Дано &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;
==Алгоритм==&lt;br /&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; &lt;br /&gt;
\sum\limits_{i=1}^{n_j} \left( p_{ij} + \sum\limits_{q=1}^{i-1} p_{qj} \right) = &lt;br /&gt;
n_j \cdot p_{1j} + (n_j - 1) \cdot p_{2j} + \dots + 2 p_{(n_j-1)j} + p_{n_jj} &lt;br /&gt;
&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; с помощью алгоритма [[Поток минимальной стоимости | поиска максимального потока минимальной стоимости]]. Поместим в левую долю графа работы, в правую долю — пары из станка и коэффициента и проведем соответствующие ребра пропускной способности &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и стоимости &amp;lt;tex&amp;gt;k \cdot 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;. Максимальный поток минимальной стоймости в построенной сети будет ответом на исходную задачу. &lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Eсли ребро &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;
|proof=&lt;br /&gt;
# Целевя функция текущей задачи совпадает со стомостью максимального потока в построенной сети, так как у ребер между долями пропускная способность 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;
&lt;br /&gt;
===Время выполнения===&lt;br /&gt;
Время выполнения алгоритма поиска максимального потока минимальной стоймости равно &amp;lt;tex&amp;gt; \mathcal{O}(V \cdot E^2) &amp;lt;/tex&amp;gt;. Количество вершин в получаемой сети равно &amp;lt;tex&amp;gt; \mathcal{O}(m \cdot n) &amp;lt;/tex&amp;gt;. Количество ребер в сети равно &amp;lt;tex&amp;gt; \mathcal{O}(m \cdot n^2) &amp;lt;/tex&amp;gt;. Следовательно, ассимптотика алгоритма равна &amp;lt;tex&amp;gt; \mathcal{O}(m^3 \cdot n^5) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
* [[Поток минимальной стоимости]]&lt;br /&gt;
* [[Методы решения задач теории расписаний]]&lt;br /&gt;
* [[PSumCi|&amp;lt;tex&amp;gt;P \mid \mid \sum C_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[QSumCi|&amp;lt;tex&amp;gt;Q \mid \mid \sum C_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Qradimir</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=RSumCi&amp;diff=55041</id>
		<title>RSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=RSumCi&amp;diff=55041"/>
				<updated>2016-06-10T10:36:14Z</updated>
		
		<summary type="html">&lt;p&gt;Qradimir: /* Описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi=&amp;quot;200&amp;quot;&amp;gt;R \mid \mid \sum C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=Дано &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;
==Алгоритм==&lt;br /&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; &lt;br /&gt;
\sum\limits_{i=1}^{n_j} \left( p_{ij} + \sum\limits_{q=1}^{i-1} p_{qj} \right) = &lt;br /&gt;
n_j \cdot p_{1j} + (n_j - 1) \cdot p_{2j} + \dots + 2 p_{(n_j-1)j} + p_{n_jj} &lt;br /&gt;
&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; с помощью алгоритма [[Поток минимальной стоимости | поиска максимального потока минимальной стоимости]]. Поместим в левую долю графа работы, в правую долю — пары из станка и коэффициента и проведем соответствующие ребра пропускной способности &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и стоимости &amp;lt;tex&amp;gt;k \cdot 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;. Максимальный поток минимальной стоймости в построенной сети будет ответом на исходную задачу. &lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Eсли ребро &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;
|proof=&lt;br /&gt;
# Целевя функция текущей задачи совпадает со стомостью максимального потока в построенной сети, так как у ребер между долями пропускная способность 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;
&lt;br /&gt;
===Время выполнения===&lt;br /&gt;
Время выполнения алгоритма поиска максимального потока минимальной стоймости равно &amp;lt;tex&amp;gt; \mathcal{O}(V \cdot E^2) &amp;lt;/tex&amp;gt;. Количество вершин в получаемой сети равно &amp;lt;tex&amp;gt; \mathcal{O}(m \cdot n) &amp;lt;/tex&amp;gt;. Количество ребер в сети равно &amp;lt;tex&amp;gt; \mathcal{O}(m \cdot n^2) &amp;lt;/tex&amp;gt;. Следовательно, ассимптотика алгоритма равна &amp;lt;tex&amp;gt; \mathcal{O}(m^3 \cdot n^5) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
* [[Поток минимальной стоимости]]&lt;br /&gt;
* [[Методы решения задач теории расписаний]]&lt;br /&gt;
* [[PSumCi|&amp;lt;tex&amp;gt;P \mid \mid \sum C_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[QSumCi|&amp;lt;tex&amp;gt;Q \mid \mid \sum C_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Qradimir</name></author>	</entry>

	<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=54838</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=54838"/>
				<updated>2016-06-07T15:04:43Z</updated>
		
		<summary type="html">&lt;p&gt;Qradimir: /* Жадное построение расписания */&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;
С помощью этого метода решаются:&lt;br /&gt;
* Задачи класса [[Классификация задач|Open Shop]] при условии &amp;lt;tex&amp;gt;p_{ij}=1&amp;lt;/tex&amp;gt; можно свести к задачам равной длительности на параллельных станках:&lt;br /&gt;
*:[[Opij1Sumwc|&amp;lt;tex&amp;gt; O \mid p_{ij} = 1 \mid \sum w_i C_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; &amp;lt;ref&amp;gt;Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 161&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Задачи класса [[Классификация задач|Flow Shop]] при условии &amp;lt;tex&amp;gt;p_{ij}=1&amp;lt;/tex&amp;gt; можно свести к задаче на одном станке:&lt;br /&gt;
*:[[Fpij1sumwu|&amp;lt;tex&amp;gt; F \mid p_{ij} = 1 \mid \sum w_i U_i &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; &amp;lt;ref&amp;gt;Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 121&amp;lt;/ref&amp;gt;&lt;br /&gt;
*:[[Flow shop|&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\mid L_{max} &amp;lt;/tex&amp;gt; &amp;lt;ref&amp;gt;Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 129-133&amp;lt;/ref&amp;gt;&lt;br /&gt;
*:[[RSumCi|&amp;lt;tex&amp;gt; R \mid \mid \sum C_i &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* Некоторые задачи сводятся к другим похожим задачам теории расписаний путем преобразования их расписаний:&lt;br /&gt;
*:[[1outtreesumwc|&amp;lt;tex&amp;gt; 1 \mid intree \mid \sum w_i C_i &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;. &lt;br /&gt;
Обычно построение расписания по нижней оценке происходит в два этапа:&lt;br /&gt;
# Построение некоторого набора нижних ограничений на произвольное расписание для задачи &amp;lt;tex&amp;gt; S &amp;lt;/tex&amp;gt;. &lt;br /&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; &amp;lt;ref&amp;gt;Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 108&amp;lt;/ref&amp;gt;&lt;br /&gt;
* &amp;lt;tex&amp;gt; R \mid pmtn \mid C_{max}&amp;lt;/tex&amp;gt; &amp;lt;ref&amp;gt;Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 137-139&amp;lt;/ref&amp;gt;&lt;br /&gt;
* [[Opij1Cmax|&amp;lt;tex&amp;gt; O \mid p_{ij}=1 \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[QpmtnCmax|&amp;lt;tex&amp;gt; Q \mid pmtn \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Ниже будет рассмотрен частный пример решения задачи подобным образом:&lt;br /&gt;
=== P | pmtn | C_max ===&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Имеется &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;
Найдем набор ограничений на значение &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;
# В допустимом расписании выполнение всех работ не может завершиться раньше одной из них, поэтому &amp;lt;tex&amp;gt; C_{max} \geqslant p_i &amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Если все станки работали время &amp;lt;tex&amp;gt; C_{max} &amp;lt;/tex&amp;gt;, на них могло выполниться не больше &amp;lt;tex&amp;gt; C_{max} \cdot m &amp;lt;/tex&amp;gt; работы, то есть &amp;lt;tex&amp;gt; \sum\limits_{i=1}^n p_i \leqslant C_{max} \cdot m &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; C_{max} \geqslant \dfrac1m \sum\limits_{i=1}^n p_i &amp;lt;/tex&amp;gt;.&lt;br /&gt;
Из этих ограничений следует, что &amp;lt;tex&amp;gt; C_{max} = \max {\left( \max\limits_{i=1 \hdots n} p_i,~ \dfrac1m \sum\limits_{i=1}^n p_i \right)} &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Построим расписание, подходящее под эту границу: будем по очереди заполнять машины работами в произвольном порядке, и если очередная работа не помещается на текущей машине полностью, перенесем ее выходящую за &amp;lt;tex&amp;gt; C_{max} &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; \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;
[[QpmtnriLmax|&amp;lt;tex&amp;gt; Q \mid pmtn, r_i \mid 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;
С помощью этого метода решаются:&lt;br /&gt;
* [[Правило Лаулера|&amp;lt;tex&amp;gt; 1 \mid prec \mid f_{max} &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1outtreesumwc|&amp;lt;tex&amp;gt; 1 \mid outtree \mid \sum w_i C_i &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1pi1sumwu|&amp;lt;tex&amp;gt; 1 \mid p_i = 1 \mid \sum w_i U_i &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1sumu|&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) \leqslant 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; \dfrac{\partial f}{\partial x_1} \dots \dfrac{\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') \leqslant 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) \leqslant f(O_1') \leqslant \dots \leqslant f(O_t') \leqslant 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;
* [[Правило Лаулера]]&lt;br /&gt;
* [[Flow shop]]&lt;br /&gt;
* [[Opi1sumu|&amp;lt;tex&amp;gt; O \mid p_{ij} = 1 \mid \sum U_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;
* Peter Brucker «Scheduling Algorithms», fifth edition, Springer ISBN 978-3-540-69515-8&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Qradimir</name></author>	</entry>

	<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=54837</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=54837"/>
				<updated>2016-06-07T15:04:10Z</updated>
		
		<summary type="html">&lt;p&gt;Qradimir: /* Жадное построение расписания */&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;
С помощью этого метода решаются:&lt;br /&gt;
* Задачи класса [[Классификация задач|Open Shop]] при условии &amp;lt;tex&amp;gt;p_{ij}=1&amp;lt;/tex&amp;gt; можно свести к задачам равной длительности на параллельных станках:&lt;br /&gt;
*:[[Opij1Sumwc|&amp;lt;tex&amp;gt; O \mid p_{ij} = 1 \mid \sum w_i C_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; &amp;lt;ref&amp;gt;Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 161&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Задачи класса [[Классификация задач|Flow Shop]] при условии &amp;lt;tex&amp;gt;p_{ij}=1&amp;lt;/tex&amp;gt; можно свести к задаче на одном станке:&lt;br /&gt;
*:[[Fpij1sumwu|&amp;lt;tex&amp;gt; F \mid p_{ij} = 1 \mid \sum w_i U_i &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; &amp;lt;ref&amp;gt;Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 121&amp;lt;/ref&amp;gt;&lt;br /&gt;
*:[[Flow shop|&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\mid L_{max} &amp;lt;/tex&amp;gt; &amp;lt;ref&amp;gt;Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 129-133&amp;lt;/ref&amp;gt;&lt;br /&gt;
*:[[RSumCi|&amp;lt;tex&amp;gt; R \mid \mid \sum C_i &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* Некоторые задачи сводятся к другим похожим задачам теории расписаний путем преобразования их расписаний:&lt;br /&gt;
*:[[1outtreesumwc|&amp;lt;tex&amp;gt; 1 \mid intree \mid \sum w_i C_i &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;. &lt;br /&gt;
Обычно построение расписания по нижней оценке происходит в два этапа:&lt;br /&gt;
# Построение некоторого набора нижних ограничений на произвольное расписание для задачи &amp;lt;tex&amp;gt; S &amp;lt;/tex&amp;gt;. &lt;br /&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; &amp;lt;ref&amp;gt;Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 108&amp;lt;/ref&amp;gt;&lt;br /&gt;
* &amp;lt;tex&amp;gt; R \mid pmtn \mid C_{max}&amp;lt;/tex&amp;gt; &amp;lt;ref&amp;gt;Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 137-139&amp;lt;/ref&amp;gt;&lt;br /&gt;
* [[Opij1Cmax|&amp;lt;tex&amp;gt; O \mid p_{ij}=1 \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[QpmtnCmax|&amp;lt;tex&amp;gt; Q \mid pmtn \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Ниже будет рассмотрен частный пример решения задачи подобным образом:&lt;br /&gt;
=== P | pmtn | C_max ===&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Имеется &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;
Найдем набор ограничений на значение &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;
# В допустимом расписании выполнение всех работ не может завершиться раньше одной из них, поэтому &amp;lt;tex&amp;gt; C_{max} \geqslant p_i &amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Если все станки работали время &amp;lt;tex&amp;gt; C_{max} &amp;lt;/tex&amp;gt;, на них могло выполниться не больше &amp;lt;tex&amp;gt; C_{max} \cdot m &amp;lt;/tex&amp;gt; работы, то есть &amp;lt;tex&amp;gt; \sum\limits_{i=1}^n p_i \leqslant C_{max} \cdot m &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; C_{max} \geqslant \dfrac1m \sum\limits_{i=1}^n p_i &amp;lt;/tex&amp;gt;.&lt;br /&gt;
Из этих ограничений следует, что &amp;lt;tex&amp;gt; C_{max} = \max {\left( \max\limits_{i=1 \hdots n} p_i,~ \dfrac1m \sum\limits_{i=1}^n p_i \right)} &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Построим расписание, подходящее под эту границу: будем по очереди заполнять машины работами в произвольном порядке, и если очередная работа не помещается на текущей машине полностью, перенесем ее выходящую за &amp;lt;tex&amp;gt; C_{max} &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; \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;
[[QpmtnriLmax|&amp;lt;tex&amp;gt; Q \mid pmtn, r_i \mid 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;
С помощью этого метода решаются:&lt;br /&gt;
* [[Правило Лаулера|&amp;lt;tex&amp;gt; 1 \mid prec \mid f_{max} &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1outtreesumwc|&amp;lt;tex&amp;gt; 1 \mid outtree \mid \sum w_i C_i &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1pi1sumwu|&amp;lt;tex&amp;gt; 1 \mid p_i = 1 \mid \sum w_i U_i &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1sumu|&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) \leqslant 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; \dfrac{\partial f}{\partial x_1} \dots \dfrac{\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') \leqslant 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) \leqslant f(O_1') \leqslant \dots \leqslant f(O_t') \leqslant 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;
* [[Правило Лаулера]]&lt;br /&gt;
* [[Flow shop]]&lt;br /&gt;
* [[Opi1sumu|&amp;lt;tex&amp;gt; O \mid p_{ij} = 1 \mid \sum U_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;
* Peter Brucker «Scheduling Algorithms», fifth edition, Springer ISBN 978-3-540-69515-8&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Qradimir</name></author>	</entry>

	<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=54836</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=54836"/>
				<updated>2016-06-07T15:02:13Z</updated>
		
		<summary type="html">&lt;p&gt;Qradimir: Фиксы&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;
С помощью этого метода решаются:&lt;br /&gt;
* Задачи класса [[Классификация задач|Open Shop]] при условии &amp;lt;tex&amp;gt;p_{ij}=1&amp;lt;/tex&amp;gt; можно свести к задачам равной длительности на параллельных станках:&lt;br /&gt;
*:[[Opij1Sumwc|&amp;lt;tex&amp;gt; O \mid p_{ij} = 1 \mid \sum w_i C_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; &amp;lt;ref&amp;gt;Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 161&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Задачи класса [[Классификация задач|Flow Shop]] при условии &amp;lt;tex&amp;gt;p_{ij}=1&amp;lt;/tex&amp;gt; можно свести к задаче на одном станке:&lt;br /&gt;
*:[[Fpij1sumwu|&amp;lt;tex&amp;gt; F \mid p_{ij} = 1 \mid \sum w_i U_i &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; &amp;lt;ref&amp;gt;Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 121&amp;lt;/ref&amp;gt;&lt;br /&gt;
*:[[Flow shop|&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\mid L_{max} &amp;lt;/tex&amp;gt; &amp;lt;ref&amp;gt;Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 129-133&amp;lt;/ref&amp;gt;&lt;br /&gt;
*:[[RSumCi|&amp;lt;tex&amp;gt; R \mid \mid \sum C_i &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* Некоторые задачи сводятся к другим похожим задачам теории расписаний путем преобразования их расписаний:&lt;br /&gt;
*:[[1outtreesumwc|&amp;lt;tex&amp;gt; 1 \mid intree \mid \sum w_i C_i &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;. &lt;br /&gt;
Обычно построение расписания по нижней оценке происходит в два этапа:&lt;br /&gt;
# Построение некоторого набора нижних ограничений на произвольное расписание для задачи &amp;lt;tex&amp;gt; S &amp;lt;/tex&amp;gt;. &lt;br /&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; &amp;lt;ref&amp;gt;Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 108&amp;lt;/ref&amp;gt;&lt;br /&gt;
* &amp;lt;tex&amp;gt; R \mid pmtn \mid C_{max}&amp;lt;/tex&amp;gt; &amp;lt;ref&amp;gt;Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 137-139&amp;lt;/ref&amp;gt;&lt;br /&gt;
* [[Opij1Cmax|&amp;lt;tex&amp;gt; O \mid p_{ij}=1 \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[QpmtnCmax|&amp;lt;tex&amp;gt; Q \mid pmtn \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Ниже будет рассмотрен частный пример решения задачи подобным образом:&lt;br /&gt;
=== P | pmtn | C_max ===&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Имеется &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;
Найдем набор ограничений на значение &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;
# В допустимом расписании выполнение всех работ не может завершиться раньше одной из них, поэтому &amp;lt;tex&amp;gt; C_{max} \geqslant p_i &amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Если все станки работали время &amp;lt;tex&amp;gt; C_{max} &amp;lt;/tex&amp;gt;, на них могло выполниться не больше &amp;lt;tex&amp;gt; C_{max} \cdot m &amp;lt;/tex&amp;gt; работы, то есть &amp;lt;tex&amp;gt; \sum\limits_{i=1}^n p_i \leqslant C_{max} \cdot m &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; C_{max} \geqslant \dfrac1m \sum\limits_{i=1}^n p_i &amp;lt;/tex&amp;gt;.&lt;br /&gt;
Из этих ограничений следует, что &amp;lt;tex&amp;gt; C_{max} = \max {\left( \max\limits_{i=1 \hdots n} p_i,~ \dfrac1m \sum\limits_{i=1}^n p_i \right)} &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Построим расписание, подходящее под эту границу: будем по очереди заполнять машины работами в произвольном порядке, и если очередная работа не помещается на текущей машине полностью, перенесем ее выходящую за &amp;lt;tex&amp;gt; C_{max} &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; \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;
[[QpmtnriLmax|&amp;lt;tex&amp;gt; Q \mid pmtn, r_i \mid 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;
С помощью этого метода решаются:&lt;br /&gt;
* [[Правило Лаулера|&amp;lt;tex&amp;gt; 1 \mid prec \mid f_{max} &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1outtreesumwc|&amp;lt;tex&amp;gt; 1 \mid outtree \mid \sum w_i C_i &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1pi1sumwu|&amp;lt;tex&amp;gt; 1 \mid p_i = 1 \mid \sum w_i U_i &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1sumu|&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) \leqslant 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; \dfrac{\partial f}{\partial x_1} \dots \dfrac{\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') \leqslant 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) \leqslant f(O_1') \leqslant \dots \leqslant f(O_t') \leqslant 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;
* [[Правило Лаулера]]&lt;br /&gt;
* [[Flow shop]]&lt;br /&gt;
* [[Opi1sumu|&amp;lt;tex&amp;gt; O \mid p_{ij} = 1 \mid \sum U_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;
* Peter Brucker «Scheduling Algorithms», fifth edition, Springer ISBN 978-3-540-69515-8&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Qradimir</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Opij1Cmax&amp;diff=54835</id>
		<title>Opij1Cmax</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Opij1Cmax&amp;diff=54835"/>
				<updated>2016-06-07T14:24:53Z</updated>
		
		<summary type="html">&lt;p&gt;Qradimir: Таблица в техе&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;O \mid p_{ij} = 1 \mid C_{max}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; одинаковых станков, которые работают параллельно и &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ, котороые необходимо выполнить в произвольном порядке на всех станках. Время выполнения каждой работы на любом станке одинаково и равно 1. Необходимо минимизировать время выполнения всех работ.&lt;br /&gt;
}}&lt;br /&gt;
==Алгоритм==&lt;br /&gt;
&lt;br /&gt;
===Описание алгоритма===&lt;br /&gt;
Минимальное значение &amp;lt;tex&amp;gt; C_{max} &amp;lt;/tex&amp;gt; упирается в следующие ограничения:&lt;br /&gt;
# В допустимом расписании на каждом станке надо обработать каждую работу, поэтому &amp;lt;tex&amp;gt; C_{max} \geqslant  n &amp;lt;/tex&amp;gt;.&lt;br /&gt;
# В допустимом расписании каждую работу нужно обработать на всех станках, причем ее нельзя обрабатывать на двух станках одновременно, поэтому &amp;lt;tex&amp;gt; C_{max} \geqslant m &amp;lt;/tex&amp;gt;.&lt;br /&gt;
Тогда &amp;lt;tex&amp;gt; C_{max} = \max{(m, n)} &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В случае &amp;lt;tex&amp;gt; n \geqslant m &amp;lt;/tex&amp;gt; оптимальное расписание строится циклическими сдвигами последовательности &amp;lt;tex&amp;gt; 1 \dots n &amp;lt;/tex&amp;gt; и выглядит следующим образом:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!              &lt;br /&gt;
!| &amp;lt;tex&amp;gt;\textbf1&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;\textbf2&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;\textbf3&amp;lt;/tex&amp;gt; ||&amp;lt;tex&amp;gt;\bf{\hdots}&amp;lt;/tex&amp;gt;|| &amp;lt;tex&amp;gt;\textbf{n - 1}&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;\textbf{n}&amp;lt;/tex&amp;gt;&lt;br /&gt;
|- style=&amp;quot;text-align:center;&amp;quot;&lt;br /&gt;
!&amp;lt;tex&amp;gt;\bf{M_1}&amp;lt;/tex&amp;gt;&lt;br /&gt;
|| &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt; ||&amp;lt;tex&amp;gt;\hdots&amp;lt;/tex&amp;gt;|| &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;&lt;br /&gt;
|- style=&amp;quot;text-align:center;&amp;quot;&lt;br /&gt;
!&amp;lt;tex&amp;gt;\bf{M_2}&amp;lt;/tex&amp;gt;&lt;br /&gt;
|| &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; ||&amp;lt;tex&amp;gt;\hdots&amp;lt;/tex&amp;gt;|| &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
|- style=&amp;quot;text-align:center;&amp;quot;&lt;br /&gt;
!&amp;lt;tex&amp;gt;\bf{M_3}&amp;lt;/tex&amp;gt;&lt;br /&gt;
|| &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; ||&amp;lt;tex&amp;gt;\hdots&amp;lt;/tex&amp;gt;|| &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt;&lt;br /&gt;
|- style=&amp;quot;text-align:center;&amp;quot;&lt;br /&gt;
!&amp;lt;tex&amp;gt;\bf{\vdots}&amp;lt;/tex&amp;gt;             &lt;br /&gt;
||&amp;lt;tex&amp;gt;\vdots&amp;lt;/tex&amp;gt;||&amp;lt;tex&amp;gt;\vdots&amp;lt;/tex&amp;gt;||&amp;lt;tex&amp;gt;\vdots&amp;lt;/tex&amp;gt;||&amp;lt;tex&amp;gt;\ddots&amp;lt;/tex&amp;gt;||&amp;lt;tex&amp;gt;\vdots&amp;lt;/tex&amp;gt;||&amp;lt;tex&amp;gt;\vdots&amp;lt;/tex&amp;gt; &lt;br /&gt;
|- style=&amp;quot;text-align:center;&amp;quot;&lt;br /&gt;
!&amp;lt;tex&amp;gt;\bf{M_m}&amp;lt;/tex&amp;gt;&lt;br /&gt;
|| &amp;lt;tex&amp;gt;n - m + 2&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;n - m + 3&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;n - m + 4&amp;lt;/tex&amp;gt; ||&amp;lt;tex&amp;gt;\hdots&amp;lt;/tex&amp;gt;|| &amp;lt;tex&amp;gt;n - m&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;n - m + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt; n &amp;lt; m &amp;lt;/tex&amp;gt;, добавим &amp;lt;tex&amp;gt; m - n &amp;lt;/tex&amp;gt; фиктивных работ с номерами &amp;lt;tex&amp;gt; n + 1 \dots m &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; \mathcal{O}(1) &amp;lt;/tex&amp;gt; времени.&lt;br /&gt;
Построение расписания сводится к заполнению матрицы размером &amp;lt;tex&amp;gt; m \times \max{(m, n)} &amp;lt;/tex&amp;gt; и выполняется за &amp;lt;tex&amp;gt; \mathcal{O}(m \dot (m + n)) &amp;lt;/tex&amp;gt; времени.&lt;br /&gt;
&lt;br /&gt;
==См. также.==&lt;br /&gt;
* [[Методы решения задач теории расписаний]]&lt;br /&gt;
* [[O2Cmax|&amp;lt;tex&amp;gt; O2 \mid \mid C_{max} &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[QpmtnCmax|&amp;lt;tex&amp;gt; Q \mid pmtn \mid C_{max} &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1Sumwc|&amp;lt;tex&amp;gt; O \mid p_{ij} = 1 \mid \sum w_i C_i &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Qradimir</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=RSumCi&amp;diff=54811</id>
		<title>RSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=RSumCi&amp;diff=54811"/>
				<updated>2016-06-07T02:47:03Z</updated>
		
		<summary type="html">&lt;p&gt;Qradimir: точки&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi=&amp;quot;200&amp;quot;&amp;gt;R \mid \mid \sum C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=Дано &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;
==Алгоритм==&lt;br /&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; &lt;br /&gt;
\sum\limits_{i=1}^{n_j} \left( p_ij + \sum\limits_{q=1}^{i-1} p_qj \right) = &lt;br /&gt;
n_j \cdot p_{1j} + (n_j - 1) \cdot p_{2j} + \dots + 2 p_{(n_j-1)j} + p_{n_jj} &lt;br /&gt;
&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; с помощью алгоритма [[Поток минимальной стоимости | поиска максимального потока минимальной стоимости]]. Поместим в левую долю графа работы, в правую долю — пары из станка и коэффициента и проведем соответствующие ребра пропускной способности &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и стоимости &amp;lt;tex&amp;gt;k \cdot 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;. Максимальный поток минимальной стоймости в построенной сети будет ответом на исходную задачу. &lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Eсли ребро &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;
|proof=&lt;br /&gt;
# Целевя функция текущей задачи совпадает со стомостью максимального потока в построенной сети, так как у ребер между долями пропускная способность 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;
&lt;br /&gt;
===Время выполнения===&lt;br /&gt;
Время выполнения алгоритма поиска максимального потока минимальной стоймости равно &amp;lt;tex&amp;gt; \mathcal{O}(V \cdot E^2) &amp;lt;/tex&amp;gt;. Количество вершин в получаемой сети равно &amp;lt;tex&amp;gt; \mathcal{O}(m \cdot n) &amp;lt;/tex&amp;gt;. Количество ребер в сети равно &amp;lt;tex&amp;gt; \mathcal{O}(m \cdot n^2) &amp;lt;/tex&amp;gt;. Следовательно, ассимптотика алгоритма равна &amp;lt;tex&amp;gt; \mathcal{O}(m^3 \cdot n^5) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
* [[Поток минимальной стоимости]]&lt;br /&gt;
* [[Методы решения задач теории расписаний]]&lt;br /&gt;
* [[PSumCi|&amp;lt;tex&amp;gt;P \mid \mid \sum C_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[QSumCi|&amp;lt;tex&amp;gt;Q \mid \mid \sum C_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Qradimir</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=RSumCi&amp;diff=54810</id>
		<title>RSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=RSumCi&amp;diff=54810"/>
				<updated>2016-06-07T02:46:27Z</updated>
		
		<summary type="html">&lt;p&gt;Qradimir: точки&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi=&amp;quot;200&amp;quot;&amp;gt;R \mid \mid \sum C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=Дано &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;
==Алгоритм==&lt;br /&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; &lt;br /&gt;
\sum\limits_{i=1}^{n_j} \left( p_ij + \sum\limits_{q=1}^{i-1} \cdot p_qj \right) = &lt;br /&gt;
n_j \cdot p_{1j} + (n_j - 1) \cdot p_{2j} + \dots + 2 p_{(n_j-1)j} + p_{n_jj} &lt;br /&gt;
&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; с помощью алгоритма [[Поток минимальной стоимости | поиска максимального потока минимальной стоимости]]. Поместим в левую долю графа работы, в правую долю — пары из станка и коэффициента и проведем соответствующие ребра пропускной способности &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и стоимости &amp;lt;tex&amp;gt;k \cdot 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;. Максимальный поток минимальной стоймости в построенной сети будет ответом на исходную задачу. &lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Eсли ребро &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;
|proof=&lt;br /&gt;
# Целевя функция текущей задачи совпадает со стомостью максимального потока в построенной сети, так как у ребер между долями пропускная способность 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;
&lt;br /&gt;
===Время выполнения===&lt;br /&gt;
Время выполнения алгоритма поиска максимального потока минимальной стоймости равно &amp;lt;tex&amp;gt; \mathcal{O}(V \cdot E^2) &amp;lt;/tex&amp;gt;. Количество вершин в получаемой сети равно &amp;lt;tex&amp;gt; \mathcal{O}(m \cdot n) &amp;lt;/tex&amp;gt;. Количество ребер в сети равно &amp;lt;tex&amp;gt; \mathcal{O}(m \cdot n^2) &amp;lt;/tex&amp;gt;. Следовательно, ассимптотика алгоритма равна &amp;lt;tex&amp;gt; \mathcal{O}(m^3 \cdot n^5) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
* [[Поток минимальной стоимости]]&lt;br /&gt;
* [[Методы решения задач теории расписаний]]&lt;br /&gt;
* [[PSumCi|&amp;lt;tex&amp;gt;P \mid \mid \sum C_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[QSumCi|&amp;lt;tex&amp;gt;Q \mid \mid \sum C_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Qradimir</name></author>	</entry>

	<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=54809</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=54809"/>
				<updated>2016-06-07T02:38:25Z</updated>
		
		<summary type="html">&lt;p&gt;Qradimir: Фиксы&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;
С помощью этого метода решаются:&lt;br /&gt;
* Некоторые задачи класса Open Shop при условии &amp;lt;tex&amp;gt;p_{ij}=1&amp;lt;/tex&amp;gt; сводятся к задачам равной длительности на параллельных станках.&lt;br /&gt;
*:[[Opij1Sumwc|&amp;lt;tex&amp;gt; O \mid p_{ij} = 1 \mid \sum w_i C_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; &amp;lt;ref&amp;gt;Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 161&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Некоторые задачи класса Flow Shop при условии &amp;lt;tex&amp;gt;p_{ij}=1&amp;lt;/tex&amp;gt; сводятся к задаче на одном станке. &lt;br /&gt;
*:[[Fpij1sumwu|&amp;lt;tex&amp;gt; F \mid p_{ij} = 1 \mid \sum w_i U_i &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; &amp;lt;ref&amp;gt;Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 121&amp;lt;/ref&amp;gt;&lt;br /&gt;
*:[[Flow shop|&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\mid L_{max} &amp;lt;/tex&amp;gt; &amp;lt;ref&amp;gt;Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 129-133&amp;lt;/ref&amp;gt;&lt;br /&gt;
*:[[RSumCi|&amp;lt;tex&amp;gt; R \mid \mid \sum C_i &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* Некоторые задачи сводятся к другим похожим задачам теории расписаний путем преобразования их расписаний:&lt;br /&gt;
*:[[1outtreesumwc|&amp;lt;tex&amp;gt; 1 \mid intree \mid \sum w_i C_i &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;. &lt;br /&gt;
Обычно построение расписания по нижней оценке происходит в два этапа:&lt;br /&gt;
# Построение некоторого набора нижних ограничений на произвольное расписание для задачи &amp;lt;tex&amp;gt; S &amp;lt;/tex&amp;gt;. &lt;br /&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; &amp;lt;ref&amp;gt;Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 108&amp;lt;/ref&amp;gt;&lt;br /&gt;
* &amp;lt;tex&amp;gt; R \mid pmtn \mid C_{max}&amp;lt;/tex&amp;gt; &amp;lt;ref&amp;gt;Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 137-139&amp;lt;/ref&amp;gt;&lt;br /&gt;
* [[Opij1Cmax|&amp;lt;tex&amp;gt; O \mid p_{ij}=1 \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[QpmtnCmax|&amp;lt;tex&amp;gt; Q \mid pmtn \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=== P | pmtn | C_max ===&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;
# В допустимом расписании выполнение всех работ не может завершиться раньше одной из них, поэтому &amp;lt;tex&amp;gt; C_{max} \geqslant p_i &amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Если все станки работали время &amp;lt;tex&amp;gt; C_{max} &amp;lt;/tex&amp;gt;, на них могло выполниться не больше &amp;lt;tex&amp;gt; C_{max} \cdot m &amp;lt;/tex&amp;gt; работы, то есть &amp;lt;tex&amp;gt; \sum\limits_i p_i \leqslant C_{max} \cdot m &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; C_{max} \geqslant \dfrac1m \sum\limits_i p_i &amp;lt;/tex&amp;gt;.&lt;br /&gt;
Из этих ограничений следует, что &amp;lt;tex&amp;gt; C_{max} = \max {\left( \max\limits_i p_i; \dfrac1m \sum\limits_i p_i \right)} &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Построим расписание, подходящее под эту границу: будем по очереди заполнять машины работами в произвольном порядке, и если очередная работа не помещается на текущей машине полностью, перенесем ее выходящую за &amp;lt;tex&amp;gt; C_{max} &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; \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;
[[QpmtnriLmax|&amp;lt;tex&amp;gt; Q \mid pmtn, r_i \mid L_{max} &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;
* [[Правило Лаулера|&amp;lt;tex&amp;gt; 1 \mid prec \mid f_{max} &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1outtreesumwc|&amp;lt;tex&amp;gt; 1 \mid outtree \mid \sum w_i C_i &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1pi1sumwu|&amp;lt;tex&amp;gt; 1 \mid p_i = 1 \mid \sum w_i U_i &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1sumu|&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) \leqslant 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; \dfrac{\partial f}{\partial x_1} \dots \dfrac{\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') \leqslant 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) \leqslant f(O_1') \leqslant \dots \leqslant f(O_t') \leqslant 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;
* [[Правило Лаулера]]&lt;br /&gt;
* [[Flow shop]]&lt;br /&gt;
* [[Opi1sumu|&amp;lt;tex&amp;gt; O \mid p_{ij} = 1 \mid \sum U_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;
* Peter Brucker «Scheduling Algorithms», fifth edition, Springer ISBN 978-3-540-69515-8&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Qradimir</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Opij1Sumwc&amp;diff=54808</id>
		<title>Opij1Sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Opij1Sumwc&amp;diff=54808"/>
				<updated>2016-06-07T01:18:19Z</updated>
		
		<summary type="html">&lt;p&gt;Qradimir: Скобки, см. также&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi=&amp;quot;200&amp;quot;&amp;gt;O \mid p_{ij}=1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; одинаковых станков, которые работают параллельно и &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ, котороые необходимо выполнить в произвольном порядке на всех станках. Время выполнения каждой работы на любом станке одинаково и равно 1. Необходимо минимизировать взвешенную сумму времен завершения работ. &lt;br /&gt;
}}&lt;br /&gt;
==Алгоритм==&lt;br /&gt;
&lt;br /&gt;
===Описание алгоритма===&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Оптимальный ответ для &amp;lt;tex&amp;gt;S = O \mid p_{ij}=1 \mid \sum w_i C_i&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;
|proof=Для доказательства этого утверждения необходимо показать то, что из оптимальности &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; 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;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;
}}&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; \left\lfloor \dfrac{n}{m} \right\rfloor &amp;lt;/tex&amp;gt; блоков по &amp;lt;tex&amp;gt; m &amp;lt;/tex&amp;gt; работ и, возможно, одного неполного блока из &amp;lt;tex&amp;gt; n \bmod m &amp;lt;/tex&amp;gt; работ. Таким образом, аналогично задаче &amp;lt;tex&amp;gt; O \mid p_{ij}=1 \mid C_{max}&amp;lt;/tex&amp;gt;, чтобы получить допустимое расписание, можно не строить раскраску графа, а просто циклически сдвигать последовательности работ внутри каждого блока.&lt;br /&gt;
&lt;br /&gt;
===Время работы===&lt;br /&gt;
Чтобы построить циклические сдвиги внутри одного блока требуется &amp;lt;tex&amp;gt; \mathcal{O} \left( m^2 \right) &amp;lt;/tex&amp;gt; времени. Всего блоков &amp;lt;tex&amp;gt; \mathcal{O} \left( \dfrac{n}{m} \right) &amp;lt;/tex&amp;gt;. &lt;br /&gt;
Значит, итоговая ассимптотика равна &amp;lt;tex&amp;gt; \mathcal{O}(n \cdot m) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==См. также.==&lt;br /&gt;
* [[Методы решения задач теории расписаний]]&lt;br /&gt;
* [[1outtreesumwc|&amp;lt;tex&amp;gt; 1 \mid outtree \mid \sum w_i C_i &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1ripi1sumwc|&amp;lt;tex&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[RSumCi|&amp;lt;tex&amp;gt; R \mid \mid \sum 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>Qradimir</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Opij1Cmax&amp;diff=54807</id>
		<title>Opij1Cmax</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Opij1Cmax&amp;diff=54807"/>
				<updated>2016-06-07T01:04:13Z</updated>
		
		<summary type="html">&lt;p&gt;Qradimir: Вики-таблица, см. также&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;O \mid p_{ij} = 1 \mid C_{max}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; одинаковых станков, которые работают параллельно и &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ, котороые необходимо выполнить в произвольном порядке на всех станках. Время выполнения каждой работы на любом станке одинаково и равно 1. Необходимо минимизировать время выполнения всех работ.&lt;br /&gt;
}}&lt;br /&gt;
==Алгоритм==&lt;br /&gt;
&lt;br /&gt;
===Описание алгоритма===&lt;br /&gt;
Минимальное значение &amp;lt;tex&amp;gt; C_{max} &amp;lt;/tex&amp;gt; упирается в следующие ограничения:&lt;br /&gt;
# В допустимом расписании на каждом станке надо обработать каждую работу, поэтому &amp;lt;tex&amp;gt; C_{max} \geqslant  n &amp;lt;/tex&amp;gt;.&lt;br /&gt;
# В допустимом расписании каждую работу нужно обработать на всех станках, причем ее нельзя обрабатывать на двух станках одновременно, поэтому &amp;lt;tex&amp;gt; C_{max} \geqslant m &amp;lt;/tex&amp;gt;.&lt;br /&gt;
Тогда &amp;lt;tex&amp;gt; C_{max} = \max{(m, n)} &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В случае &amp;lt;tex&amp;gt; n \geqslant m &amp;lt;/tex&amp;gt; оптимальное расписание строится циклическими сдвигами последовательности &amp;lt;tex&amp;gt; 1 \dots n &amp;lt;/tex&amp;gt; и выглядит следующим образом:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!              &lt;br /&gt;
!| 1 || 2 || 3 ||&amp;lt;tex&amp;gt;\hdots&amp;lt;/tex&amp;gt;|| n - 1 || n&lt;br /&gt;
|- style=&amp;quot;text-align:center;&amp;quot;&lt;br /&gt;
!&amp;lt;tex&amp;gt;M_1&amp;lt;/tex&amp;gt;&lt;br /&gt;
|| 1 || 2 || 3 ||&amp;lt;tex&amp;gt;\hdots&amp;lt;/tex&amp;gt;|| n - 1 || n&lt;br /&gt;
|- style=&amp;quot;text-align:center;&amp;quot;&lt;br /&gt;
!&amp;lt;tex&amp;gt;M_2&amp;lt;/tex&amp;gt;&lt;br /&gt;
|| n || 1 || 2 ||&amp;lt;tex&amp;gt;\hdots&amp;lt;/tex&amp;gt;|| n - 2 || n - 1&lt;br /&gt;
|- style=&amp;quot;text-align:center;&amp;quot;&lt;br /&gt;
!&amp;lt;tex&amp;gt;M_3&amp;lt;/tex&amp;gt;&lt;br /&gt;
|| n - 1 || n || 1 ||&amp;lt;tex&amp;gt;\hdots&amp;lt;/tex&amp;gt;|| n - 3 || n - 2&lt;br /&gt;
|- style=&amp;quot;text-align:center;&amp;quot;&lt;br /&gt;
!&amp;lt;tex&amp;gt;\vdots&amp;lt;/tex&amp;gt;             &lt;br /&gt;
||&amp;lt;tex&amp;gt;\vdots&amp;lt;/tex&amp;gt;||&amp;lt;tex&amp;gt;\vdots&amp;lt;/tex&amp;gt;||&amp;lt;tex&amp;gt;\vdots&amp;lt;/tex&amp;gt;||&amp;lt;tex&amp;gt;\ddots&amp;lt;/tex&amp;gt;||&amp;lt;tex&amp;gt;\vdots&amp;lt;/tex&amp;gt;||&amp;lt;tex&amp;gt;\vdots&amp;lt;/tex&amp;gt; &lt;br /&gt;
|- style=&amp;quot;text-align:center;&amp;quot;&lt;br /&gt;
!&amp;lt;tex&amp;gt;M_m&amp;lt;/tex&amp;gt;&lt;br /&gt;
|| n - m + 2 || n - m + 3 || n - m + 4 ||&amp;lt;tex&amp;gt;\hdots&amp;lt;/tex&amp;gt;|| n - m ||n - m + 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt; n &amp;lt; m &amp;lt;/tex&amp;gt;, добавим &amp;lt;tex&amp;gt; m - n &amp;lt;/tex&amp;gt; фиктивных работ с номерами &amp;lt;tex&amp;gt; n + 1 \dots m &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; \mathcal{O}(1) &amp;lt;/tex&amp;gt; времени.&lt;br /&gt;
Построение расписания сводится к заполнению матрицы размером &amp;lt;tex&amp;gt; m \times \max{(m, n)} &amp;lt;/tex&amp;gt; и выполняется за &amp;lt;tex&amp;gt; \mathcal{O}(m \dot (m + n)) &amp;lt;/tex&amp;gt; времени.&lt;br /&gt;
&lt;br /&gt;
==См. также.==&lt;br /&gt;
* [[Методы решения задач теории расписаний]]&lt;br /&gt;
* [[O2Cmax|&amp;lt;tex&amp;gt; O2 \mid \mid C_{max} &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[QpmtnCmax|&amp;lt;tex&amp;gt; Q \mid pmtn \mid C_{max} &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1Sumwc|&amp;lt;tex&amp;gt; O \mid p_{ij} = 1 \mid \sum w_i C_i &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Qradimir</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=RSumCi&amp;diff=54806</id>
		<title>RSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=RSumCi&amp;diff=54806"/>
				<updated>2016-06-06T23:55:46Z</updated>
		
		<summary type="html">&lt;p&gt;Qradimir: Фиксы&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi=&amp;quot;200&amp;quot;&amp;gt;R \mid \mid \sum C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=Дано &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;
==Алгоритм==&lt;br /&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; &lt;br /&gt;
\sum\limits_{i=1}^{n_j} \left( p_ij + \sum\limits_{q=1}^{i-1} p_qj \right) = &lt;br /&gt;
n_j p_{1j} + (n_j - 1) p_{2j} + \dots + 2 p_{(n_j-1)j} + p_{n_jj} &lt;br /&gt;
&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; с помощью алгоритма [[Поток минимальной стоимости | поиска максимального потока минимальной стоимости]]. Поместим в левую долю графа работы, в правую долю — пары из станка и коэффициента и проведем соответствующие ребра пропускной способности &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и стоимости &amp;lt;tex&amp;gt;k \cdot 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;. Максимальный поток минимальной стоймости в построенной сети будет ответом на исходную задачу. &lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Eсли ребро &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;
|proof=&lt;br /&gt;
# Целевя функция текущей задачи совпадает со стомостью максимального потока в построенной сети, так как у ребер между долями пропускная способность 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;
&lt;br /&gt;
===Время выполнения===&lt;br /&gt;
Время выполнения алгоритма поиска максимального потока минимальной стоймости равно &amp;lt;tex&amp;gt; \mathcal{O}(V \cdot E^2) &amp;lt;/tex&amp;gt;. Количество вершин в получаемой сети равно &amp;lt;tex&amp;gt; \mathcal{O}(m \cdot n) &amp;lt;/tex&amp;gt;. Количество ребер в сети равно &amp;lt;tex&amp;gt; \mathcal{O}(m \cdot n^2) &amp;lt;/tex&amp;gt;. Следовательно, ассимптотика алгоритма равна &amp;lt;tex&amp;gt; \mathcal{O}(m^3 \cdot n^5) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
* [[Поток минимальной стоимости]]&lt;br /&gt;
* [[Методы решения задач теории расписаний]]&lt;br /&gt;
* [[PSumCi|&amp;lt;tex&amp;gt;P \mid \mid \sum C_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[QSumCi|&amp;lt;tex&amp;gt;Q \mid \mid \sum C_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Qradimir</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=1outtreesumwc&amp;diff=54805</id>
		<title>1outtreesumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=1outtreesumwc&amp;diff=54805"/>
				<updated>2016-06-06T23:29:04Z</updated>
		
		<summary type="html">&lt;p&gt;Qradimir: 1 | intree | Sum(w*C) - наводим красоту&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot; &amp;gt;1 \mid outtree \mid \sum w_i C_i&amp;lt;/tex&amp;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;
Докажем некоторые свойства оптимального расписания, которые мы будем использовать в доказательстве корректности алгоритма.&lt;br /&gt;
&lt;br /&gt;
Введем некоторые обозначения для удобства. За &amp;lt;tex&amp;gt;\mathrm{edges} &amp;lt;/tex&amp;gt; обозначим список всех ребёр дерева. Для всех работ &amp;lt;tex&amp;gt;i = 1, \ldots, n&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; в дереве зависимостей, включая саму работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, введём новый параметр работы &amp;lt;tex&amp;gt;q_i = \dfrac{w_i}{p_i}&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для подмножества работ &amp;lt;tex&amp;gt;I \subseteq \{1, \ldots, n\}&amp;lt;/tex&amp;gt; определим:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;w(I) = \sum\limits_{i \in I} w_i, p(I) = \sum\limits_{i \in I} p_i, q(I) = \dfrac{w(I)}{p(I)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Два непересекающихся множества работ &amp;lt;tex&amp;gt;I, J \subseteq \{1, \ldots, n\}&amp;lt;/tex&amp;gt; будем называть '''параллельными''' &amp;lt;tex&amp;gt;(I \sim J)&amp;lt;/tex&amp;gt;, если для всех &amp;lt;tex&amp;gt;i \in I, j \in J&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;I = \{i\},\ J = \{j\}&amp;lt;/tex&amp;gt;, будем писать &amp;lt;tex&amp;gt;i \sim j&amp;lt;/tex&amp;gt;. Каждое расписание представлено перестановкой &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|statement= Пусть &amp;lt;tex&amp;gt;\pi&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;\pi&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;. Пусть &amp;lt;tex&amp;gt;\pi'&amp;lt;/tex&amp;gt; {{---}} расписание, полученное из &amp;lt;tex&amp;gt;\pi&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;. Тогда выполяются следующие пункты:&lt;br /&gt;
:&amp;lt;tex&amp;gt;(a)~ I \sim J \Rightarrow q(I) \geqslant q(J)&amp;lt;/tex&amp;gt; &lt;br /&gt;
:&amp;lt;tex&amp;gt;(b)&amp;lt;/tex&amp;gt; Если &amp;lt;tex&amp;gt;I \sim J&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;q(I) = q(J)&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\pi'&amp;lt;/tex&amp;gt; {{---}} оптимальное расписание.&lt;br /&gt;
|proof= &lt;br /&gt;
&amp;lt;tex&amp;gt;(a)&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:Пусть &amp;lt;tex&amp;gt;f = \sum w_i C_i&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt; {{---}} оптимальное расписание, то &amp;lt;tex&amp;gt;f(\pi) \leqslant f(\pi')&amp;lt;/tex&amp;gt;. Таким образом:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;0 \leqslant f(\pi') - f(\pi) = w(I) p(J) - w(J) p(I)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:Поделим на &amp;lt;tex&amp;gt;p(I)p(J)&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;q(I) = \dfrac{w(I)}{p(I)} \geqslant \dfrac{w(J)}{p(J)} = q(J) &amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;(b)&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:Если &amp;lt;tex&amp;gt;q(I) = q(J) &amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;f(\pi) = f(\pi') &amp;lt;/tex&amp;gt;, следовательно расписание &amp;lt;tex&amp;gt;\pi'&amp;lt;/tex&amp;gt; оптимально.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id = theorem1&lt;br /&gt;
|statement = Пусть &amp;lt;tex&amp;gt;i, ~j&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; q_j = \max \{q_k \mid ~ (i, k) \in \mathrm{edges} \}&amp;lt;/tex&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&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;
|proof = &lt;br /&gt;
Каждое расписание может быть представлено последовательностью работ в порядке, в котором они выполняются. Пусть &amp;lt;tex&amp;gt; \pi &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; l &amp;lt;/tex&amp;gt; было бы минимальным. Можно считать, что &amp;lt;tex&amp;gt; l &amp;gt; 0 &amp;lt;/tex&amp;gt;. Тогда расписание можно представить следующим образом:&lt;br /&gt;
&lt;br /&gt;
[[Файл:JobBlock.jpg]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; случая.&lt;br /&gt;
&lt;br /&gt;
'''Случай 1''': &amp;lt;tex&amp;gt; k \in S(i) &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; k &amp;lt;/tex&amp;gt; , иначе у неё было бы &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; предка. Следовательно, &amp;lt;tex&amp;gt; k \sim j &amp;lt;/tex&amp;gt;. По [[#lemma1 | лемме]] &amp;lt;tex&amp;gt; q(k) \geqslant q(j) &amp;lt;/tex&amp;gt;, а по условию выбора &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt; имеем &amp;lt;tex&amp;gt; q(j) \geqslant q(k) &amp;lt;/tex&amp;gt;, значит, &amp;lt;tex&amp;gt; q(j) = q(k) &amp;lt;/tex&amp;gt;. Опять же из [[#lemma1 | леммы]] следует, что работы &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; l &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Случай 2''': &amp;lt;tex&amp;gt; k \not\in S(i) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:Пусть &amp;lt;tex&amp;gt; h &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; i) &amp;lt;/tex&amp;gt;, которая принадлежит &amp;lt;tex&amp;gt; S(i) &amp;lt;/tex&amp;gt;, то есть для всех работ &amp;lt;tex&amp;gt; r &amp;lt;/tex&amp;gt; в множестве &amp;lt;tex&amp;gt; K &amp;lt;/tex&amp;gt;, назначенных между &amp;lt;tex&amp;gt; h &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt;, имеем, что &amp;lt;tex&amp;gt; r \not\in S(i) &amp;lt;/tex&amp;gt;. Так как наш [[Основные определения теории графов | граф]] зависимостей работ является исходящим деревом и  &amp;lt;tex&amp;gt;(i, j) \in \mathrm{edges} &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;. Поэтому никакая работа из &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; i) &amp;lt;/tex&amp;gt; или потомком, значит, &amp;lt;tex&amp;gt; K \sim j &amp;lt;/tex&amp;gt;. Из этого следует, что &amp;lt;tex&amp;gt; q(K) \geqslant q(j) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Работа &amp;lt;tex&amp;gt; h \in S(i) &amp;lt;/tex&amp;gt; не является потомком какой-либо работы &amp;lt;tex&amp;gt; r \in K &amp;lt;/tex&amp;gt;. В противном же случае получалось, что &amp;lt;tex&amp;gt; r \in S(i) &amp;lt;/tex&amp;gt;, значит, &amp;lt;tex&amp;gt; h &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; и &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt;. Поэтому &amp;lt;tex&amp;gt; h \sim K &amp;lt;/tex&amp;gt;, откуда тут же следует, что &amp;lt;tex&amp;gt; q(h) \geqslant q(K) \geqslant q(j) &amp;lt;/tex&amp;gt;. По определению &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt; имеем, что &amp;lt;tex&amp;gt; q(j) \geqslant q(h) &amp;lt;/tex&amp;gt;, следовательно &amp;lt;tex&amp;gt; q(j) = q(h) = q(K) &amp;lt;/tex&amp;gt;. По [[#lemma1 | лемме]] мы можем поменять блоки &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;
&lt;br /&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;
}}&lt;br /&gt;
&lt;br /&gt;
== Алгоритм ==&lt;br /&gt;
Доказанная в предыдущем пункте [[#theorem1 | теорема]] уже даёт основную идею алгоритма: взять работу &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt;, отличную от корня дерева, с максимальным значением &amp;lt;tex&amp;gt; q_j &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; i &amp;lt;/tex&amp;gt;, то мы можем объедить вершины графа в одну вершину &amp;lt;tex&amp;gt; J_i  = \{i, j\}&amp;lt;/tex&amp;gt;, которая представляет собой последовательность &amp;lt;tex&amp;gt; \pi_i \colon i, j &amp;lt;/tex&amp;gt;. Все сыновья работы &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt; станут сыновьями новой вершины &amp;lt;tex&amp;gt; J_i &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; J_i &amp;lt;/tex&amp;gt; и соответствующей этому множеству последовательностью &amp;lt;tex&amp;gt; \pi_i &amp;lt;/tex&amp;gt;. На очередном шаге алгоритма мы находим вершину &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt;, отличную от корня, с максимальным значением &amp;lt;tex&amp;gt; q_j &amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt; par &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;, что &amp;lt;tex&amp;gt; par \in J_i &amp;lt;/tex&amp;gt;. После этого мы объединяем обе вершины, заменяя &amp;lt;tex&amp;gt; J_i &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; \pi_i &amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt; J_i \cup J_j &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; \pi_i \circ \pi_j &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt; \pi_i \circ \pi_j &amp;lt;/tex&amp;gt; {{---}} это конкатенация последовательностей &amp;lt;tex&amp;gt; \pi_i &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; \pi_j &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Детали описаны в алгоритме ниже, в котором&lt;br /&gt;
* &amp;lt;tex&amp;gt; E(i) &amp;lt;/tex&amp;gt; обозначает последнюю работу в последовательности &amp;lt;tex&amp;gt; \pi_i &amp;lt;/tex&amp;gt;,&lt;br /&gt;
* &amp;lt;tex&amp;gt; P(i) &amp;lt;/tex&amp;gt; обозначает предка в графе зависимостей, а после слияния с какой-то вершиной &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt; {{---}} предыдущую работу в последовательности &amp;lt;tex&amp;gt; \pi_j &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
  w[root] = &amp;lt;tex&amp;gt; - \infty &amp;lt;/tex&amp;gt;&lt;br /&gt;
  '''for''' i = 1..n&lt;br /&gt;
    E[i] = {i} &lt;br /&gt;
    J[i] = {i} &lt;br /&gt;
    q[i] = w[i] \ p[i]&lt;br /&gt;
  L = {1, ... , n}&lt;br /&gt;
  '''while''' L &amp;lt;tex&amp;gt; \ne &amp;lt;/tex&amp;gt; {root} &amp;lt;font color=darkgreen&amp;gt;// пока в списке работ не останется только корень&amp;lt;/font&amp;gt;&lt;br /&gt;
    Найти работу j &amp;lt;tex&amp;gt; \in &amp;lt;/tex&amp;gt; L с маскимальным значением q[j]&lt;br /&gt;
    par = P[j]&lt;br /&gt;
    Найти i, что par &amp;lt;tex&amp;gt; \in &amp;lt;/tex&amp;gt; J[i]&lt;br /&gt;
    w[i] += w[j]&lt;br /&gt;
    p[i] += p[j]&lt;br /&gt;
    q[i] = w[i] / w[j]    &amp;lt;font color=darkgreen&amp;gt;// пересчитаем значения в вершине&amp;lt;/font&amp;gt;&lt;br /&gt;
    P[j] = E[i]           &amp;lt;font color=darkgreen&amp;gt;// предком работы j теперь будет последняя работа в &amp;lt;tex&amp;gt; \pi_i &amp;lt;/tex&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
    E[i] = E[j]           &amp;lt;font color=darkgreen&amp;gt;// последней работой в &amp;lt;tex&amp;gt; \pi_i &amp;lt;/tex&amp;gt; теперь будет последняя работа в &amp;lt;tex&amp;gt; \pi_j &amp;lt;/tex&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
    J[i] = J[i] &amp;lt;tex&amp;gt; \cup &amp;lt;/tex&amp;gt; J[j]&lt;br /&gt;
    L = L \ {j}&lt;br /&gt;
Вначале делаем присваивание &amp;lt;tex&amp;gt; w(root) = -\infty &amp;lt;/tex&amp;gt;, чтобы корень никогда не выбрался на шаге выбора вершины с максимальным значением &amp;lt;tex&amp;gt; q &amp;lt;/tex&amp;gt;. В реализации же можно просто дополнительно проверять на равенство с корнем, чтобы избежать переполнений или испортить значение &amp;lt;tex&amp;gt;-\infty&amp;lt;/tex&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
После завершения этой процедуры оптимальное расписание можно восстановить с конца, зная &amp;lt;tex&amp;gt; E(root) &amp;lt;/tex&amp;gt; и массив &amp;lt;tex&amp;gt; P &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; q(j) &amp;lt;/tex&amp;gt; использовать очередь с приоритетами, а для поиска родителям вершины использовать систему непересекающихся множеств, то время работы алгоритма будет &amp;lt;tex&amp;gt; \mathcal{O}(n\log{n}) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Проиллюстрируем работу алгоритма на следующем примере.&lt;br /&gt;
&lt;br /&gt;
[[Файл:JobsOuttrees.jpg|650px]]&lt;br /&gt;
&lt;br /&gt;
Первой выберется работа с номером &amp;lt;tex&amp;gt; 5 &amp;lt;/tex&amp;gt;. Она объединиться со своим родителем &amp;lt;tex&amp;gt; 2 &amp;lt;/tex&amp;gt; и допишется в конец &amp;lt;tex&amp;gt; \pi_2 &amp;lt;/tex&amp;gt;. Потом выберется работа &amp;lt;tex&amp;gt; 4 &amp;lt;/tex&amp;gt;, потом &amp;lt;tex&amp;gt; \{2, 5\} &amp;lt;/tex&amp;gt; и т. д. Процесс будет продолжаться, пока не останется одна вершина. Ответ {{---}} оптимальная последовательность работ {{---}} содержится в &amp;lt;tex&amp;gt; \pi_1 &amp;lt;/tex&amp;gt;, который написан внутри последней вершины.&lt;br /&gt;
&lt;br /&gt;
== Доказательство оптимальности алгоритма ==&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id = theorem2&lt;br /&gt;
|statement = Алгоритм &amp;lt;tex&amp;gt; 1 \mid outtree \mid \sum w_i C_i&amp;lt;/tex&amp;gt; строит оптимальное расписание.&lt;br /&gt;
|proof = &lt;br /&gt;
Доказательство проведём по индукции. Очевидно, что для одной вершины алгоритм построит оптимальное расписание. Пусть теперь он может составить оптимальную последовательность назначенных работ числом меньше &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt;. Пусть также работы &amp;lt;tex&amp;gt; i, j &amp;lt;/tex&amp;gt; {{---}} работы, которые объединятся на первом шаге алгоритма. Тогда оптимальное расписание &amp;lt;tex&amp;gt; R &amp;lt;/tex&amp;gt; можно представить следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; \pi \colon \pi (1), \ldots, \pi (k), i, j, \pi (k + 3), \ldots, \pi (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; j &amp;lt;/tex&amp;gt; в одну расписание &amp;lt;tex&amp;gt; R' &amp;lt;/tex&amp;gt; примет такой вид:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; \pi ' \colon \pi (1), \ldots, \pi (k), I, \pi (k + 3), \ldots, \pi (n) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где &amp;lt;tex&amp;gt; I = \{i, j\}, ~w(I) = w(i) + w(j), p(I) = p(i) + p(j)&amp;lt;/tex&amp;gt;. Обозначим за &amp;lt;tex&amp;gt; f_n(\pi ), ~f_{n-1}(\pi ') &amp;lt;/tex&amp;gt; целевые функции для последовательностей &amp;lt;tex&amp;gt; \pi &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; \pi ' &amp;lt;/tex&amp;gt; соответственно. Тогда &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; f_n(\pi ) - f_{n-1}(\pi') = w(i)p(i) + w(j)(p(i) + p(j)) - (w(i) + w(j))(p(i) + p(j)) = -w(i) p(j)\ (*) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Следовательно, расписание &amp;lt;tex&amp;gt; R &amp;lt;/tex&amp;gt; будет оптимальным тогда и только тогда, когда расписание &amp;lt;tex&amp;gt; R' &amp;lt;/tex&amp;gt; будет оптимальным. А по предположению индукции наш алгоритм составит оптимальное расписание для последовательности &amp;lt;tex&amp;gt; \pi ' &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теперь разделим обе части равенства &amp;lt;tex&amp;gt; (*) &amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt; w(i)w(j) &amp;lt;/tex&amp;gt;. Получим, что расстояние между целевыми функциями равно&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; -\dfrac{p(j)}{w(j)} = -\dfrac{1}{q(j)} &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; q(j) &amp;lt;/tex&amp;gt;. Из этих утверждений и следует оптимальность построенного алгоритмом расписания. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== 1 | intree | Sum(w*C)==&lt;br /&gt;
&amp;lt;tex dpi=&amp;quot;200&amp;quot;&amp;gt; 1 \mid intree \mid \sum w_i C_i &amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Необходимо составить расписание на одном станке работ с произвольными временами выполнения. Минимизировать нужно взвешенную сумму времен завершения работ. Зависимости между работами заданы [[Дерево, эквивалентные определения | деревом]], в котором листья {{---}} работы, которые доступны в начале, а все остальные работы недоступны пока все их дети не будут выполнены. &lt;br /&gt;
}}&lt;br /&gt;
Сведем задачу &amp;lt;tex&amp;gt; S_{in} = 1 \mid intree \mid \sum w_i C_i &amp;lt;/tex&amp;gt; к решенной задаче &amp;lt;tex&amp;gt;S_{out} = 1 \mid outtree \mid \sum w_i C_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;, теперь работа &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;
{{Теорема&lt;br /&gt;
|statement=Развернутое оптимальное расписание соответствующей задачи &amp;lt;tex&amp;gt; S_{out} &amp;lt;/tex&amp;gt; с весами &amp;lt;tex&amp;gt; w'_i &amp;lt;/tex&amp;gt; является оптимальным расписанием для задачи  &amp;lt;tex&amp;gt; S_{in} &amp;lt;/tex&amp;gt;&lt;br /&gt;
|proof=&lt;br /&gt;
Полученное расписание будет допустимым, так как расписание для &amp;lt;tex&amp;gt; S_{out} &amp;lt;/tex&amp;gt; было допустимым, и в нем никакие две работы не пересекались и не прерывались. Развернув ребра, мы не могли нарушить это свойство. Также из-за того, что мы развернули ребра в расписании, мы добились того, что все работы выполняются в правильном порядке (в расписании для &amp;lt;tex&amp;gt; S_{out} &amp;lt;/tex&amp;gt; из-за того, что все ребра были развернуты, порядок был нарушен для всех работ). Таким образом получили, что расписание допустимое.&lt;br /&gt;
&lt;br /&gt;
Пусть с помощью задачи &amp;lt;tex&amp;gt; S_{out} &amp;lt;/tex&amp;gt; мы получили последовательность работ &amp;lt;tex&amp;gt; 1 \dots n &amp;lt;/tex&amp;gt;. Распишем по определению значение целевой функции для &amp;lt;tex&amp;gt; S_{out} &amp;lt;/tex&amp;gt;:&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
\sum\limits_{i=1}^n \left( -w_i C_i \right) &lt;br /&gt;
= \sum \limits_{i=1}^n \left( -w_i \sum \limits_{j=1}^i p_j \right) = \\&lt;br /&gt;
= \sum\limits_{i=1}^n \left( w_i \sum\limits_{j=i+1}^n p_j \right) &lt;br /&gt;
- \sum\limits_{i=1}^n w_i \sum \limits_{i=1}^n p_i = \\&lt;br /&gt;
= \sum\limits_{i=1}^n \left( w_i \sum\limits_{j=i}^n p_j \right) &lt;br /&gt;
- \sum\limits_{i=1}^n w_i p_i &lt;br /&gt;
- \sum\limits_{i=1}^n w_i \sum \limits_{i=1}^n p_i&lt;br /&gt;
&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_{out} &amp;lt;/tex&amp;gt; также минимизирует &amp;lt;tex&amp;gt; S_{in} &amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 73 - 78&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Qradimir</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=RSumCi&amp;diff=54703</id>
		<title>RSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=RSumCi&amp;diff=54703"/>
				<updated>2016-06-06T09:38:47Z</updated>
		
		<summary type="html">&lt;p&gt;Qradimir: /* Время выполнения */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi=&amp;quot;200&amp;quot;&amp;gt;R \mid \mid \sum C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=Дано &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;
==Алгоритм==&lt;br /&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;. Максимальный поток минимальной стоймости в построенной сети будет ответом на исходную задачу. &lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Eсли ребро &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;
|proof=&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;
&lt;br /&gt;
===Время выполнения===&lt;br /&gt;
Время выполнения mincost-maxflow равно &amp;lt;tex&amp;gt; \mathcal{O}(V \cdot E^2) &amp;lt;/tex&amp;gt;. Количество вершин в получаемой сети равно &amp;lt;tex&amp;gt; \mathcal{O}(m \cdot n) &amp;lt;/tex&amp;gt;. Количество ребер в сети равно &amp;lt;tex&amp;gt; \mathcal{O}(m \cdot n^2) &amp;lt;/tex&amp;gt;. Следственно, ассимптотика алгоритма равна &amp;lt;tex&amp;gt; \mathcal{O}(m^3 \cdot n^5) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
* [[Поток минимальной стоимости]]&lt;br /&gt;
* [[Методы решения задач теории расписаний]]&lt;/div&gt;</summary>
		<author><name>Qradimir</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Opij1Sumwc&amp;diff=54702</id>
		<title>Opij1Sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Opij1Sumwc&amp;diff=54702"/>
				<updated>2016-06-06T09:37:00Z</updated>
		
		<summary type="html">&lt;p&gt;Qradimir: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi=&amp;quot;200&amp;quot;&amp;gt;O \mid p_{ij}=1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; одинаковых станков, которые работают параллельно и &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ, котороые необходимо выполнить в произвольном порядке на всех станках. Время выполнения каждой работы на любом станке одинаково и равно 1. Необходимо минимизировать взвешенную сумму времен завершения работ. &lt;br /&gt;
}}&lt;br /&gt;
==Алгоритм==&lt;br /&gt;
&lt;br /&gt;
===Описание алгоритма===&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Оптимальный ответ для &amp;lt;tex&amp;gt;S = O \mid p_{ij}=1 \mid \sum w_i C_i&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;
|proof=Для доказательства этого утверждения необходимо показать то, что из оптимальности &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; 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;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;
}}&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 \bmod m &amp;lt;/tex&amp;gt; работ. Таким образом, аналогично задаче &amp;lt;tex&amp;gt; O \mid p_{ij}=1 \mid C_{max}&amp;lt;/tex&amp;gt;, чтобы получить допустимое расписание, можно не строить раскраску графа, а просто циклически сдвигать последовательности работ внутри каждого блока.&lt;br /&gt;
&lt;br /&gt;
===Время работы===&lt;br /&gt;
Чтобы построить циклические сдвиги внутри одного блока требуется &amp;lt;tex&amp;gt; \mathcal{O}(m^2) &amp;lt;/tex&amp;gt; времени. Всего блоков &amp;lt;tex&amp;gt; \mathcal{O}(\frac{n}{m}) &amp;lt;/tex&amp;gt;. &lt;br /&gt;
Значит, итоговая ассимптотика равна &amp;lt;tex&amp;gt; \mathcal{O}(n \cdot m) &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;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Qradimir</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Opij1Cmax&amp;diff=54701</id>
		<title>Opij1Cmax</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Opij1Cmax&amp;diff=54701"/>
				<updated>2016-06-06T09:35:00Z</updated>
		
		<summary type="html">&lt;p&gt;Qradimir: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;O \mid p_{ij} = 1 \mid C_{max}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; одинаковых станков, которые работают параллельно и &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ, котороые необходимо выполнить в произвольном порядке на всех станках. Время выполнения каждой работы на любом станке одинаково и равно 1. Необходимо минимизировать время выполнения всех работ.&lt;br /&gt;
}}&lt;br /&gt;
==Алгоритм==&lt;br /&gt;
&lt;br /&gt;
===Описание алгоритма===&lt;br /&gt;
Минимальное значение &amp;lt;tex&amp;gt; T_{min} &amp;lt;/tex&amp;gt; минимизуруемой функции упирается в следующие ограничения:&lt;br /&gt;
# В допустимом расписании на каждом станке надо обработать каждую работу, поэтому &amp;lt;tex&amp;gt; T_{min} \geqslant  n &amp;lt;/tex&amp;gt;.&lt;br /&gt;
# В допустимом расписании каждую работу нужно обработать на всех станках, причем ее нельзя обрабатывать на двух станках одновременно, поэтому &amp;lt;tex&amp;gt; T_{min} \geqslant 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;
&lt;br /&gt;
В случае &amp;lt;tex&amp;gt; n \geqslant m &amp;lt;/tex&amp;gt; оптимальное расписание циклическими сдвигами последовательности &amp;lt;tex&amp;gt; 1 \dots n &amp;lt;/tex&amp;gt; и выглядит следующим образом:&lt;br /&gt;
         '''1     2     3   ... 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;
Если же &amp;lt;tex&amp;gt; n &amp;lt; m &amp;lt;/tex&amp;gt;, добавим &amp;lt;tex&amp;gt; m - n &amp;lt;/tex&amp;gt; фиктивных работ с номерами &amp;lt;tex&amp;gt; n + 1 \dots m &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; \mathcal{O}(1) &amp;lt;/tex&amp;gt; времени.&lt;br /&gt;
Построение расписания сводится к заполнению матрицы размером &amp;lt;tex&amp;gt; m \times \max{(m, n)} &amp;lt;/tex&amp;gt; и выполняется за &amp;lt;tex&amp;gt; \mathcal{O}(m \dot (m + 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;/div&gt;</summary>
		<author><name>Qradimir</name></author>	</entry>

	<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=54700</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=54700"/>
				<updated>2016-06-06T09:31:55Z</updated>
		
		<summary type="html">&lt;p&gt;Qradimir: Выделены задачи в конспекты, добавлены ссылки, разделы в конце конспекта&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;
С помощью этого метода решаются:&lt;br /&gt;
* Некоторые задачи класса Open Shop при условии &amp;lt;tex&amp;gt;p_{ij}=1&amp;lt;/tex&amp;gt; сводятся к задачам равной длительности на параллельных станках.&lt;br /&gt;
** &amp;lt;tex&amp;gt; O \mid p_{ij} = 1 \mid \sum w_i C_i &amp;lt;/tex&amp;gt; ([[Opij1Sumwc|ссылка]])&lt;br /&gt;
** &amp;lt;tex&amp;gt; O \mid p_{ij} = 1, r_i \mid C_{max} &amp;lt;/tex&amp;gt; &amp;lt;ref&amp;gt;Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 161&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Некоторые задачи класса Flow Shop при условии &amp;lt;tex&amp;gt;p_{ij}=1&amp;lt;/tex&amp;gt; сводятся к задаче на одном станке. &lt;br /&gt;
** &amp;lt;tex&amp;gt; F \mid p_{ij} = 1 \mid \sum w_i U_i &amp;lt;/tex&amp;gt; ([[Fpij1sumwu|ссылка]])&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; &amp;lt;ref&amp;gt;Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 121&amp;lt;/ref&amp;gt;&lt;br /&gt;
** &amp;lt;tex&amp;gt; F2 \mid pmtn \mid C_{max} &amp;lt;/tex&amp;gt; ([[Flow_shop|ссылка]])&lt;br /&gt;
* Некоторые задачи проверки существования расписания сводятся к задаче поиска максимального потока:&lt;br /&gt;
** &amp;lt;tex&amp;gt; Q \mid pmtn, r_i\mid L_{max} &amp;lt;/tex&amp;gt; &amp;lt;ref&amp;gt;Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 129-133&amp;lt;/ref&amp;gt;&lt;br /&gt;
** &amp;lt;tex&amp;gt; R \mid \mid \sum C_i &amp;lt;/tex&amp;gt; ([[RSumCi|ссылка]])&lt;br /&gt;
* &amp;lt;tex&amp;gt; 1 \mid intree \mid \sum w_i C_i &amp;lt;/tex&amp;gt; ([[1outtreesumwc|ссылка]])&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; &amp;lt;ref&amp;gt;Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 108&amp;lt;/ref&amp;gt;&lt;br /&gt;
* &amp;lt;tex&amp;gt; R \mid pmtn \mid C_{max}&amp;lt;/tex&amp;gt; &amp;lt;ref&amp;gt;Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 137-139&amp;lt;/ref&amp;gt;&lt;br /&gt;
* &amp;lt;tex&amp;gt; O \mid p_{ij}=1 \mid C_{max}&amp;lt;/tex&amp;gt; ([[Opij1Cmax|ссылка]])&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;
=== 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;
== Бинарный поиск по ответу ==&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; Q \mid pmtn, r_i \mid L_{max} &amp;lt;/tex&amp;gt; ([[QpmtnriLmax |ссылка]])&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; ([[1outtreesumwc|ссылка]])&lt;br /&gt;
* &amp;lt;tex&amp;gt; 1 \mid p_i = 1 \mid \sum w_i U_i &amp;lt;/tex&amp;gt; ([[1pi1sumwu|''Earliest Due Date rule'']])&lt;br /&gt;
* &amp;lt;tex&amp;gt; 1 \mid \mid \sum U_i &amp;lt;/tex&amp;gt; ([[1sumu|ссылка]])&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;
* [[Правило Лаулера]]&lt;br /&gt;
* [[Flow shop]]&lt;br /&gt;
* [[Opi1sumu|&amp;lt;tex&amp;gt; O \mid p_{ij} = 1 \mid \sum U_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;
* Peter Brucker «Scheduling Algorithms», fifth edition, Springer ISBN 978-3-540-69515-8&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Qradimir</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=1outtreesumwc&amp;diff=54693</id>
		<title>1outtreesumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=1outtreesumwc&amp;diff=54693"/>
				<updated>2016-06-06T00:23:14Z</updated>
		
		<summary type="html">&lt;p&gt;Qradimir: Добавлен раздел про intree расписание&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot; &amp;gt;1 \mid outtree \mid \sum w_i C_i&amp;lt;/tex&amp;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;
Докажем некоторые свойства оптимального расписания, которые мы будем использовать в доказательстве корректности алгоритма.&lt;br /&gt;
&lt;br /&gt;
Введем некоторые обозначения для удобства. За &amp;lt;tex&amp;gt;\mathrm{edges} &amp;lt;/tex&amp;gt; обозначим список всех ребёр дерева. Для всех работ &amp;lt;tex&amp;gt;i = 1, \ldots, n&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; в дереве зависимостей, включая саму работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, введём новый параметр работы &amp;lt;tex&amp;gt;q_i = \dfrac{w_i}{p_i}&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для подмножества работ &amp;lt;tex&amp;gt;I \subseteq \{1, \ldots, n\}&amp;lt;/tex&amp;gt; определим:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;w(I) = \sum\limits_{i \in I} w_i, p(I) = \sum\limits_{i \in I} p_i, q(I) = \dfrac{w(I)}{p(I)}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Два непересекающихся множества работ &amp;lt;tex&amp;gt;I, J \subseteq \{1, \ldots, n\}&amp;lt;/tex&amp;gt; будем называть '''параллельными''' &amp;lt;tex&amp;gt;(I \sim J)&amp;lt;/tex&amp;gt;, если для всех &amp;lt;tex&amp;gt;i \in I, j \in J&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;I = \{i\},\ J = \{j\}&amp;lt;/tex&amp;gt;, будем писать &amp;lt;tex&amp;gt;i \sim j&amp;lt;/tex&amp;gt;. Каждое расписание представлено перестановкой &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|statement= Пусть &amp;lt;tex&amp;gt;\pi&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;\pi&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;. Пусть &amp;lt;tex&amp;gt;\pi'&amp;lt;/tex&amp;gt; {{---}} расписание, полученное из &amp;lt;tex&amp;gt;\pi&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;. Тогда выполяются следующие пункты:&lt;br /&gt;
:&amp;lt;tex&amp;gt;(a)~ I \sim J \Rightarrow q(I) \geqslant q(J)&amp;lt;/tex&amp;gt; &lt;br /&gt;
:&amp;lt;tex&amp;gt;(b)&amp;lt;/tex&amp;gt; Если &amp;lt;tex&amp;gt;I \sim J&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;q(I) = q(J)&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\pi'&amp;lt;/tex&amp;gt; {{---}} оптимальное расписание.&lt;br /&gt;
|proof= &lt;br /&gt;
&amp;lt;tex&amp;gt;(a)&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:Пусть &amp;lt;tex&amp;gt;f = \sum w_i C_i&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt; {{---}} оптимальное расписание, то &amp;lt;tex&amp;gt;f(\pi) \leqslant f(\pi')&amp;lt;/tex&amp;gt;. Таким образом:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;0 \leqslant f(\pi') - f(\pi) = w(I) p(J) - w(J) p(I)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:Поделим на &amp;lt;tex&amp;gt;p(I)p(J)&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;q(I) = \dfrac{w(I)}{p(I)} \geqslant \dfrac{w(J)}{p(J)} = q(J) &amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;(b)&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
:Если &amp;lt;tex&amp;gt;q(I) = q(J) &amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;f(\pi) = f(\pi') &amp;lt;/tex&amp;gt;, следовательно расписание &amp;lt;tex&amp;gt;\pi'&amp;lt;/tex&amp;gt; оптимально.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id = theorem1&lt;br /&gt;
|statement = Пусть &amp;lt;tex&amp;gt;i, ~j&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; q_j = \max \{q_k \mid ~ (i, k) \in \mathrm{edges} \}&amp;lt;/tex&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&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;
|proof = &lt;br /&gt;
Каждое расписание может быть представлено последовательностью работ в порядке, в котором они выполняются. Пусть &amp;lt;tex&amp;gt; \pi &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; l &amp;lt;/tex&amp;gt; было бы минимальным. Можно считать, что &amp;lt;tex&amp;gt; l &amp;gt; 0 &amp;lt;/tex&amp;gt;. Тогда расписание можно представить следующим образом:&lt;br /&gt;
&lt;br /&gt;
[[Файл:JobBlock.jpg]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; случая.&lt;br /&gt;
&lt;br /&gt;
'''Случай 1''': &amp;lt;tex&amp;gt; k \in S(i) &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; k &amp;lt;/tex&amp;gt; , иначе у неё было бы &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; предка. Следовательно, &amp;lt;tex&amp;gt; k \sim j &amp;lt;/tex&amp;gt;. По [[#lemma1 | лемме]] &amp;lt;tex&amp;gt; q(k) \geqslant q(j) &amp;lt;/tex&amp;gt;, а по условию выбора &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt; имеем &amp;lt;tex&amp;gt; q(j) \geqslant q(k) &amp;lt;/tex&amp;gt;, значит, &amp;lt;tex&amp;gt; q(j) = q(k) &amp;lt;/tex&amp;gt;. Опять же из [[#lemma1 | леммы]] следует, что работы &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; l &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Случай 2''': &amp;lt;tex&amp;gt; k \not\in S(i) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:Пусть &amp;lt;tex&amp;gt; h &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; i) &amp;lt;/tex&amp;gt;, которая принадлежит &amp;lt;tex&amp;gt; S(i) &amp;lt;/tex&amp;gt;, то есть для всех работ &amp;lt;tex&amp;gt; r &amp;lt;/tex&amp;gt; в множестве &amp;lt;tex&amp;gt; K &amp;lt;/tex&amp;gt;, назначенных между &amp;lt;tex&amp;gt; h &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt;, имеем, что &amp;lt;tex&amp;gt; r \not\in S(i) &amp;lt;/tex&amp;gt;. Так как наш [[Основные определения теории графов | граф]] зависимостей работ является исходящим деревом и  &amp;lt;tex&amp;gt;(i, j) \in \mathrm{edges} &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;. Поэтому никакая работа из &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; i) &amp;lt;/tex&amp;gt; или потомком, значит, &amp;lt;tex&amp;gt; K \sim j &amp;lt;/tex&amp;gt;. Из этого следует, что &amp;lt;tex&amp;gt; q(K) \geqslant q(j) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
:Работа &amp;lt;tex&amp;gt; h \in S(i) &amp;lt;/tex&amp;gt; не является потомком какой-либо работы &amp;lt;tex&amp;gt; r \in K &amp;lt;/tex&amp;gt;. В противном же случае получалось, что &amp;lt;tex&amp;gt; r \in S(i) &amp;lt;/tex&amp;gt;, значит, &amp;lt;tex&amp;gt; h &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; и &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt;. Поэтому &amp;lt;tex&amp;gt; h \sim K &amp;lt;/tex&amp;gt;, откуда тут же следует, что &amp;lt;tex&amp;gt; q(h) \geqslant q(K) \geqslant q(j) &amp;lt;/tex&amp;gt;. По определению &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt; имеем, что &amp;lt;tex&amp;gt; q(j) \geqslant q(h) &amp;lt;/tex&amp;gt;, следовательно &amp;lt;tex&amp;gt; q(j) = q(h) = q(K) &amp;lt;/tex&amp;gt;. По [[#lemma1 | лемме]] мы можем поменять блоки &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;
&lt;br /&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;
}}&lt;br /&gt;
&lt;br /&gt;
== Алгоритм ==&lt;br /&gt;
Доказанная в предыдущем пункте [[#theorem1 | теорема]] уже даёт основную идею алгоритма: взять работу &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt;, отличную от корня дерева, с максимальным значением &amp;lt;tex&amp;gt; q_j &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; i &amp;lt;/tex&amp;gt;, то мы можем объедить вершины графа в одну вершину &amp;lt;tex&amp;gt; J_i  = \{i, j\}&amp;lt;/tex&amp;gt;, которая представляет собой последовательность &amp;lt;tex&amp;gt; \pi_i \colon i, j &amp;lt;/tex&amp;gt;. Все сыновья работы &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt; станут сыновьями новой вершины &amp;lt;tex&amp;gt; J_i &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; J_i &amp;lt;/tex&amp;gt; и соответствующей этому множеству последовательностью &amp;lt;tex&amp;gt; \pi_i &amp;lt;/tex&amp;gt;. На очередном шаге алгоритма мы находим вершину &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt;, отличную от корня, с максимальным значением &amp;lt;tex&amp;gt; q_j &amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt; par &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;, что &amp;lt;tex&amp;gt; par \in J_i &amp;lt;/tex&amp;gt;. После этого мы объединяем обе вершины, заменяя &amp;lt;tex&amp;gt; J_i &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; \pi_i &amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt; J_i \cup J_j &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; \pi_i \circ \pi_j &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt; \pi_i \circ \pi_j &amp;lt;/tex&amp;gt; {{---}} это конкатенация последовательностей &amp;lt;tex&amp;gt; \pi_i &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; \pi_j &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Детали описаны в алгоритме ниже, в котором&lt;br /&gt;
* &amp;lt;tex&amp;gt; E(i) &amp;lt;/tex&amp;gt; обозначает последнюю работу в последовательности &amp;lt;tex&amp;gt; \pi_i &amp;lt;/tex&amp;gt;,&lt;br /&gt;
* &amp;lt;tex&amp;gt; P(i) &amp;lt;/tex&amp;gt; обозначает предка в графе зависимостей, а после слияния с какой-то вершиной &amp;lt;tex&amp;gt; j &amp;lt;/tex&amp;gt; {{---}} предыдущую работу в последовательности &amp;lt;tex&amp;gt; \pi_j &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
  w[root] = &amp;lt;tex&amp;gt; - \infty &amp;lt;/tex&amp;gt;&lt;br /&gt;
  '''for''' i = 1..n&lt;br /&gt;
    E[i] = {i} &lt;br /&gt;
    J[i] = {i} &lt;br /&gt;
    q[i] = w[i] \ p[i]&lt;br /&gt;
  L = {1, ... , n}&lt;br /&gt;
  '''while''' L &amp;lt;tex&amp;gt; \ne &amp;lt;/tex&amp;gt; {root} &amp;lt;font color=darkgreen&amp;gt;// пока в списке работ не останется только корень&amp;lt;/font&amp;gt;&lt;br /&gt;
    Найти работу j &amp;lt;tex&amp;gt; \in &amp;lt;/tex&amp;gt; L с маскимальным значением q[j]&lt;br /&gt;
    par = P[j]&lt;br /&gt;
    Найти i, что par &amp;lt;tex&amp;gt; \in &amp;lt;/tex&amp;gt; J[i]&lt;br /&gt;
    w[i] += w[j]&lt;br /&gt;
    p[i] += p[j]&lt;br /&gt;
    q[i] = w[i] / w[j]    &amp;lt;font color=darkgreen&amp;gt;// пересчитаем значения в вершине&amp;lt;/font&amp;gt;&lt;br /&gt;
    P[j] = E[i]           &amp;lt;font color=darkgreen&amp;gt;// предком работы j теперь будет последняя работа в &amp;lt;tex&amp;gt; \pi_i &amp;lt;/tex&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
    E[i] = E[j]           &amp;lt;font color=darkgreen&amp;gt;// последней работой в &amp;lt;tex&amp;gt; \pi_i &amp;lt;/tex&amp;gt; теперь будет последняя работа в &amp;lt;tex&amp;gt; \pi_j &amp;lt;/tex&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
    J[i] = J[i] &amp;lt;tex&amp;gt; \cup &amp;lt;/tex&amp;gt; J[j]&lt;br /&gt;
    L = L \ {j}&lt;br /&gt;
Вначале делаем присваивание &amp;lt;tex&amp;gt; w(root) = -\infty &amp;lt;/tex&amp;gt;, чтобы корень никогда не выбрался на шаге выбора вершины с максимальным значением &amp;lt;tex&amp;gt; q &amp;lt;/tex&amp;gt;. В реализации же можно просто дополнительно проверять на равенство с корнем, чтобы избежать переполнений или испортить значение &amp;lt;tex&amp;gt;-\infty&amp;lt;/tex&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
После завершения этой процедуры оптимальное расписание можно восстановить с конца, зная &amp;lt;tex&amp;gt; E(root) &amp;lt;/tex&amp;gt; и массив &amp;lt;tex&amp;gt; P &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; q(j) &amp;lt;/tex&amp;gt; использовать очередь с приоритетами, а для поиска родителям вершины использовать систему непересекающихся множеств, то время работы алгоритма будет &amp;lt;tex&amp;gt; \mathcal{O}(n\log{n}) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Проиллюстрируем работу алгоритма на следующем примере.&lt;br /&gt;
&lt;br /&gt;
[[Файл:JobsOuttrees.jpg|650px]]&lt;br /&gt;
&lt;br /&gt;
Первой выберется работа с номером &amp;lt;tex&amp;gt; 5 &amp;lt;/tex&amp;gt;. Она объединиться со своим родителем &amp;lt;tex&amp;gt; 2 &amp;lt;/tex&amp;gt; и допишется в конец &amp;lt;tex&amp;gt; \pi_2 &amp;lt;/tex&amp;gt;. Потом выберется работа &amp;lt;tex&amp;gt; 4 &amp;lt;/tex&amp;gt;, потом &amp;lt;tex&amp;gt; \{2, 5\} &amp;lt;/tex&amp;gt; и т. д. Процесс будет продолжаться, пока не останется одна вершина. Ответ {{---}} оптимальная последовательность работ {{---}} содержится в &amp;lt;tex&amp;gt; \pi_1 &amp;lt;/tex&amp;gt;, который написан внутри последней вершины.&lt;br /&gt;
&lt;br /&gt;
== Доказательство оптимальности алгоритма ==&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id = theorem2&lt;br /&gt;
|statement = Алгоритм &amp;lt;tex&amp;gt; 1 \mid outtree \mid \sum w_i C_i&amp;lt;/tex&amp;gt; строит оптимальное расписание.&lt;br /&gt;
|proof = &lt;br /&gt;
Доказательство проведём по индукции. Очевидно, что для одной вершины алгоритм построит оптимальное расписание. Пусть теперь он может составить оптимальную последовательность назначенных работ числом меньше &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt;. Пусть также работы &amp;lt;tex&amp;gt; i, j &amp;lt;/tex&amp;gt; {{---}} работы, которые объединятся на первом шаге алгоритма. Тогда оптимальное расписание &amp;lt;tex&amp;gt; R &amp;lt;/tex&amp;gt; можно представить следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; \pi \colon \pi (1), \ldots, \pi (k), i, j, \pi (k + 3), \ldots, \pi (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; j &amp;lt;/tex&amp;gt; в одну расписание &amp;lt;tex&amp;gt; R' &amp;lt;/tex&amp;gt; примет такой вид:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; \pi ' \colon \pi (1), \ldots, \pi (k), I, \pi (k + 3), \ldots, \pi (n) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где &amp;lt;tex&amp;gt; I = \{i, j\}, ~w(I) = w(i) + w(j), p(I) = p(i) + p(j)&amp;lt;/tex&amp;gt;. Обозначим за &amp;lt;tex&amp;gt; f_n(\pi ), ~f_{n-1}(\pi ') &amp;lt;/tex&amp;gt; целевые функции для последовательностей &amp;lt;tex&amp;gt; \pi &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; \pi ' &amp;lt;/tex&amp;gt; соответственно. Тогда &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; f_n(\pi ) - f_{n-1}(\pi') = w(i)p(i) + w(j)(p(i) + p(j)) - (w(i) + w(j))(p(i) + p(j)) = -w(i) p(j)\ (*) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Следовательно, расписание &amp;lt;tex&amp;gt; R &amp;lt;/tex&amp;gt; будет оптимальным тогда и только тогда, когда расписание &amp;lt;tex&amp;gt; R' &amp;lt;/tex&amp;gt; будет оптимальным. А по предположению индукции наш алгоритм составит оптимальное расписание для последовательности &amp;lt;tex&amp;gt; \pi ' &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теперь разделим обе части равенства &amp;lt;tex&amp;gt; (*) &amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt; w(i)w(j) &amp;lt;/tex&amp;gt;. Получим, что расстояние между целевыми функциями равно&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; -\dfrac{p(j)}{w(j)} = -\dfrac{1}{q(j)} &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; q(j) &amp;lt;/tex&amp;gt;. Из этих утверждений и следует оптимальность построенного алгоритмом расписания. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Применение алгоритма в задаче с intree-зависимостью ==&lt;br /&gt;
Сведем задачу &amp;lt;tex&amp;gt; S_{in} = 1 \mid intree \mid \sum w_i C_i &amp;lt;/tex&amp;gt; к решенной задаче &amp;lt;tex&amp;gt;S_{out} = 1 \mid outtree \mid \sum w_i C_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;, работа &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;
{{Утверждение&lt;br /&gt;
|statement=Развернутое оптимальное расписание соответствующей задачи &amp;lt;tex&amp;gt; S_{out} &amp;lt;/tex&amp;gt; с весами &amp;lt;tex&amp;gt; w'_i &amp;lt;/tex&amp;gt; является оптимальным расписанием для задачи  &amp;lt;tex&amp;gt; S_{in} &amp;lt;/tex&amp;gt;&lt;br /&gt;
|proof=&lt;br /&gt;
Полученное расписание будет допустимым, так как расписание для &amp;lt;tex&amp;gt; S_{out} &amp;lt;/tex&amp;gt; было допустимым, и в нем никакие две работы не пересекались и не прерывались. Развернув, мы не могли нарушить это свойство. Также из-за того, что мы развернули расписание, мы добились того, что все работы выполняются в правильном порядке (в расписании для &amp;lt;tex&amp;gt; S_{out} &amp;lt;/tex&amp;gt; из-за того, что все ребра были развернуты, порядок был нарушен для всех работ). Таким образом, получили что расписание — допустимое.&lt;br /&gt;
&lt;br /&gt;
Пусть с помощью задачи &amp;lt;tex&amp;gt; S_{out} &amp;lt;/tex&amp;gt; мы получили последовательность работ &amp;lt;tex&amp;gt; 1 \dots n &amp;lt;/tex&amp;gt;. Распишем по определению значение целевой функции для &amp;lt;tex&amp;gt; S_{out} &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_{out} &amp;lt;/tex&amp;gt; также минимизирует &amp;lt;tex&amp;gt; S_{in} &amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 73 - 78&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Qradimir</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=RSumCi&amp;diff=54689</id>
		<title>RSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=RSumCi&amp;diff=54689"/>
				<updated>2016-06-05T22:25:47Z</updated>
		
		<summary type="html">&lt;p&gt;Qradimir: Конспект создан&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi=&amp;quot;200&amp;quot;&amp;gt;R \mid \mid \sum C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=Дано &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;
==Алгоритм==&lt;br /&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;. Максимальный поток минимальной стоймости в построенной сети будет ответом на исходную задачу. &lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Eсли ребро &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;
|proof=&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;
&lt;br /&gt;
===Время выполнения===&lt;br /&gt;
Время выполнения mincost-maxflow равно &amp;lt;tex&amp;gt; O(V \cdot E^2) &amp;lt;/tex&amp;gt;. Количество вершин в получаемой сети равно &amp;lt;tex&amp;gt; O(m \cdot n) &amp;lt;/tex&amp;gt;. Количество ребер в сети равно &amp;lt;tex&amp;gt; O(m \cdot n^2) &amp;lt;/tex&amp;gt;. Следственно, ассимптотика алгоритма равна &amp;lt;tex&amp;gt; O(m^3 \cdot n^5) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
* [[Поток минимальной стоимости]]&lt;br /&gt;
* [[Методы решения задач теории расписаний]]&lt;/div&gt;</summary>
		<author><name>Qradimir</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Opij1Sumwc&amp;diff=54670</id>
		<title>Opij1Sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Opij1Sumwc&amp;diff=54670"/>
				<updated>2016-06-05T21:36:09Z</updated>
		
		<summary type="html">&lt;p&gt;Qradimir: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi=&amp;quot;200&amp;quot;&amp;gt;O \mid p_{ij}=1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; одинаковых станков, которые работают параллельно и &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ, котороые необходимо выполнить в произвольном порядке на всех станках. Время выполнения каждой работы на любом станке одинаково и равно 1. Необходимо минимизировать взвешенную сумму времен завершения работ. &lt;br /&gt;
}}&lt;br /&gt;
==Алгоритм==&lt;br /&gt;
&lt;br /&gt;
===Описание алгоритма===&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Оптимальный ответ для &amp;lt;tex&amp;gt;S = O \mid p_{ij}=1 \mid \sum w_i C_i&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;
|proof=Для доказательства этого утверждения необходимо показать то, что из оптимальности &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; 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;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;
}}&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;, чтобы получить допустимое расписание, можно не строить раскраску графа, а просто циклически сдвигать последовательности работ внутри каждого блока.&lt;br /&gt;
&lt;br /&gt;
===Время работы===&lt;br /&gt;
Чтобы построить циклические сдвиги внутри одного блока требуется &amp;lt;tex&amp;gt; O(m^2) &amp;lt;/tex&amp;gt; времени. Всего блоков &amp;lt;tex&amp;gt; O(\frac{n}{m}) &amp;lt;/tex&amp;gt;. &lt;br /&gt;
Значит, итоговая ассимптотика равна &amp;lt;tex&amp;gt; O(n \cdot m) &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;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Qradimir</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Opij1Sumwc&amp;diff=54668</id>
		<title>Opij1Sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Opij1Sumwc&amp;diff=54668"/>
				<updated>2016-06-05T21:34:26Z</updated>
		
		<summary type="html">&lt;p&gt;Qradimir: Конспект создан&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi=&amp;quot;200&amp;quot;&amp;gt;O \mid p_{ij}=1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; одинаковых станков, которые работают параллельно и &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ, котороые необходимо выполнить в произвольном порядке на всех станках. Время выполнения каждой работы на любом станке одинаково и равно 1. Необходимо минимизировать взвешенную сумму времен завершения работ. &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;S = O \mid p_{ij}=1 \mid \sum w_i C_i&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;
|proof=Для доказательства этого утверждения необходимо показать то, что из оптимальности &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; 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;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;
}}&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;, чтобы получить допустимое расписание, можно не строить раскраску графа, а просто циклически сдвигать последовательности работ внутри каждого блока.&lt;br /&gt;
&lt;br /&gt;
===Время работы===&lt;br /&gt;
Чтобы построить циклические сдвиги внутри одного блока требуется &amp;lt;tex&amp;gt; O(m^2) &amp;lt;/tex&amp;gt; времени. Всего блоков &amp;lt;tex&amp;gt; O(\frac{n}{m}) &amp;lt;/tex&amp;gt;. &lt;br /&gt;
Значит, итоговая ассимптотика равна &amp;lt;tex&amp;gt; O(n \cdot m) &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;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Qradimir</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Opij1Cmax&amp;diff=54655</id>
		<title>Opij1Cmax</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Opij1Cmax&amp;diff=54655"/>
				<updated>2016-06-05T20:34:54Z</updated>
		
		<summary type="html">&lt;p&gt;Qradimir: /* Оценка сложности алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;O \mid p_{ij} = 1 \mid C_{max}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; одинаковых станков, которые работают параллельно и &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ, котороые необходимо выполнить в произвольном порядке на всех станках. Время выполнения каждой работы на любом станке одинаково и равно 1. Необходимо минимизировать время выполнения всех работ.&lt;br /&gt;
}}&lt;br /&gt;
==Алгоритм==&lt;br /&gt;
&lt;br /&gt;
===Описание алгоритма===&lt;br /&gt;
Минимальное значение &amp;lt;tex&amp;gt; T_{min} &amp;lt;/tex&amp;gt; минимизуруемой функции упирается в следующие ограничения:&lt;br /&gt;
# В допустимом расписании на каждом станке надо обработать каждую работу, поэтому &amp;lt;tex&amp;gt; T_{min} \ge n &amp;lt;/tex&amp;gt;.&lt;br /&gt;
# В допустимом расписании каждую работу нужно обработать на всех станках, причем ее нельзя обрабатывать на двух станках одновременно, поэтому &amp;lt;tex&amp;gt; T_{min} \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;
&lt;br /&gt;
В случае &amp;lt;tex&amp;gt; n \ge m &amp;lt;/tex&amp;gt; оптимальное расписание циклическими сдвигами последовательности &amp;lt;tex&amp;gt; 1 \dots n &amp;lt;/tex&amp;gt; и выглядит следующим образом:&lt;br /&gt;
         '''1     2     3   ... 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;
Если же &amp;lt;tex&amp;gt; n &amp;lt; m &amp;lt;/tex&amp;gt;, добавим &amp;lt;tex&amp;gt; m - n &amp;lt;/tex&amp;gt; фиктивных работ с номерами &amp;lt;tex&amp;gt; n + 1 \dots m &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; \mathcal{O}(1) &amp;lt;/tex&amp;gt; времени.&lt;br /&gt;
Построение расписания сводится к заполнению матрицы размером &amp;lt;tex&amp;gt; m \times \max{(m, n)} &amp;lt;/tex&amp;gt; и выполняется за &amp;lt;tex&amp;gt; \mathcal{O}(m \dot (m + 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;/div&gt;</summary>
		<author><name>Qradimir</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Opij1Cmax&amp;diff=54651</id>
		<title>Opij1Cmax</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Opij1Cmax&amp;diff=54651"/>
				<updated>2016-06-05T20:02:13Z</updated>
		
		<summary type="html">&lt;p&gt;Qradimir: Добавлен конспект&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;O \mid p_{ij} = 1 \mid C_{max}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; одинаковых станков, которые работают параллельно и &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ, котороые необходимо выполнить в произвольном порядке на всех станках. Время выполнения каждой работы на любом станке одинаково и равно 1. Необходимо минимизировать время выполнения всех работ.&lt;br /&gt;
}}&lt;br /&gt;
==Алгоритм==&lt;br /&gt;
&lt;br /&gt;
===Описание алгоритма===&lt;br /&gt;
Минимальное значение &amp;lt;tex&amp;gt; T_{min} &amp;lt;/tex&amp;gt; минимизуруемой функции упирается в следующие ограничения:&lt;br /&gt;
# В допустимом расписании на каждом станке надо обработать каждую работу, поэтому &amp;lt;tex&amp;gt; T_{min} \ge n &amp;lt;/tex&amp;gt;.&lt;br /&gt;
# В допустимом расписании каждую работу нужно обработать на всех станках, причем ее нельзя обрабатывать на двух станках одновременно, поэтому &amp;lt;tex&amp;gt; T_{min} \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;
&lt;br /&gt;
В случае &amp;lt;tex&amp;gt; n \ge m &amp;lt;/tex&amp;gt; оптимальное расписание циклическими сдвигами последовательности &amp;lt;tex&amp;gt; 1 \dots n &amp;lt;/tex&amp;gt; и выглядит следующим образом:&lt;br /&gt;
         '''1     2     3   ... 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;
Если же &amp;lt;tex&amp;gt; n &amp;lt; m &amp;lt;/tex&amp;gt;, добавим &amp;lt;tex&amp;gt; m - n &amp;lt;/tex&amp;gt; фиктивных работ с номерами &amp;lt;tex&amp;gt; n + 1 \dots m &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; O(1) &amp;lt;/tex&amp;gt; времени.&lt;br /&gt;
Построение расписания сводится к заполнению матрицы размером &amp;lt;tex&amp;gt; m \times \max{(m, n)} &amp;lt;/tex&amp;gt; и выполняется за &amp;lt;tex&amp;gt; O(m \dot (m + 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;/div&gt;</summary>
		<author><name>Qradimir</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%94%D0%B8%D1%81%D0%BA%D1%80%D0%B5%D1%82%D0%BD%D0%B0%D1%8F_%D0%BC%D0%B0%D1%82%D0%B5%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0,_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D0%B8_%D1%81%D1%82%D1%80%D1%83%D0%BA%D1%82%D1%83%D1%80%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=54649</id>
		<title>Дискретная математика, алгоритмы и структуры данных</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%94%D0%B8%D1%81%D0%BA%D1%80%D0%B5%D1%82%D0%BD%D0%B0%D1%8F_%D0%BC%D0%B0%D1%82%D0%B5%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0,_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D0%B8_%D1%81%D1%82%D1%80%D1%83%D0%BA%D1%82%D1%83%D1%80%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=54649"/>
				<updated>2016-06-05T19:04:48Z</updated>
		
		<summary type="html">&lt;p&gt;Qradimir: Новые конспекты из методов решений&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
Убедительная просьба читать [[Обсуждение:Дискретная_математика_и_алгоритмы | правила оформления вики-конспектов]].&lt;br /&gt;
&lt;br /&gt;
Символом &amp;lt;tex&amp;gt; \star &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;
*[[Симметричное отношение]]&lt;br /&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;
== Булевы функции ==&lt;br /&gt;
*[[Определение булевой функции]]&lt;br /&gt;
*[[Побитовые операции]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Суперпозиции]]&lt;br /&gt;
*[[ДНФ]]&lt;br /&gt;
*[[Сокращенная и минимальная ДНФ | Сокращенная и минимальная ДНФ, минимизация ДНФ методами гиперкубов, карт Карно, Квайна]]&lt;br /&gt;
*[[КНФ]]&lt;br /&gt;
*[[2-SAT]]&lt;br /&gt;
*[[Специальные формы КНФ|Специальные формы КНФ: КНФ в форме Хорна и КНФ в форме Крома]]&lt;br /&gt;
*[[Полином Жегалкина | Полином Жегалкина, преобразование Мёбиуса]]&lt;br /&gt;
*[[Полные системы функций. Теорема Поста о полной системе функций]]&lt;br /&gt;
*[[Представление функции класса DM с помощью медианы]]&lt;br /&gt;
*[[Пороговая функция]]&lt;br /&gt;
*[[Троичная логика]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Схемы из функциональных элементов ==&lt;br /&gt;
*[[Реализация булевой функции схемой из функциональных элементов]]&lt;br /&gt;
*[[Простейшие методы синтеза схем из функциональных элементов]]&lt;br /&gt;
*[[Метод Лупанова синтеза схем]]&lt;br /&gt;
*[[Cумматор]]&lt;br /&gt;
*[[Каскадный сумматор]]&lt;br /&gt;
*[[Двоичный каскадный сумматор]]&lt;br /&gt;
*[[Троичный сумматор]]&amp;lt;tex&amp;gt;^\star&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;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Квантовые гейты]]&amp;lt;tex&amp;gt;^\star&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;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Алгоритмы сжатия ==&lt;br /&gt;
* [[Алгоритм Хаффмана]]&lt;br /&gt;
* [[Оптимальное хранение словаря в алгоритме Хаффмана]]&lt;br /&gt;
* [[Алгоритм Хаффмана за O(n)]]&lt;br /&gt;
* [[Алгоритм Ху-Таккера]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Неравенство Крафта]]&lt;br /&gt;
* [[Неравенство Макмиллана]]&lt;br /&gt;
* [[Код Шеннона]]&lt;br /&gt;
* [[Оптимальный префиксный код с длиной кодового слова не более L бит]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритмы LZ77 и LZ78]]&lt;br /&gt;
* [[Алгоритм LZW]]&lt;br /&gt;
* [[Алгоритм LZSS]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Преобразование Барроуза-Уиллера | Преобразование Барроуза-Уиллера и обратное ему]]&lt;br /&gt;
* [[Преобразование MTF]]&lt;br /&gt;
* [[Расстояние Хэмминга]]&lt;br /&gt;
* [[Избыточное кодирование, код Хэмминга]]&lt;br /&gt;
* [[Гамма-, дельта- и омега-код Элиаса]]&amp;lt;tex&amp;gt;^\star&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;
* [[Коды антигрея]]&lt;br /&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;
* [[Получение предыдущего объекта]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;  &lt;br /&gt;
* [[Метод генерации случайной перестановки, алгоритм Фишера-Йетса]]&lt;br /&gt;
* [[Методы генерации случайного сочетания]]&amp;lt;tex&amp;gt;^\star&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;
* [[Числа Стирлинга первого рода]]&lt;br /&gt;
* [[Числа Стирлинга второго рода]]&lt;br /&gt;
* [[Числа Эйлера I и II рода | Числа Эйлера первого и второго рода. Подъемы в перестановках]]&amp;lt;tex&amp;gt;^\star&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;
* [[Матричное представление перестановок]]&lt;br /&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;
*[[Задача о порядке перемножения матриц]]&lt;br /&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;
*[[Применение метода четырех русских в задачах ДП на примере задачи о НОП]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Задача об оптимальном префиксном коде с сохранением порядка. Монотонность точки разреза]]&lt;br /&gt;
*[[Meet-in-the-middle]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Другие задачи ===&lt;br /&gt;
*[[Задача о расстоянии Дамерау-Левенштейна]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Задача о выводе в контекстно-свободной грамматике, алгоритм Кока-Янгера-Касами]]&lt;br /&gt;
*[[Задача о наибольшей подпоследовательности-палиндроме]]&lt;br /&gt;
*[[Наибольшая общая возрастающая подпоследовательность]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Задача о наибольшей общей палиндромной подпоследовательности]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Динамическое программирование по профилю]]&amp;lt;tex&amp;gt;^\star&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;
*[[Формула Байеса]]&lt;br /&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;
*[[Симуляция одним распределением другого]]&lt;br /&gt;
*[[Арифметическое кодирование]]&lt;br /&gt;
*[[Парадоксы теории вероятностей]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Схема Бернулли]]&amp;lt;tex&amp;gt;^\star&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;
* [[Расчет вероятности поглощения в состоянии]]&lt;br /&gt;
* [[Эргодическая марковская цепь]]&lt;br /&gt;
* [[Регулярная марковская цепь]]&lt;br /&gt;
* [[Примеры использования Марковских цепей]]&lt;br /&gt;
* [[Скрытые Марковские модели]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм Витерби]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм &amp;quot;Вперед-Назад&amp;quot;]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм Баума-Велша]]&amp;lt;tex&amp;gt;^\star&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;
* [[Hashed Array Tree]]&amp;lt;tex&amp;gt;^\star&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;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[List order maintenance]]&amp;lt;tex&amp;gt;^\star&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;
&lt;br /&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;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Система непересекающихся множеств ==&lt;br /&gt;
* [[СНМ (наивные реализации) | Наивные реализации]]&lt;br /&gt;
* [[СНМ (списки с весовой эвристикой) | Списки с весовой эвристикой]]&lt;br /&gt;
* [[СНМ(реализация с помощью леса корневых деревьев) | Реализация с помощью леса корневых деревьев]]&lt;br /&gt;
* [[СНМ с операцией удаления за О(1)]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [[Поисковые структуры данных]] ==&lt;br /&gt;
* [[Упорядоченное множество]]&lt;br /&gt;
* [[Дерево поиска, наивная реализация]]&lt;br /&gt;
* [[АВЛ-дерево]]&lt;br /&gt;
* [[2-3 дерево]]&lt;br /&gt;
* [[B-дерево]]&lt;br /&gt;
* [[Красно-черное дерево]]&lt;br /&gt;
* [[Декартово дерево]]&lt;br /&gt;
* [[Декартово дерево по неявному ключу]]&lt;br /&gt;
* [[Splay-дерево]]&lt;br /&gt;
* [[Tango-дерево]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Рандомизированное бинарное дерево поиска]]&lt;br /&gt;
* [[Дерево ван Эмде Боаса]]&lt;br /&gt;
* [[Список с пропусками]]&lt;br /&gt;
* [[Fusion tree]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Сверхбыстрый цифровой бор]]&lt;br /&gt;
* [[Rope]]&amp;lt;tex&amp;gt;^\star&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;
* [[Несогласованные поддеревья. Реализация массового обновления]]&lt;br /&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;
&lt;br /&gt;
== Хеширование ==&lt;br /&gt;
* [[Хеш-таблица]]&lt;br /&gt;
* [[Разрешение коллизий]]&lt;br /&gt;
* [[Хеширование кукушки]]&lt;br /&gt;
* [[Идеальное хеширование]]&lt;br /&gt;
* [[Перехеширование]]&lt;br /&gt;
* [[Фильтр Блума]]&lt;br /&gt;
* [[Quotient filter]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Универсальное семейство хеш-функций]]&lt;br /&gt;
* [[Расширяемое хеширование]]&amp;lt;tex&amp;gt;^\star&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;
* [[Сортировка Шелла]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Сортировка кучей]]&lt;br /&gt;
* [[Быстрая сортировка]]&lt;br /&gt;
* [[Сортировка слиянием]]&lt;br /&gt;
* [[Cортировка слиянием с использованием O(1) дополнительной памяти]]&lt;br /&gt;
* [[Терпеливая сортировка]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Timsort]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Smoothsort]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Теорема о нижней оценке для сортировки сравнениями]]&lt;br /&gt;
&lt;br /&gt;
=== Многопоточные сортировки ===&lt;br /&gt;
* [[Многопоточная сортировка слиянием]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[PSRS-сортировка]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
=== Другие сортировки ===&lt;br /&gt;
* [[Поиск k-ой порядковой статистики]]&lt;br /&gt;
* [[Поиск k-ой порядковой статистики за линейное время]]&lt;br /&gt;
* [[Поиск k-ой порядковой статистики в двух массивах]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Сортировка подсчетом]]&lt;br /&gt;
* [[Цифровая сортировка]]&lt;br /&gt;
* [[Карманная сортировка]]&lt;br /&gt;
* [[Сортировка Хана]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Задача флага Нидерландов]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Блинная сортировка]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Сортирующие сети ==&lt;br /&gt;
* [[Сортирующие сети]]&lt;br /&gt;
* [[0-1 принцип | Проверка сети компараторов на то, что она сортирующая. 0-1 принцип]]&lt;br /&gt;
* [[Сортирующие сети для квадратичных сортировок]]&lt;br /&gt;
* [[Сортировочные сети с особыми свойствами]]&amp;lt;tex&amp;gt;^\star&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;^\star&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;^\star&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;
* [[Основные определения теории графов|Основные определения: граф, ребро, вершина, степень, петля, путь, цикл]]&lt;br /&gt;
* [[Лемма о рукопожатиях]]&lt;br /&gt;
* [[Теорема о существовании простого пути в случае существования пути]]&lt;br /&gt;
* [[Теорема о существовании простого цикла в случае существования цикла]]&lt;br /&gt;
* [[Матрица смежности графа]]&lt;br /&gt;
* [[Матрица инцидентности графа]]&lt;br /&gt;
* [[Циклическое пространство графа]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Фундаментальные циклы графа]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Дерево, эквивалентные определения]]&lt;br /&gt;
* [[Алгоритмы на деревьях]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Дополнительный, самодополнительный граф]]&lt;br /&gt;
* [[Теоретико-множественные операции над графами]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Рёберное ядро]]&lt;br /&gt;
* [[Факторизация графов]]&amp;lt;tex&amp;gt;^\star&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;
* [[Граф компонент реберной двусвязности]]&lt;br /&gt;
* [[Граф блоков-точек сочленения]]&lt;br /&gt;
* [[k-связность]]&lt;br /&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;
* [[Алгоритм Краскала]]&lt;br /&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;
* [[Количество помеченных деревьев]]&lt;br /&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;
=== Гамильтоновы графы ===&lt;br /&gt;
* [[Гамильтоновы графы]]&lt;br /&gt;
* [[Теорема Хватала]]&lt;br /&gt;
* [[Теорема Дирака]]&lt;br /&gt;
* [[Теорема Оре]]&lt;br /&gt;
* [[Теорема Поша]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Теорема Гуйя-Ури]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм нахождения Гамильтонова цикла в условиях теорем Дирака и Оре]]&lt;br /&gt;
* [[Теорема Гринберга]]&amp;lt;tex&amp;gt;^\star&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;
* [[Непланарность K5 и K3,3|Непланарность &amp;lt;tex&amp;gt;K_5&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;K_{3,3}&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;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Двойственный граф планарного графа]]&lt;br /&gt;
* [[Теорема Фари]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Гамма-алгоритм]]&lt;br /&gt;
&lt;br /&gt;
== Раскраски графов ==&lt;br /&gt;
* [[Раскраска графа]]&lt;br /&gt;
* [[Двудольные графы и раскраска в 2 цвета]]&lt;br /&gt;
* [[Хроматический многочлен]]&lt;br /&gt;
* [[Формула Зыкова]]&lt;br /&gt;
* [[Формула Уитни]]&lt;br /&gt;
* [[Теорема Брукса]]&lt;br /&gt;
* [[Верхние и нижние оценки хроматического числа]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Хроматическое число планарного графа]]&lt;br /&gt;
* [[Многочлен Татта]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Теория Рамсея]]&amp;lt;tex&amp;gt;^\star&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;
* [[Использование обхода в глубину для поиска компонент сильной связности]]&lt;br /&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;
* [[Алгоритм Дейкстры]]&lt;br /&gt;
* [[Алгоритм Флойда]]&lt;br /&gt;
* [[Алгоритм Джонсона]]&lt;br /&gt;
* [[Алгоритм Левита]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм A*]] &amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм D*]] &amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Эвристики для поиска кратчайших путей]]&amp;lt;tex&amp;gt;^\star&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;
* [[Связь вершинного покрытия и независимого множества]]&lt;br /&gt;
* [[Рёберное ядро]]&amp;lt;tex&amp;gt;^\star&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;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Совершенное паросочетание в кубическом графе]]&amp;lt;tex&amp;gt;^\star&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;
* [[Алгоритм Форда-Фалкерсона, реализация с помощью поиска в глубину]]&lt;br /&gt;
* [[Алоритм Эдмондса-Карпа]]&lt;br /&gt;
* [[Алгоритм масштабирования потока]]&lt;br /&gt;
* [[Блокирующий поток]]&lt;br /&gt;
* [[Схема алгоритма Диница]]&lt;br /&gt;
* [[Теоремы Карзанова о числе итераций алгоритма Диница в сети с целочисленными пропускными способностями]]&lt;br /&gt;
* [[Алгоритм Голдберга-Тарьяна]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм поиска блокирующего потока в ациклической сети]]&lt;br /&gt;
* [[Метод проталкивания предпотока]]&lt;br /&gt;
* [[Алгоритм &amp;quot;поднять-в-начало&amp;quot;]]&lt;br /&gt;
* [[Теорема о декомпозиции]]&lt;br /&gt;
* [[Теорема о декомпозиционном барьере]]&lt;br /&gt;
* [[Циркуляция потока]]&lt;br /&gt;
* [[Алгоритм Каргера для нахождения минимального разреза]]&amp;lt;tex&amp;gt;^\star&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;
* [[Сведение задачи о назначениях к задаче о потоке минимальной стоимости]]&lt;br /&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;
* [[Слово Туэ-Морса]]&lt;br /&gt;
* [[Декомпозиция Линдона]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм Ландау-Шмидта]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм Крочемора]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм Мейна-Лоренца]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм Манакера]]&amp;lt;tex&amp;gt;^\star&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;
* [[Алгоритм Кнута-Морриса-Пратта]]&lt;br /&gt;
* [[Автомат Кнута-Морриса-Пратта]]&lt;br /&gt;
* [[Z-функция]]&lt;br /&gt;
* [[Бор]]&lt;br /&gt;
* [[Алгоритм Ахо-Корасик]]&lt;br /&gt;
* [[Суффиксный автомат]]&lt;br /&gt;
* [[Алгоритм Бойера-Мура]]&lt;br /&gt;
* [[Алгоритм Апостолико-Крочемора]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм Колусси]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм Райта]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм Shift-And]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Двусторонний алгоритм]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Турбо-алгоритм Бойера-Мура]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Нечёткий поиск ===&lt;br /&gt;
* [[Алгоритм Ландау-Вишкина (k несовпадений)]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм Ландау-Вишкина (k различий)]]&amp;lt;tex&amp;gt;^\star&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;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм Фарача]]&amp;lt;tex&amp;gt;^\star&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;
* [[Алгоритм поиска подстроки в строке с помощью суффиксного массива]]&lt;br /&gt;
* [[Количество подпалиндромов в строке]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Задача о наименьшем общем предке ==&lt;br /&gt;
* [[Сведение задачи LCA к задаче RMQ]]&lt;br /&gt;
* [[Сведение задачи RMQ к задаче LCA]]&lt;br /&gt;
* [[Метод двоичного подъема]]&lt;br /&gt;
* [[Решение RMQ с помощью разреженной таблицы]]&lt;br /&gt;
* [[Алгоритм Фарака-Колтона и Бендера]] (решение +/-1 RMQ с помощью метода четырех русских)&lt;br /&gt;
* [[Алгоритм Хьюи]]&lt;br /&gt;
* [[Heavy-light декомпозиция]]&lt;br /&gt;
* [[Алгоритм Шибера-Вишкина]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм Тарьяна поиска LCA за O(1) в оффлайн]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Link-Cut Tree]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Rake-Compress деревья]]&amp;lt;tex&amp;gt;^\star&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;
* [[Теорема о базах]]&lt;br /&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;
* [[Матроид Вамоса]]&amp;lt;tex&amp;gt;^\star&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;
* [[Объединение матроидов, проверка множества на независимость]]&lt;br /&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;
&lt;br /&gt;
=== Задачи с одним станком ===&lt;br /&gt;
* [[1sumu|&amp;lt;tex&amp;gt;1 \mid \mid \sum U_{i}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1sumwu|&amp;lt;tex&amp;gt; 1 \mid\mid \sum w_i U_i &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1ridipi1|&amp;lt;tex&amp;gt;1 \mid r_{i}, d_{i}, p_{i} = 1 \mid -&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1pi1sumwu|&amp;lt;tex&amp;gt;1 \mid p_{i} = 1 \mid \sum w_{i}U_{i}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1ripi1sumwc|&amp;lt;tex&amp;gt;1 \mid r_{i}, p_i=1\mid \sum w_{i}C_{i}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1ripi1sumf|&amp;lt;tex&amp;gt;1 \mid r_i, p_i = 1 \mid \sum f_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1ripipsumwu|&amp;lt;tex&amp;gt; 1 \mid r_i,p_i=p \mid \sum w_i U_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1ripmtnsumwc|&amp;lt;tex&amp;gt;1 \mid r_i, pmtn \mid \sum w_{i}C_{i}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1outtreesumwc | &amp;lt;tex&amp;gt;1 \mid outtree \mid \sum w_i C_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1precpmtnrifmax|&amp;lt;tex&amp;gt;1 \mid prec, pmtn, r_i \mid f_{\max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1precripi1Lmax|&amp;lt;tex&amp;gt;1 \mid prec; r_i; p_i = 1 \mid L_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=== Специальные случаи задач для двух станков ===&lt;br /&gt;
* [[P2precpi1Lmax|&amp;lt;tex&amp;gt;P2 \mid prec, p_i = 1 \mid L_{\max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[R2Cmax|&amp;lt;tex&amp;gt;R2 \mid \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[F2Cmax|&amp;lt;tex&amp;gt;F2 \mid \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[O2Cmax|&amp;lt;tex&amp;gt;O2 \mid \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[J2ni2Cmax|&amp;lt;tex&amp;gt;J2 \mid n_{i} \leqslant 2 \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[J2pij1Lmax| &amp;lt;tex&amp;gt;J2\mid p_{ij} = 1\mid L_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=== Задачи для произвольного числа станков ===&lt;br /&gt;
* [[Flow shop]]&lt;br /&gt;
* [[Fpij1sumwu|&amp;lt;tex&amp;gt;F \mid p_{ij} = 1 \mid \sum w_i U_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[PSumCi|&amp;lt;tex&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Pintreepi1Lmax|&amp;lt;tex&amp;gt;P \mid intree, p_{i} = 1 \mid L_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[PpmtnriLmax|&amp;lt;tex&amp;gt;P \mid pmtn, r_i \mid L_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Ppi1sumwu|&amp;lt;tex&amp;gt;P \mid p_i=1 \mid \sum w_i U_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Ppi1riintegerLmax|&amp;lt;tex&amp;gt;P \mid p_i=1; r_i - integer \mid L_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[RSumCi|&amp;lt;tex&amp;gt;R \mid \mid \sum C_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[QpmtnCmax|&amp;lt;tex&amp;gt;Q \mid pmtn \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[QpmtnSumCi|&amp;lt;tex&amp;gt; Q \mid pmtn \mid \sum C_i &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[QpmtnriLmax|&amp;lt;tex&amp;gt;Q \mid pmtn, r_{i} \mid L_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[QSumCi|&amp;lt;tex&amp;gt;Q\mid\mid\sum{C_i}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opi1sumu|&amp;lt;tex&amp;gt;O \mid p_{ij} = 1 \mid \sum U_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1di|&amp;lt;tex&amp;gt;O \mid p_{ij} = 1, d_i \mid - &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1sumwu|&amp;lt;tex&amp;gt; O \mid p_{i,j} = 1 \mid \sum w_{i} U_{i} &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1SumTi|&amp;lt;tex&amp;gt; O \mid p_{i,j} = 1 \mid \sum T_{i} &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1Cmax|&amp;lt;tex&amp;gt; O \mid p_{ij} = 1 \mid C_{max} &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1Sumwc|&amp;lt;tex&amp;gt; O \mid p_{ij} = 1 \mid \sum w_i C_i &amp;lt;/tex&amp;gt;]]&lt;/div&gt;</summary>
		<author><name>Qradimir</name></author>	</entry>

	</feed>