<?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=Sergej+Arkhipov</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=Sergej+Arkhipov"/>
		<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/Sergej_Arkhipov"/>
		<updated>2026-08-04T13:39:21Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47561</id>
		<title>1ripi1sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47561"/>
				<updated>2015-06-05T12:18:28Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: /* Реализация 2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt; и вес &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum w_{i} C_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;C_{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;
===Вариант 1===&lt;br /&gt;
&amp;lt;tex&amp;gt; 1 \mid p_i = 1\mid \sum C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот случай простейший. Ответом будет &amp;lt;tex&amp;gt;\sum\limits_{k = 1}^n(k)&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; членов арифметической прогрессии алгоритм &amp;lt;tex&amp;gt;S_n=\frac{a_1+a_n}2 \cdot n&amp;lt;/tex&amp;gt; будет работает за &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;, но если нужно вывести и само расписание время работы будет &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Вариант 2===&lt;br /&gt;
&amp;lt;tex&amp;gt; 1 \mid p_i = 1\mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для верного выполнения просто выставим работы по порядку невозрастания весов, тогда ответом будет &amp;lt;tex&amp;gt; \sum\limits_{i = 1}^nw_i C_i&amp;lt;/tex&amp;gt;, так как мы &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; раз сложим время окончания выполнения одной работы (которое в нашем случае &amp;lt;tex&amp;gt;C_{i-1}+1&amp;lt;/tex&amp;gt;) домноженное на вес этой работы. Данный алгоритм корректен по [[Задача_о_минимуме/максимуме_скалярного_произведения|теореме о минимуме/максимуме скалярного произведения]], так как мы сопоставляем две последовательности, подходящие под условия теоремы.  &lt;br /&gt;
&lt;br /&gt;
Так как [[Сортировка|сортировка]] весов занимает &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt; время, то асимптотика времени работы алгорита равна &amp;lt;tex&amp;gt;O(n + n \log n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Вариант 3===&lt;br /&gt;
&amp;lt;tex&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum f_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_{i}&amp;lt;/tex&amp;gt; {{---}} монотонная функция времени окончания работы &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; для работ &amp;lt;tex&amp;gt;i = 1, 2, \ldots , n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Нам нужно распределить &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ в разное время. Если мы назначим время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; для работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; то цена будет &amp;lt;tex&amp;gt;f_i(t + 1)&amp;lt;/tex&amp;gt;. Функция &amp;lt;tex&amp;gt;f_i&amp;lt;/tex&amp;gt; монотонно неубывающая, тогда работы в расписании надо располагать как можно раньше для получения верного решения. &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; временных интервалов &amp;lt;tex&amp;gt;t_i&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; r_1 \leqslant r_2 \leqslant \ldots \leqslant r_n&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
'''Псевдокод'''&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;tex&amp;gt;t_1 \leftarrow r_1 &amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for'''  &amp;lt;tex&amp;gt; i \leftarrow 2&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      &amp;lt;tex&amp;gt; t_i \leftarrow &amp;lt;/tex&amp;gt; '''max'''&amp;lt;tex&amp;gt;(r_i, \ t_{i-1} - 1)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм работает за &amp;lt;tex&amp;gt;O(n \log n +n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
==Основная задача== &lt;br /&gt;
===Описание алгоритма===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; {{---}} текущий момент времени.&amp;lt;br/&amp;gt;&lt;br /&gt;
Для каждого очередного значения &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt;, которое изменяется от &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; до времени окончания последней работы, будем:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Выбирать работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из множества невыполненных работ, у которой &amp;lt;tex&amp;gt;r_{i} \leqslant time&amp;lt;/tex&amp;gt;, а значение &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt; максимально.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Если мы смогли найти работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, то выполняем её в момент времени &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; и удаляем из множества невыполненных работ.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Увеличиваем &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; на один.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Доказательство корректности алгоритма===&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Расписание, построенное данным алгоритмом, является корректным и оптимальным.&lt;br /&gt;
|proof=&lt;br /&gt;
Доказательство будем вести от противного.&amp;lt;br/&amp;gt;&lt;br /&gt;
Рассмотрим расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, полученное после выполнения нашего алгоритма, и оптимальное расписание &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Возьмём первый момент времени &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;, когда расписания  различаются. Пусть в этот момент времени  в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, будет выполняться работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt;, а в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; {{---}} работа с весом &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Это первый момент, в котором расписания отличаются, значит в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; выполнится в момент времени &amp;lt;tex&amp;gt;t_{2} &amp;gt; t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Поменяем местами работы с весами &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и полуим расписание &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Это возможно, потому что время появления этих работ не меньше &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При такой перестановке ответы на задачу для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt; будут отличаться на &lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;tex&amp;gt;t_{1}w_{2} + t_{2}w_{1} - t_{1}w_{1} + t_{2}w_{2} = t_{1}(w_{2} - w_{1}) + t_{2}(w_{1} - w_{2}) = (t_{1} - t_{2})(w_{2} - w_{1})&amp;lt;/tex&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Первая скобка отрицательная: &amp;lt;tex&amp;gt;t_{1} &amp;lt; t_{2}&amp;lt;/tex&amp;gt;. Вторая скобка тоже отрицательная из того, что в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_1&amp;lt;/tex&amp;gt; выполняется раньше, значит её вес должен быть больше &amp;lt;tex&amp;gt;w_2&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Итого имеем, что ответ для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; больше, чем ответ для &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Следовательно расписание &amp;lt;tex&amp;gt;S_2&amp;lt;/tex&amp;gt; неоптимальное. Получили противоречие. Значит не существует такого момента времени, когда расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; отличается от оптимального. Следовательно мы доказали, что оно оптимальное.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Псевдокод===&lt;br /&gt;
&lt;br /&gt;
====Реализация 1====&lt;br /&gt;
   &amp;lt;tex&amp;gt; S \leftarrow \{1 \ldots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{time} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{answer} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''while''' &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow null &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt; i \in S&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt; r_{i} \leqslant \mathtt{time}&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt;w_i \geqslant \max\limits_{j \in S, j = 1 \ldots n} w_j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; j \leftarrow i &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; \mathtt{time++}&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;n + \max\limits_{i = 1 \ldots n} r_{i}&amp;lt;/tex&amp;gt; шагов цикла. Определить максимум в множестве можно за время &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, используя , например, [[:Категория:Приоритетные_очереди|очередь с приоритетами]]. Значит общее время работы алгоритма &amp;lt;tex&amp;gt;O((n + \max\limits_{i = 1 \ldots n} r_{i})\log n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Реализация 2====&lt;br /&gt;
Перед началом алгоритма [[Сортировка|отсортируем]] работы по порядку неубывания веса.&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{time} \leftarrow r_1&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{answer} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for''' &amp;lt;tex&amp;gt;i \leftarrow 1 &amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      '''if'''  &amp;lt;tex&amp;gt; r_{i} \leqslant \mathtt{time}&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''else'''&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{time} \leftarrow r_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; \mathtt{time++}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В начале алгоритма сортируем работы &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt; времени. Затем мы тратим &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; на получение ответа. Тогда суммарное время работы алгоритма составит &amp;lt;tex&amp;gt;O(n \log n + n )&amp;lt;/tex&amp;gt; что есть &amp;lt;tex&amp;gt;O(n (\log n + 1))&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;
* [[1ridipi1|&amp;lt;tex&amp;gt;1 | r_{i}, d_{i}, p_{i}=1 | -&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 19-20&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 38-39&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 84-85&lt;br /&gt;
* Лазарев А.А., Мусатова Е.Г., Кварацхелия А.Г., Гафаров Е.Р. Пособие по теории расписаний.&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Fpij1sumwu&amp;diff=47548</id>
		<title>Fpij1sumwu</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Fpij1sumwu&amp;diff=47548"/>
				<updated>2015-06-05T10:49:27Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;F \mid p_{ij} = 1 \mid \sum w_iu_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; станков, на которых нужно обработать &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; деталей. Каждую деталь нужно обработать по очереди на всех станках. Любая работа на любом станке выполняется единицу времени. Для каждой работы есть дедлайн &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; {{---}} время, до которого она должна быть закончена, и штраф &amp;lt;tex&amp;gt;w_i&amp;lt;/tex&amp;gt;, который нужно будет выплатить в случае, если работа была закончена после &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt;. Необходимо минимизировать суммарный штраф, который придется выплатить.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Алгоритм==&lt;br /&gt;
&lt;br /&gt;
===Описание алгоритма===&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Существует оптимальное расписание, в котором каждая работа делается непрерывно.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим расписание, в котором есть работы, которые делаются не непрерывно. Рассмотрим самый ранний разрыв: работа &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; делалась в моменты &amp;lt;tex&amp;gt;t(i), t(i) + 1, \ldots, t(i) + k&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;k &amp;lt; m&amp;lt;/tex&amp;gt;, но не делалась в момент времени &amp;lt;tex&amp;gt;t(i) + k + 1&amp;lt;/tex&amp;gt;. Докажем, что в момент времени &amp;lt;tex&amp;gt;t(i) + k + 1&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;k + 1&amp;lt;/tex&amp;gt;-й станок простаивает и можно продолжить делать &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ю работу. &lt;br /&gt;
&lt;br /&gt;
Пусть в момент времени &amp;lt;tex&amp;gt;t(i) + k + 1&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;k + 1&amp;lt;/tex&amp;gt;-м станке делается работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;. &lt;br /&gt;
В &amp;lt;tex&amp;gt;t(i) + k&amp;lt;/tex&amp;gt;-й момент времени &amp;lt;tex&amp;gt;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;t(i) + k + 1&amp;lt;/tex&amp;gt;-й момент &amp;lt;tex&amp;gt;k + 1&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;
&lt;br /&gt;
По этому утверждению, если работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; начали делать в &amp;lt;tex&amp;gt;t(i)&amp;lt;/tex&amp;gt;, то закончена она будет в &amp;lt;tex&amp;gt;t(i) + m&amp;lt;/tex&amp;gt;. Найдем время &amp;lt;tex&amp;gt;d'_i&amp;lt;/tex&amp;gt; такое, что начав выполнять в него работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, мы успеем выполнить ее до &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;d'_i = d_i - m&amp;lt;/tex&amp;gt;. Таким образом, вычтя из всех &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; число &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;, мы свели задачу к &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum w_i U_i&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Построив оптимальное расписание для &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum w_i U_i&amp;lt;/tex&amp;gt;, мы найдем времена, в которые нужно начинать выполнять работы. По утверждению выше, работы можно выполнять непрерывно.&lt;br /&gt;
&lt;br /&gt;
===Сложность алгоритма===&lt;br /&gt;
Задача &amp;lt;tex&amp;gt;F \mid p_{i j} = 1 \mid \sum w_iu_i&amp;lt;/tex&amp;gt; за &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; сводится к [[1pi1sumwu|задаче &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum w_i u_i&amp;lt;/tex&amp;gt;]]. Задача &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum u_iw_i&amp;lt;/tex&amp;gt; решается за &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt;. После решения этой задачи, нужно вывести ответ, имеющий размер &amp;lt;tex&amp;gt;O(nm)&amp;lt;/tex&amp;gt;. Значит, итоговая сложность алгоритма {{---}} &amp;lt;tex&amp;gt;O(n \log n + nm)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==См. также.==&lt;br /&gt;
* [[Классификация задач]]&lt;br /&gt;
* [[Flow shop]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* Лазарев А.А., Мусатова Е.Г., Кварацхелия А.Г., Гафаров Е.Р. Пособие по теории расписаний.&lt;br /&gt;
* Vladimír Modrák, R. Sudhakara Pandian. FLOW SHOP SCHEDULING ALGORITHM TO MINIMIZE COMPLETION TIME FOR -JOBS -MACHINES PROBLEM&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Flow_shop&amp;diff=47545</id>
		<title>Flow shop</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Flow_shop&amp;diff=47545"/>
				<updated>2015-06-05T10:27:43Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Описание ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Flow shop''' ('''&amp;lt;tex&amp;gt;F_{m}&amp;lt;/tex&amp;gt;''' в нотации Грэхема): В системе находится &amp;lt;tex&amp;gt; m &amp;lt;/tex&amp;gt; машин, работающих параллельно. Машины упорядочены. Каждая работа должна быть выполнена последовательно на всех машинах с первой по последнюю.}}&lt;br /&gt;
&lt;br /&gt;
Рассмотрим пример:  &amp;lt;tex&amp;gt;F \mid p_{ij} = 1 \mid C_{max}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Допустим, у нас &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; машин. В начальный момент времени мы можем начать обрабатывать любую работу на первой машине. В следующий момент на первой машине можно обрабатывать следующую работу, а на второй перейдёт предыдущая работа с первой машины, и так далее. Таким образом, на выполнение всех работ у нас уйдёт &amp;lt;tex&amp;gt;n + m - 1&amp;lt;/tex&amp;gt; единиц времени. Проиллюстрируем это диаграммой Гантта для случая &amp;lt;tex&amp;gt;n = 6, m = 5&amp;lt;/tex&amp;gt;:&lt;br /&gt;
         '''0   1   2   3   4   5   6   7   8   9   10'''&lt;br /&gt;
         -------------------------------------------&lt;br /&gt;
  '''M_1'''   |    1   2   3   4   5   6   -   -   -   -&lt;br /&gt;
  '''M_2'''   |    -   1   2   3   4   5   6   -   -   -&lt;br /&gt;
  '''M_3'''   |    -   -   1   2   3   4   5   6   -   -&lt;br /&gt;
  '''M_4'''   |    -   -   -   1   2   3   4   5   6   -&lt;br /&gt;
  '''M_5'''   |    -   -   -   -   1   2   3   4   5   6&lt;br /&gt;
&lt;br /&gt;
Заметим, что в данном случае &amp;lt;tex&amp;gt;p_{ij}&amp;lt;/tex&amp;gt; может быть равно не только единице, но и любой константе.&lt;br /&gt;
 &lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement = Любая задача вида &amp;lt;tex&amp;gt;F \mid p_{ij} = 1 \mid ? &amp;lt;/tex&amp;gt; сводится к соответствующей задаче вида &amp;lt;tex&amp;gt;1 \mid p_{ij} = 1 \mid ?&amp;lt;/tex&amp;gt;. &lt;br /&gt;
|proof = &lt;br /&gt;
Поскольку работа всегда заканчивает выполняться на последней машине, нас интересуют только времена завершения работ на последней машине. Также очевидно, что последняя машина может начать работать только в момент времени &amp;lt;tex&amp;gt; m - 1 &amp;lt;/tex&amp;gt;. Оказывается, что любое решение задачи &amp;lt;tex&amp;gt; 1 \mid p_{ij} = 1 \mid ? &amp;lt;/tex&amp;gt; с дедлайнами, уменьшенными на &amp;lt;tex&amp;gt; m - 1 &amp;lt;/tex&amp;gt; можно преобразовать в оптимальное расписание для задачи &amp;lt;tex&amp;gt;F \mid p_{ij} = 1 \mid ? &amp;lt;/tex&amp;gt;. Докажем это.&lt;br /&gt;
&lt;br /&gt;
Возьмем оптимальное расписание для соответствующей задачи с одним станком, выполним работы в этом порядке на первой машине, затем на второй машине, начиная с момента времени &amp;lt;tex&amp;gt; 1 &amp;lt;/tex&amp;gt;, и так далее, до выполнения на последней машине, начиная с &amp;lt;tex&amp;gt; m - 1 &amp;lt;/tex&amp;gt;. Это расписание корректно и соблюдает все дедлайны. Поскольку целевая функция совпадает с соответствующей функцией для задачи на одном станке, оно оптимально и для данной задачи.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Примером применения этого утверждения может служить следующая [[Fpij1sumwu|задача: &amp;lt;tex&amp;gt;F \mid p_{ij} = 1 \mid \sum w_iu_i&amp;lt;/tex&amp;gt;]].&lt;br /&gt;
&lt;br /&gt;
Задачи с произвольными временами выполнения работ почти все являются NP-трудными.&lt;br /&gt;
&lt;br /&gt;
== Задача Джонсона о двух станках &amp;lt;tex&amp;gt;F_2 \mid \mid C_{max}&amp;lt;/tex&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
Это единственная из flow shop задач с произвольными временами выполнения работ, которая решается за полиномиальное время.&lt;br /&gt;
&lt;br /&gt;
Приведём здесь решение задачи без доказательства, его можно посмотреть в [1].&lt;br /&gt;
&lt;br /&gt;
Оптимальное расписание для первой и второй машины будет совпадать. Таким образом, нам требуется найти порядок, в котором будут выполняться работы на каждой машине.&lt;br /&gt;
&lt;br /&gt;
Алгоритм такой: возьмём два пустых списка. Будем рассматривать работы в порядке возрастания &amp;lt;tex&amp;gt;min(p_1, p_2)&amp;lt;/tex&amp;gt;, то есть, минимума из времён выполнения данной работы на первой и второй машине. Если у работы &amp;lt;tex&amp;gt;p_1 \le p_2&amp;lt;/tex&amp;gt;, то добавим её в конец первого списка. В противном случае, добавим её в начало второго списка. Итоговое расписание — это конкатенация первого и второго списков.&lt;br /&gt;
&lt;br /&gt;
Псевдокод:&lt;br /&gt;
 J - множество работ&lt;br /&gt;
 Head &amp;lt;tex&amp;gt; \leftarrow \emptyset &amp;lt;/tex&amp;gt;&lt;br /&gt;
 Tail &amp;lt;tex&amp;gt; \leftarrow \emptyset &amp;lt;/tex&amp;gt;&lt;br /&gt;
 '''while''' J &amp;lt;tex&amp;gt; \ne \emptyset &amp;lt;/tex&amp;gt; &lt;br /&gt;
     '''do'''&lt;br /&gt;
         I &amp;lt;tex&amp;gt; \leftarrow &amp;lt;/tex&amp;gt; работа с минимальным значением &amp;lt;tex&amp;gt;min(p_1, p_2)&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''if''' &amp;lt;tex&amp;gt;p_1 &amp;lt;= p_2&amp;lt;/tex&amp;gt; Head &amp;lt;tex&amp;gt; \leftarrow &amp;lt;/tex&amp;gt; Head &amp;lt;tex&amp;gt;\circ&amp;lt;/tex&amp;gt; I&lt;br /&gt;
         '''else''' Tail &amp;lt;tex&amp;gt; \leftarrow &amp;lt;/tex&amp;gt; I &amp;lt;tex&amp;gt;\circ&amp;lt;/tex&amp;gt; Tail&lt;br /&gt;
         J &amp;lt;tex&amp;gt; \leftarrow &amp;lt;/tex&amp;gt; J &amp;lt;tex&amp;gt; \backslash &amp;lt;/tex&amp;gt; I&lt;br /&gt;
 Result &amp;lt;tex&amp;gt; \leftarrow &amp;lt;/tex&amp;gt; Head &amp;lt;tex&amp;gt;\circ&amp;lt;/tex&amp;gt; Tail&lt;br /&gt;
&lt;br /&gt;
== Задача Джонсона о двух станках с прерываниями &amp;lt;tex&amp;gt;F_2 \mid pmtn \mid C_{max}&amp;lt;/tex&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
Оптимальное решение этой задачи совпадает с решением задачи &amp;lt;tex&amp;gt;F_2 \mid \mid C_{max}&amp;lt;/tex&amp;gt;, приведённой выше. Докажем это.&lt;br /&gt;
&lt;br /&gt;
Пусть у нас есть оптимальное расписание для задачи &amp;lt;tex&amp;gt;F_2 \mid pmtn \mid C_{max}&amp;lt;/tex&amp;gt;. Покажем, что его за конечное число шагов можно преобразовать к расписанию без прерываний, не изменив при это значение &amp;lt;tex&amp;gt;C_{max}&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; 2 &amp;lt;/tex&amp;gt; или более разных промежутка времени. Тогда передвинем более ранний промежуток вправо по оси времени так, чтоб он заканчивался в тот момент, когда начинается второй промежуток, при этом работы, которые были между этими двумя промежутками, сдвинем влево на длину первого промежутка. Расписание при этом осталось корректным, так как работы на машинах по-прежнему не пересекаются, и каждая работа на второй машине делается после того, как она сделана на первой: работа &amp;lt;tex&amp;gt; J &amp;lt;/tex&amp;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;
&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;
== См. также ==&lt;br /&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;
== Литература ==&lt;br /&gt;
*[1][http://books.google.ru/books?id=FrUytMqlCv8C&amp;amp;printsec=frontcover&amp;amp;dq=scheduling+algorithms&amp;amp;hl=ru&amp;amp;sa=X&amp;amp;ei=0MPMT4HqKYSk4gSBm6gp&amp;amp;sqi=2&amp;amp;ved=0CDEQ6AEwAA#v=onepage&amp;amp;q=scheduling%20algorithms&amp;amp;f=false Scheduling Algorithms, Peter Brucker]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47539</id>
		<title>1ripi1sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47539"/>
				<updated>2015-06-05T09:45:17Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: /* Вариант 2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt; и вес &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum w_{i} C_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;C_{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;
===Вариант 1===&lt;br /&gt;
&amp;lt;tex&amp;gt; 1 \mid p_i = 1\mid \sum C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот случай простейший. Ответом будет &amp;lt;tex&amp;gt;\sum\limits_{k = 1}^n(k)&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; членов арифметической прогрессии алгоритм &amp;lt;tex&amp;gt;S_n=\frac{a_1+a_n}2 \cdot n&amp;lt;/tex&amp;gt; будет работает за &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;, но если нужно вывести и само расписание время работы будет &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Вариант 2===&lt;br /&gt;
&amp;lt;tex&amp;gt; 1 \mid p_i = 1\mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для верного выполнения просто выставим работы по порядку невозрастания весов, тогда ответом будет &amp;lt;tex&amp;gt; \sum\limits_{i = 1}^n(w_i C_i)&amp;lt;/tex&amp;gt;, так как мы &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; раз сложим время окончания выполнения одной работы (которое в нашем случае &amp;lt;tex&amp;gt;C_{i-1}+1&amp;lt;/tex&amp;gt;) домноженное на вес этой работы. &lt;br /&gt;
&lt;br /&gt;
Данный алгоритм корректен по [[Задача_о_минимуме/максимуме_скалярного_произведения|теореме о минимуме/максимуме скалярного произведения]], так как мы сопоставляем две последовательности подходящие под условия теоремы.  &lt;br /&gt;
&lt;br /&gt;
Вес работ [[Сортировка|отсортировали]] за &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt;. Алгоритм работает за &amp;lt;tex&amp;gt;O(n + n \log n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Вариант 3===&lt;br /&gt;
&amp;lt;tex&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum f_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_{i}&amp;lt;/tex&amp;gt; {{---}} монотонная функция времени окончания работы &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; для работ &amp;lt;tex&amp;gt;i = 1, 2, \ldots , n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Нам нужно распределить &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ в разное время. Если мы назначим время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; для работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; то цена будет &amp;lt;tex&amp;gt;f_i(t + 1)&amp;lt;/tex&amp;gt;. Функция &amp;lt;tex&amp;gt;f_i&amp;lt;/tex&amp;gt; монотонно неубывающая, тогда работы в расписании надо располагать как можно раньше для получения верного решения. &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; временных интервалов &amp;lt;tex&amp;gt;t_i&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; r_1 \leqslant r_2 \leqslant \ldots \leqslant r_n&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
'''Псевдокод'''&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;tex&amp;gt;t_1 \leftarrow r_1 &amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for'''  &amp;lt;tex&amp;gt; i \leftarrow 2&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      &amp;lt;tex&amp;gt; t_i \leftarrow &amp;lt;/tex&amp;gt; '''max'''&amp;lt;tex&amp;gt;(r_i, \ t_{i-1} - 1)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм работает за &amp;lt;tex&amp;gt;O(n \log n +n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
==Основная задача== &lt;br /&gt;
===Описание алгоритма===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; {{---}} текущий момент времени.&amp;lt;br/&amp;gt;&lt;br /&gt;
Для каждого очередного значения &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt;, которое изменяется от &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; до времени окончания последней работы, будем:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Выбирать работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из множества невыполненных работ, у которой &amp;lt;tex&amp;gt;r_{i} \leqslant time&amp;lt;/tex&amp;gt;, а значение &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt; максимально.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Если мы смогли найти работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, то выполняем её в момент времени &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; и удаляем из множества невыполненных работ.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Увеличиваем &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; на один.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Доказательство корректности алгоритма===&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Расписание, построенное данным алгоритмом, является корректным и оптимальным.&lt;br /&gt;
|proof=&lt;br /&gt;
Доказательство будем вести от противного.&amp;lt;br/&amp;gt;&lt;br /&gt;
Рассмотрим расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, полученное после выполнения нашего алгоритма, и оптимальное расписание &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Возьмём первый момент времени &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;, когда расписания  различаются. Пусть в этот момент времени  в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, будет выполняться работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt;, а в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; {{---}} работа с весом &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Это первый момент, в котором расписания отличаются, значит в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; выполнится в момент времени &amp;lt;tex&amp;gt;t_{2} &amp;gt; t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Поменяем местами работы с весами &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и полуим расписание &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Это возможно, потому что время появления этих работ не меньше &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При такой перестановке ответы на задачу для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt; будут отличаться на &lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;tex&amp;gt;t_{1}w_{2} + t_{2}w_{1} - t_{1}w_{1} + t_{2}w_{2} = t_{1}(w_{2} - w_{1}) + t_{2}(w_{1} - w_{2}) = (t_{1} - t_{2})(w_{2} - w_{1})&amp;lt;/tex&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Первая скобка отрицательная: &amp;lt;tex&amp;gt;t_{1} &amp;lt; t_{2}&amp;lt;/tex&amp;gt;. Вторая скобка тоже отрицательная из того, что в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_1&amp;lt;/tex&amp;gt; выполняется раньше, значит её вес должен быть больше &amp;lt;tex&amp;gt;w_2&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Итого имеем, что ответ для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; больше, чем ответ для &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Следовательно расписание &amp;lt;tex&amp;gt;S_2&amp;lt;/tex&amp;gt; неоптимальное. Получили противоречие. Значит не существует такого момента времени, когда расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; отличается от оптимального. Следовательно мы доказали, что оно оптимальное.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Псевдокод===&lt;br /&gt;
&lt;br /&gt;
====Реализация 1====&lt;br /&gt;
   &amp;lt;tex&amp;gt; S \leftarrow \{1 \ldots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{time} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{answer} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''while''' &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow null &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt; i \in S&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt; r_{i} \leqslant \mathtt{time}&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt;w_i \geqslant \max\limits_{j \in S, j = 1 \ldots n} w_j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; j \leftarrow i &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; \mathtt{time++}&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;n + \max\limits_{i = 1 \ldots n} r_{i}&amp;lt;/tex&amp;gt; шагов цикла. Определить максимум в множестве можно за время &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, используя , например, [[:Категория:Приоритетные_очереди|очередь с приоритетами]]. Значит общее время работы алгоритма &amp;lt;tex&amp;gt;O((n + \max\limits_{i = 1 \ldots n} r_{i})\log n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Реализация 2====&lt;br /&gt;
Перед началом алгоритма [[Сортировка|отсортируем]] работы по порядку неубывания веса.&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{time} \leftarrow r_1&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{answer} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for''' &amp;lt;tex&amp;gt;i \leftarrow 1 &amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      '''if'''  &amp;lt;tex&amp;gt; r_{i} \leqslant \mathtt{time}&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''else'''&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{time} \leftarrow r_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В начале алгоритма сортируем работы &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt; времени. Затем мы тратим &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; на получение ответа. Тогда суммарное время работы алгоритма составит &amp;lt;tex&amp;gt;O(n \log n + n )&amp;lt;/tex&amp;gt; что есть &amp;lt;tex&amp;gt;O(n (\log n + 1))&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;
* [[1ridipi1|&amp;lt;tex&amp;gt;1 | r_{i}, d_{i}, p_{i}=1 | -&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 19-20&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 38-39&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 84-85&lt;br /&gt;
* Лазарев А.А., Мусатова Е.Г., Кварацхелия А.Г., Гафаров Е.Р. Пособие по теории расписаний.&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47365</id>
		<title>1ripi1sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47365"/>
				<updated>2015-06-03T20:40:03Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt; и вес &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum w_{i} C_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;C_{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;
===Вариант 1===&lt;br /&gt;
&amp;lt;tex&amp;gt; 1 \mid p_i = 1\mid \sum C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот случай простейший. Ответом будет &amp;lt;tex&amp;gt;\sum\limits_{k = 1}^n(k)&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; членов арифметической прогрессии алгоритм &amp;lt;tex&amp;gt;S_n=\frac{a_1+a_n}2 \cdot n&amp;lt;/tex&amp;gt; будет работает за &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;, но если нужно вывести и само расписание время работы будет &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Вариант 2===&lt;br /&gt;
&amp;lt;tex&amp;gt; 1 \mid p_i = 1\mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для верного выполнения просто выставим работы по порядку невозрастания весов, тогда ответом будет &amp;lt;tex&amp;gt; \sum\limits_{i = 1}^n(w_i C_i)&amp;lt;/tex&amp;gt;, так как мы &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; раз сложим время окончания выполнения одной работы (которое в нашем случае &amp;lt;tex&amp;gt;C_{i-1}+1&amp;lt;/tex&amp;gt;) домноженное на вес этой работы. &lt;br /&gt;
&lt;br /&gt;
Покажем что алгоритм [[Методы_решения_задач_теории_расписаний|жадного построения расписания]] корректен. &amp;lt;tex&amp;gt;w_i C_i \geqslant w_j C_j&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;w_i C_i&amp;lt;/tex&amp;gt; произведение на текущем шаге до сортировки, а &amp;lt;tex&amp;gt;w_j C_j&amp;lt;/tex&amp;gt; после. Полученное произведение &amp;lt;tex&amp;gt;w_j C_j&amp;lt;/tex&amp;gt; «более похоже» на оптимальное, чем произведение &amp;lt;tex&amp;gt;w_i C_i&amp;lt;/tex&amp;gt;. Тогда применение жадного алгоритма дает верный ответ.&lt;br /&gt;
&lt;br /&gt;
Вес работ [[Сортировка|отсортировали]] за &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt;. Алгоритм работает за &amp;lt;tex&amp;gt;O(n + n \log n)&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
===Вариант 3===&lt;br /&gt;
&amp;lt;tex&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum f_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_{i}&amp;lt;/tex&amp;gt; {{---}} монотонная функция времени окончания работы &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; для работ &amp;lt;tex&amp;gt;i = 1, 2, \ldots , n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Нам нужно распределить &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ в разное время. Если мы назначим время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; для работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; то цена будет &amp;lt;tex&amp;gt;f_i(t + 1)&amp;lt;/tex&amp;gt;. Функция &amp;lt;tex&amp;gt;f_i&amp;lt;/tex&amp;gt; монотонно неубывающая, тогда работы в расписании надо располагать как можно раньше для получения верного решения. &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; временных интервалов &amp;lt;tex&amp;gt;t_i&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; r_1 \leqslant r_2 \leqslant \ldots \leqslant r_n&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
'''Псевдокод'''&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;tex&amp;gt;t_1 \leftarrow r_1 &amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for'''  &amp;lt;tex&amp;gt; i \leftarrow 2&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      &amp;lt;tex&amp;gt; t_i \leftarrow &amp;lt;/tex&amp;gt; '''max'''&amp;lt;tex&amp;gt;(r_i, \ t_{i-1} - 1)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм работает за &amp;lt;tex&amp;gt;O(n \log n +n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
==Основная задача== &lt;br /&gt;
===Описание алгоритма===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; {{---}} текущий момент времени.&amp;lt;br/&amp;gt;&lt;br /&gt;
Для каждого очередного значения &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt;, которое изменяется от &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; до времени окончания последней работы, будем:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Выбирать работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из множества невыполненных работ, у которой &amp;lt;tex&amp;gt;r_{i} \leqslant time&amp;lt;/tex&amp;gt;, а значение &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt; максимально.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Если мы смогли найти работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, то выполняем её в момент времени &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; и удаляем из множества невыполненных работ.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Увеличиваем &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; на один.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Доказательство корректности алгоритма===&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Расписание, построенное данным алгоритмом, является корректным и оптимальным.&lt;br /&gt;
|proof=&lt;br /&gt;
Доказательство будем вести от противного.&amp;lt;br/&amp;gt;&lt;br /&gt;
Рассмотрим расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, полученное после выполнения нашего алгоритма, и оптимальное расписание &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Возьмём первый момент времени &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;, когда расписания  различаются. Пусть в этот момент времени  в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, будет выполняться работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt;, а в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; {{---}} работа с весом &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Это первый момент, в котором расписания отличаются, значит в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; выполнится в момент времени &amp;lt;tex&amp;gt;t_{2} &amp;gt; t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Поменяем местами работы с весами &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и полуим расписание &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Это возможно, потому что время появления этих работ не меньше &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При такой перестановке ответы на задачу для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt; будут отличаться на &lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;tex&amp;gt;t_{1}w_{2} + t_{2}w_{1} - t_{1}w_{1} + t_{2}w_{2} = t_{1}(w_{2} - w_{1}) + t_{2}(w_{1} - w_{2}) = (t_{1} - t_{2})(w_{2} - w_{1})&amp;lt;/tex&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Первая скобка отрицательная: &amp;lt;tex&amp;gt;t_{1} &amp;lt; t_{2}&amp;lt;/tex&amp;gt;. Вторая скобка тоже отрицательная из того, что в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_1&amp;lt;/tex&amp;gt; выполняется раньше, значит её вес должен быть больше &amp;lt;tex&amp;gt;w_2&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Итого имеем, что ответ для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; больше, чем ответ для &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Следовательно расписание &amp;lt;tex&amp;gt;S_2&amp;lt;/tex&amp;gt; неоптимальное. Получили противоречие. Значит не существует такого момента времени, когда расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; отличается от оптимального. Следовательно мы доказали, что оно оптимальное.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Псевдокод===&lt;br /&gt;
&lt;br /&gt;
====Реализация 1====&lt;br /&gt;
   &amp;lt;tex&amp;gt; S \leftarrow \{1 \ldots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{time} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{answer} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''while''' &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow null &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt; i \in S&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt; r_{i} \leqslant \mathtt{time}&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt;w_i \geqslant \max\limits_{j \in S, j = 1 \ldots n} w_j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; j \leftarrow i &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; \mathtt{time++}&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;n + \max\limits_{i = 1 \ldots n} r_{i}&amp;lt;/tex&amp;gt; шагов цикла. Определить максимум в множестве можно за время &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, используя , например, [[:Категория:Приоритетные_очереди|очередь с приоритетами]]. Значит общее время работы алгоритма &amp;lt;tex&amp;gt;O((n + \max\limits_{i = 1 \ldots n} r_{i})\log n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Реализация 2====&lt;br /&gt;
Перед началом алгоритма [[Сортировка|отсортируем]] работы по порядку неубывания веса.&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{time} \leftarrow r_1&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{answer} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for''' &amp;lt;tex&amp;gt;i \leftarrow 1 &amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      '''if'''  &amp;lt;tex&amp;gt; r_{i} \leqslant \mathtt{time}&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''else'''&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{time} \leftarrow r_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В начале алгоритма сортируем работы &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt; времени. Затем мы тратим &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; на получение ответа. Тогда суммарное время работы алгоритма составит &amp;lt;tex&amp;gt;O(n \log n + n )&amp;lt;/tex&amp;gt; что есть &amp;lt;tex&amp;gt;O(n (\log n + 1))&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;
* [[1ridipi1|&amp;lt;tex&amp;gt;1 | r_{i}, d_{i}, p_{i}=1 | -&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 19-20&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 38-39&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 84-85&lt;br /&gt;
* Лазарев А.А., Мусатова Е.Г., Кварацхелия А.Г., Гафаров Е.Р. Пособие по теории расписаний.&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47355</id>
		<title>1ripi1sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47355"/>
				<updated>2015-06-03T19:37:00Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt; и вес &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum w_{i} C_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;C_{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;
===Вариант 1===&lt;br /&gt;
&amp;lt;tex&amp;gt; 1 \mid p_i = 1\mid \sum C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот случай простейший. Ответом будет &amp;lt;tex&amp;gt;\sum\limits_{k = 1}^n(k)&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; членов арифметической прогрессии алгоритм &amp;lt;tex&amp;gt;S_n=\frac{a_1+a_n}2 \cdot n&amp;lt;/tex&amp;gt; будет работает за &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;, но если нужно вывести и само расписание время работы будет &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Вариант 2===&lt;br /&gt;
&amp;lt;tex&amp;gt; 1 \mid p_i = 1\mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для верного выполнения просто выставим работы по порядку невозрастания весов, тогда ответом будет &amp;lt;tex&amp;gt; \sum\limits_{i = 1}^n(w_i C_i)&amp;lt;/tex&amp;gt;, так как мы &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; раз сложим время окончания выполнения одной работы (которое в нашем случае &amp;lt;tex&amp;gt;C_{i-1}+1&amp;lt;/tex&amp;gt;) домноженное на вес этой работы. То есть решаем жадным алгоритмом: на каждом шаге получаем оптимальное решение и в результате верный ответ. Вес работ [[Сортировка|отсортировали]] за &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt;. Алгоритм работает за &amp;lt;tex&amp;gt;O(n + n \log n)&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
===Вариант 3===&lt;br /&gt;
&amp;lt;tex&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum f_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_{i}&amp;lt;/tex&amp;gt; {{---}} монотонная функция времени окончания работы &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; для работ &amp;lt;tex&amp;gt;i = 1, 2, \ldots , n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Нам нужно распределить &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ в разное время. Если мы назначим время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; для работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; то цена будет &amp;lt;tex&amp;gt;f_i(t + 1)&amp;lt;/tex&amp;gt;. Функция &amp;lt;tex&amp;gt;f_i&amp;lt;/tex&amp;gt; монотонно неубывающая, тогда работы в расписании надо располагать как можно раньше для получения верного решения. &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; временных интервалов &amp;lt;tex&amp;gt;t_i&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; r_1 \leqslant r_2 \leqslant \ldots \leqslant r_n&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
'''Псевдокод'''&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;tex&amp;gt;t_1 \leftarrow r_1 &amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for'''  &amp;lt;tex&amp;gt; i \leftarrow 2&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      &amp;lt;tex&amp;gt; t_i \leftarrow &amp;lt;/tex&amp;gt; '''max'''&amp;lt;tex&amp;gt;(r_i, \ t_{i-1} - 1)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм работает за &amp;lt;tex&amp;gt;O(n \log n +n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
==Основная задача== &lt;br /&gt;
===Описание алгоритма===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; {{---}} текущий момент времени.&amp;lt;br/&amp;gt;&lt;br /&gt;
Для каждого очередного значения &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt;, которое изменяется от &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; до времени окончания последней работы, будем:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Выбирать работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из множества невыполненных работ, у которой &amp;lt;tex&amp;gt;r_{i} \leqslant time&amp;lt;/tex&amp;gt;, а значение &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt; максимально.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Если мы смогли найти работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, то выполняем её в момент времени &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; и удаляем из множества невыполненных работ.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Увеличиваем &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; на один.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Доказательство корректности алгоритма===&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Расписание, построенное данным алгоритмом, является корректным и оптимальным.&lt;br /&gt;
|proof=&lt;br /&gt;
Доказательство будем вести от противного.&amp;lt;br/&amp;gt;&lt;br /&gt;
Рассмотрим расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, полученное после выполнения нашего алгоритма, и оптимальное расписание &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Возьмём первый момент времени &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;, когда расписания  различаются. Пусть в этот момент времени  в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, будет выполняться работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt;, а в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; {{---}} работа с весом &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Это первый момент, в котором расписания отличаются, значит в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; выполнится в момент времени &amp;lt;tex&amp;gt;t_{2} &amp;gt; t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Поменяем местами работы с весами &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и полуим расписание &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Это возможно, потому что время появления этих работ не меньше &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При такой перестановке ответы на задачу для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt; будут отличаться на &lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;tex&amp;gt;t_{1}w_{2} + t_{2}w_{1} - t_{1}w_{1} + t_{2}w_{2} = t_{1}(w_{2} - w_{1}) + t_{2}(w_{1} - w_{2}) = (t_{1} - t_{2})(w_{2} - w_{1})&amp;lt;/tex&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Первая скобка отрицательная: &amp;lt;tex&amp;gt;t_{1} &amp;lt; t_{2}&amp;lt;/tex&amp;gt;. Вторая скобка тоже отрицательная из того, что в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_1&amp;lt;/tex&amp;gt; выполняется раньше, значит её вес должен быть больше &amp;lt;tex&amp;gt;w_2&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Итого имеем, что ответ для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; больше, чем ответ для &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Следовательно расписание &amp;lt;tex&amp;gt;S_2&amp;lt;/tex&amp;gt; неоптимальное. Получили противоречие. Значит не существует такого момента времени, когда расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; отличается от оптимального. Следовательно мы доказали, что оно оптимальное.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Псевдокод===&lt;br /&gt;
&lt;br /&gt;
====Реализация 1====&lt;br /&gt;
   &amp;lt;tex&amp;gt; S \leftarrow \{1 \ldots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{time} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{answer} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''while''' &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow null &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt; i \in S&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt; r_{i} \leqslant \mathtt{time}&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt;w_i \geqslant \max\limits_{j \in S, j = 1 \ldots n} w_j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; j \leftarrow i &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; \mathtt{time++}&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;n + \max\limits_{i = 1 \ldots n} r_{i}&amp;lt;/tex&amp;gt; шагов цикла. Определить максимум в множестве можно за время &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, используя , например, [[:Категория:Приоритетные_очереди|очередь с приоритетами]]. Значит общее время работы алгоритма &amp;lt;tex&amp;gt;O((n + \max\limits_{i = 1 \ldots n} r_{i})\log n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Реализация 2====&lt;br /&gt;
Перед началом алгоритма [[Сортировка|отсортируем]]работы по порядку неубывания веса.&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{time} \leftarrow r_1&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{answer} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for''' &amp;lt;tex&amp;gt;i \leftarrow 1 &amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      '''if'''  &amp;lt;tex&amp;gt; r_{i} \leqslant \mathtt{time}&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''else'''&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{time} \leftarrow r_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В начале алгоритма сортируем работы &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt; времени. Затем мы тратим &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; на получение ответа. Тогда суммарное время работы алгоритма составит &amp;lt;tex&amp;gt;O(n \log n + n )&amp;lt;/tex&amp;gt; что есть &amp;lt;tex&amp;gt;O(n (\log n + 1))&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;
* [[1ridipi1|&amp;lt;tex&amp;gt;1 | r_{i}, d_{i}, p_{i}=1 | -&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 19-20&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 38-39&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 84-85&lt;br /&gt;
* Лазарев А.А., Мусатова Е.Г., Кварацхелия А.Г., Гафаров Е.Р. Пособие по теории расписаний.&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47335</id>
		<title>1ripi1sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47335"/>
				<updated>2015-06-03T17:40:51Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt; и вес &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum w_{i} C_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;C_{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;
===Вариант 1===&lt;br /&gt;
&amp;lt;tex&amp;gt; 1 \mid p_i = 1\mid \sum C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот случай простейший. Ответом будет &amp;lt;tex&amp;gt;\sum\limits_{k = 1}^n(k)&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; членов арифметической прогрессии алгоритм &amp;lt;tex&amp;gt;S_n=\frac{a_1+a_n}2 \cdot n&amp;lt;/tex&amp;gt; будет работает за &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Вариант 2===&lt;br /&gt;
&amp;lt;tex&amp;gt; 1 \mid p_i = 1\mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для верного выполнения просто выставим работы по порядку невозрастания весов, тогда ответом будет &amp;lt;tex&amp;gt; \sum\limits_{i = 1}^n(w_i C_i)&amp;lt;/tex&amp;gt;, так как мы &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; раз сложим время окончания выполнения одной работы (которое в нашем случае &amp;lt;tex&amp;gt;C_{i-1}+1&amp;lt;/tex&amp;gt;) домноженное на вес этой работы. Вес работ [[Сортировка|отсортировали]] за &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt;. Алгоритм работает за &amp;lt;tex&amp;gt;O(n + n \log n)&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
===Вариант 3===&lt;br /&gt;
&amp;lt;tex&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum f_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_{i}&amp;lt;/tex&amp;gt; {{---}} монотонная функция времени окончания работы &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; для работ &amp;lt;tex&amp;gt;i = 1, 2, \ldots , n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Нам нужно распределить &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ в разное время. Если мы назначим время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; для работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; то цена будет &amp;lt;tex&amp;gt;f_i(t + 1)&amp;lt;/tex&amp;gt;. Функция &amp;lt;tex&amp;gt;f_i&amp;lt;/tex&amp;gt; монотонно неубывающая, тогда работы в расписании надо располагать как можно раньше для получения верного решения. &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; временных интервалов &amp;lt;tex&amp;gt;t_i&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; r_1 \leqslant r_2 \leqslant \ldots \leqslant r_n&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
'''Псевдокод'''&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;tex&amp;gt;t_1 \leftarrow r_1 &amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for'''  &amp;lt;tex&amp;gt; i \leftarrow 2&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      &amp;lt;tex&amp;gt; t_i \leftarrow &amp;lt;/tex&amp;gt; '''max'''&amp;lt;tex&amp;gt;(r_i, \ t_{i-1} - 1)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм работает за &amp;lt;tex&amp;gt;O(n \log n +n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
==Основная задача== &lt;br /&gt;
===Описание алгоритма===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; {{---}} текущий момент времени.&amp;lt;br/&amp;gt;&lt;br /&gt;
Для каждого очередного значения &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt;, которое изменяется от &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; до времени окончания последней работы, будем:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Выбирать работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из множества невыполненных работ, у которой &amp;lt;tex&amp;gt;r_{i} \leqslant time&amp;lt;/tex&amp;gt;, а значение &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt; максимально.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Если мы смогли найти работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, то выполняем её в момент времени &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; и удаляем из множества невыполненных работ.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Увеличиваем &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; на один.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Доказательство корректности алгоритма===&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Расписание, построенное данным алгоритмом, является корректным и оптимальным.&lt;br /&gt;
|proof=&lt;br /&gt;
Доказательство будем вести от противного.&amp;lt;br/&amp;gt;&lt;br /&gt;
Рассмотрим расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, полученное после выполнения нашего алгоритма, и оптимальное расписание &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Возьмём первый момент времени &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;, когда расписания  различаются. Пусть в этот момент времени  в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, будет выполняться работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt;, а в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; {{---}} работа с весом &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Это первый момент, в котором расписания отличаются, значит в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; выполнится в момент времени &amp;lt;tex&amp;gt;t_{2} &amp;gt; t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Поменяем местами работы с весами &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и полуим расписание &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Это возможно, потому что время появления этих работ не меньше &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При такой перестановке ответы на задачу для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt; будут отличаться на &lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;tex&amp;gt;t_{1}w_{2} + t_{2}w_{1} - t_{1}w_{1} + t_{2}w_{2} = t_{1}(w_{2} - w_{1}) + t_{2}(w_{1} - w_{2}) = (t_{1} - t_{2})(w_{2} - w_{1})&amp;lt;/tex&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Первая скобка отрицательная: &amp;lt;tex&amp;gt;t_{1} &amp;lt; t_{2}&amp;lt;/tex&amp;gt;. Вторая скобка тоже отрицательная из того, что в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_1&amp;lt;/tex&amp;gt; выполняется раньше, значит её вес должен быть больше &amp;lt;tex&amp;gt;w_2&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Итого имеем, что ответ для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; больше, чем ответ для &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Следовательно расписание &amp;lt;tex&amp;gt;S_2&amp;lt;/tex&amp;gt; неоптимальное. Получили противоречие. Значит не существует такого момента времени, когда расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; отличается от оптимального. Следовательно мы доказали, что оно оптимальное.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Псевдокод===&lt;br /&gt;
&lt;br /&gt;
====Реализация 1====&lt;br /&gt;
   &amp;lt;tex&amp;gt; S \leftarrow \{1 \ldots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{time} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{answer} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''while''' &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow null &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt; i \in S&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt; r_{i} \leqslant \mathtt{time}&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt;w_i \geqslant \max\limits_{j \in S, j = 1 \ldots n} w_j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; j \leftarrow i &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; \mathtt{time++}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Реализация 2====&lt;br /&gt;
Эта реализация использует [[Двоичная_куча|двоичную кучу]] &amp;lt;tex&amp;gt;\mathtt{Heap}&amp;lt;/tex&amp;gt; в которой операции вставки и извлечения выполняются за &amp;lt;tex&amp;gt;O(\log n)&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; S \leftarrow \{1 \ldots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{time} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{answer} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for''' &amp;lt;tex&amp;gt;i \leftarrow 1 &amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      Heap.insert(&amp;lt;tex&amp;gt;w_i&amp;lt;/tex&amp;gt;)&lt;br /&gt;
   '''while''' &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow null &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt; i \in S&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt; r_{i} \leqslant \mathtt{time}&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt;w_i \geqslant &amp;lt;/tex&amp;gt; Heap.Max()&lt;br /&gt;
         &amp;lt;tex&amp;gt; j \leftarrow i &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         Heap.extractMax()&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; \mathtt{time++}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Сложность алгоритмов===&lt;br /&gt;
====Алгоритм 1====&lt;br /&gt;
Множество &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; станет пустым не позже, чем через &amp;lt;tex&amp;gt;n + \max\limits_{i = 1 \ldots n} r_{i}&amp;lt;/tex&amp;gt; шагов цикла. Определить максимум в множестве можно за время &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, используя , например, [[:Категория:Приоритетные_очереди|очередь с приоритетами]]. Значит общее время работы алгоритма &amp;lt;tex&amp;gt;O((n + \max\limits_{i = 1 \ldots n} r_{i})\log n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Алгоритм 2====&lt;br /&gt;
В начале алгоритма мы добавляем все элементы &amp;lt;tex&amp;gt;w_i&amp;lt;/tex&amp;gt; в двоичную кучу тратя на это &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt; времени. Затем мы тратим &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt; на получение ответа. Тогда суммарное время работы алгоритма составит &amp;lt;tex&amp;gt;O(n \log n + n \log n)&amp;lt;/tex&amp;gt; что есть &amp;lt;tex&amp;gt;O(n \log n)&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;
* [[1ridipi1|&amp;lt;tex&amp;gt;1 | r_{i}, d_{i}, p_{i}=1 | -&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 19-20&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 38-39&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 84-85&lt;br /&gt;
* Лазарев А.А., Мусатова Е.Г., Кварацхелия А.Г., Гафаров Е.Р. Пособие по теории расписаний.&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47334</id>
		<title>1ripi1sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47334"/>
				<updated>2015-06-03T17:38:17Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt; и вес &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum w_{i} C_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;C_{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;
===Вариант 1===&lt;br /&gt;
&amp;lt;tex&amp;gt; 1 \mid p_i = 1\mid \sum C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот случай простейший. Ответом будет &amp;lt;tex&amp;gt;\sum\limits_{k = 1}^n(k)&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; членов арифметической прогрессии алгоритм &amp;lt;tex&amp;gt;S_n=\frac{a_1+a_n}2 \cdot n&amp;lt;/tex&amp;gt; будет работает за &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Вариант 2===&lt;br /&gt;
&amp;lt;tex&amp;gt; 1 \mid p_i = 1\mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для верного выполнения просто выставим работы по порядку невозрастания весов, тогда ответом будет &amp;lt;tex&amp;gt; \sum\limits_{i = 1}^n(w_i C_i)&amp;lt;/tex&amp;gt;, так как мы &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; раз сложим время окончания выполнения одной работы (которое в нашем случае &amp;lt;tex&amp;gt;C_{i-1}+1&amp;lt;/tex&amp;gt;) домноженное на вес этой работы. Вес работ [[Сортировка|отсортировали]] за &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt;. Алгоритм работает за &amp;lt;tex&amp;gt;O(n + n \log n)&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
===Вариант 3===&lt;br /&gt;
&amp;lt;tex&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum f_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_{i}&amp;lt;/tex&amp;gt; {{---}} монотонная функция времени окончания работы &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; для работ &amp;lt;tex&amp;gt;i = 1, 2, \ldots , n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Нам нужно распределить &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ в разное время. Если мы назначим время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; для работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; то цена будет &amp;lt;tex&amp;gt;f_i(t + 1)&amp;lt;/tex&amp;gt;. Функция &amp;lt;tex&amp;gt;f_i&amp;lt;/tex&amp;gt; монотонно неубывающая, тогда работы в расписании надо располагать как можно раньше для получения верного решения. &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; временных интервалов &amp;lt;tex&amp;gt;t_i&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; r_1 \leqslant r_2 \leqslant \ldots \leqslant r_n&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
'''Псевдокод'''&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;tex&amp;gt;t_1 \leftarrow r_1 &amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for'''  &amp;lt;tex&amp;gt; i \leftarrow 2&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      &amp;lt;tex&amp;gt; t_i \leftarrow &amp;lt;/tex&amp;gt; '''max'''&amp;lt;tex&amp;gt;(r_i, \ t_{i-1} - 1)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм работает за &amp;lt;tex&amp;gt;O(n \log n +n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
==Основная задача== &lt;br /&gt;
===Описание алгоритма===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; {{---}} текущий момент времени.&amp;lt;br/&amp;gt;&lt;br /&gt;
Для каждого очередного значения &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt;, которое изменяется от &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; до времени окончания последней работы, будем:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Выбирать работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из множества невыполненных работ, у которой &amp;lt;tex&amp;gt;r_{i} \leqslant time&amp;lt;/tex&amp;gt;, а значение &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt; максимально.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Если мы смогли найти работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, то выполняем её в момент времени &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; и удаляем из множества невыполненных работ.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Увеличиваем &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; на один.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Доказательство корректности алгоритма===&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Расписание, построенное данным алгоритмом, является корректным и оптимальным.&lt;br /&gt;
|proof=&lt;br /&gt;
Доказательство будем вести от противного.&amp;lt;br/&amp;gt;&lt;br /&gt;
Рассмотрим расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, полученное после выполнения нашего алгоритма, и оптимальное расписание &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Возьмём первый момент времени &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;, когда расписания  различаются. Пусть в этот момент времени  в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, будет выполняться работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt;, а в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; {{---}} работа с весом &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Это первый момент, в котором расписания отличаются, значит в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; выполнится в момент времени &amp;lt;tex&amp;gt;t_{2} &amp;gt; t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Поменяем местами работы с весами &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и полуим расписание &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Это возможно, потому что время появления этих работ не меньше &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При такой перестановке ответы на задачу для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt; будут отличаться на &lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;tex&amp;gt;t_{1}w_{2} + t_{2}w_{1} - t_{1}w_{1} + t_{2}w_{2} = t_{1}(w_{2} - w_{1}) + t_{2}(w_{1} - w_{2}) = (t_{1} - t_{2})(w_{2} - w_{1})&amp;lt;/tex&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Первая скобка отрицательная: &amp;lt;tex&amp;gt;t_{1} &amp;lt; t_{2}&amp;lt;/tex&amp;gt;. Вторая скобка тоже отрицательная из того, что в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_1&amp;lt;/tex&amp;gt; выполняется раньше, значит её вес должен быть больше &amp;lt;tex&amp;gt;w_2&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Итого имеем, что ответ для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; больше, чем ответ для &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Следовательно расписание &amp;lt;tex&amp;gt;S_2&amp;lt;/tex&amp;gt; неоптимальное. Получили противоречие. Значит не существует такого момента времени, когда расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; отличается от оптимального. Следовательно мы доказали, что оно оптимальное.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Псевдокод===&lt;br /&gt;
&lt;br /&gt;
====Алгоритм 1====&lt;br /&gt;
   &amp;lt;tex&amp;gt; S \leftarrow \{1 \ldots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{time} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{answer} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''while''' &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow null &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt; i \in S&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt; r_{i} \leqslant \mathtt{time}&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt;w_i \geqslant \max\limits_{j \in S, j = 1 \ldots n} w_j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; j \leftarrow i &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; \mathtt{time++}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Алгоритм 2====&lt;br /&gt;
Этот алгоритм реализован с помощью [[Двоичная_куча|двоичной кучи]] &amp;lt;tex&amp;gt;\mathtt{Heap}&amp;lt;/tex&amp;gt; в которой операции вставки и извлечения выполняются за &amp;lt;tex&amp;gt;O(\log n)&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; S \leftarrow \{1 \ldots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{time} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{answer} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for''' &amp;lt;tex&amp;gt;i \leftarrow 1 &amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      Heap.insert(&amp;lt;tex&amp;gt;w_i&amp;lt;/tex&amp;gt;)&lt;br /&gt;
   '''while''' &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow null &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt; i \in S&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt; r_{i} \leqslant \mathtt{time}&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt;w_i \geqslant &amp;lt;/tex&amp;gt; Heap.Max()&lt;br /&gt;
         &amp;lt;tex&amp;gt; j \leftarrow i &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         Heap.ExtractMax()&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; \mathtt{time++}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Сложность алгоритмов===&lt;br /&gt;
====Алгоритм 1====&lt;br /&gt;
Множество &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; станет пустым не позже, чем через &amp;lt;tex&amp;gt;n + \max\limits_{i = 1 \ldots n} r_{i}&amp;lt;/tex&amp;gt; шагов цикла. Определить максимум в множестве можно за время &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, используя , например, [[:Категория:Приоритетные_очереди|очередь с приоритетами]]. Значит общее время работы алгоритма &amp;lt;tex&amp;gt;O((n + \max\limits_{i = 1 \ldots n} r_{i})\log n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Алгоритм 2====&lt;br /&gt;
В начале алгоритма мы добавляем все элементы &amp;lt;tex&amp;gt;w_i&amp;lt;/tex&amp;gt; в двоичную кучу тратя на это &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt; времени. Затем мы тратим &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt; на получение ответа. Тогда суммарное время работы алгоритма составит &amp;lt;tex&amp;gt;O(n \log n + n \log n)&amp;lt;/tex&amp;gt; что есть &amp;lt;tex&amp;gt;O(n \log n)&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;
* [[1ridipi1|&amp;lt;tex&amp;gt;1 | r_{i}, d_{i}, p_{i}=1 | -&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 19-20&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 38-39&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 84-85&lt;br /&gt;
* Лазарев А.А., Мусатова Е.Г., Кварацхелия А.Г., Гафаров Е.Р. Пособие по теории расписаний.&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Fpij1sumwu&amp;diff=47332</id>
		<title>Fpij1sumwu</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Fpij1sumwu&amp;diff=47332"/>
				<updated>2015-06-03T17:36:07Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;F \mid p_{ij} = 1 \mid \sum w_iu_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; станков, на которых нужно обработать &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; деталей. Каждую деталь нужно обработать по очереди на всех станках. Любая работа на любом станке выполняется единицу времени. Для каждой работы есть дедлайн &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; {{---}} время, до которого она должна быть закончена, и штраф &amp;lt;tex&amp;gt;w_i&amp;lt;/tex&amp;gt;, который нужно будет выплатить в случае, если работа была закончена после &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt;. Необходимо минимизировать суммарный штраф, который придется выплатить.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Алгоритм==&lt;br /&gt;
&lt;br /&gt;
===Описание алгоритма===&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Существует оптимальное расписание, в котором каждая работа делается непрерывно.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим расписание, в котором есть работы, которые делаются не непрерывно. Рассмотрим самый ранний разрыв: работа &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; делалась в моменты &amp;lt;tex&amp;gt;t(i), t(i) + 1, \ldots, t(i) + k&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;k &amp;lt; m&amp;lt;/tex&amp;gt;, но не делалась в момент времени &amp;lt;tex&amp;gt;t(i) + k + 1&amp;lt;/tex&amp;gt;. Докажем, что в момент времени &amp;lt;tex&amp;gt;t(i) + k + 1&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;k + 1&amp;lt;/tex&amp;gt;-й станок простаивает и можно продолжить делать &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ю работу. &lt;br /&gt;
&lt;br /&gt;
Пусть в момент времени &amp;lt;tex&amp;gt;t(i) + k + 1&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;k + 1&amp;lt;/tex&amp;gt;-м станке делается работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;. &lt;br /&gt;
В &amp;lt;tex&amp;gt;t(i) + k&amp;lt;/tex&amp;gt;-й момент времени &amp;lt;tex&amp;gt;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;t(i) + k + 1&amp;lt;/tex&amp;gt;-й момент &amp;lt;tex&amp;gt;k + 1&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;
&lt;br /&gt;
По этому утверждению, если работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; начали делать в &amp;lt;tex&amp;gt;t(i)&amp;lt;/tex&amp;gt;, то закончена она будет в &amp;lt;tex&amp;gt;t(i) + m&amp;lt;/tex&amp;gt;. Найдем время &amp;lt;tex&amp;gt;d'_i&amp;lt;/tex&amp;gt; такое, что начав выполнять в него работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, мы успеем выполнить ее до &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;d'_i = d_i - m&amp;lt;/tex&amp;gt;. Таким образом, вычтя из всех &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; число &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;, мы свели задачу к &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum w_i U_i&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Построив оптимальное расписание для &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum w_i U_i&amp;lt;/tex&amp;gt;, мы найдем времена, в которые нужно начинать выполнять работы. По утверждению выше, работы можно выполнять непрерывно.&lt;br /&gt;
&lt;br /&gt;
===Сложность алгоритма===&lt;br /&gt;
Задача &amp;lt;tex&amp;gt;F \mid p_{i j} = 1 \mid \sum w_iu_i&amp;lt;/tex&amp;gt; за &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; сводится к задаче &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum w_i u_i&amp;lt;/tex&amp;gt;. Задача &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum u_iw_i&amp;lt;/tex&amp;gt; решается за &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt;. После решения этой задачи, нужно вывести ответ, имеющий размер &amp;lt;tex&amp;gt;O(nm)&amp;lt;/tex&amp;gt;. Значит, итоговая сложность алгоритма {{---}} &amp;lt;tex&amp;gt;O(n \log n + nm)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==См. также.==&lt;br /&gt;
* [[Классификация задач]]&lt;br /&gt;
* [[Flow shop]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* Лазарев А.А., Мусатова Е.Г., Кварацхелия А.Г., Гафаров Е.Р. Пособие по теории расписаний.&lt;br /&gt;
* Vladimír Modrák, R. Sudhakara Pandian. FLOW SHOP SCHEDULING ALGORITHM TO MINIMIZE COMPLETION TIME FOR -JOBS -MACHINES PROBLEM&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47331</id>
		<title>1ripi1sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47331"/>
				<updated>2015-06-03T17:33:47Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt; и вес &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum w_{i} C_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;C_{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;
===Вариант 1===&lt;br /&gt;
&amp;lt;tex&amp;gt; 1 \mid p_i = 1\mid \sum C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот случай простейший. Ответом будет &amp;lt;tex&amp;gt;\sum\limits_{k = 1}^n(k)&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; членов арифметической прогрессии алгоритм &amp;lt;tex&amp;gt;S_n=\frac{a_1+a_n}2 \cdot n&amp;lt;/tex&amp;gt; будет работает за &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Вариант 2===&lt;br /&gt;
&amp;lt;tex&amp;gt; 1 \mid p_i = 1\mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для верного выполнения просто выставим работы по порядку невозрастания весов, тогда ответом будет &amp;lt;tex&amp;gt; \sum\limits_{i = 1}^n(w_i C_i)&amp;lt;/tex&amp;gt;, так как мы &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; раз сложим время окончания выполнения одной работы (которое в нашем случае &amp;lt;tex&amp;gt;C_{i-1}+1&amp;lt;/tex&amp;gt;) домноженное на вес этой работы. Вес работ [[Сортировка|отсортировали]] за &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt;. Алгоритм работает за &amp;lt;tex&amp;gt;O(n + n \log n)&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
===Вариант 3===&lt;br /&gt;
&amp;lt;tex&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum f_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_{i}&amp;lt;/tex&amp;gt; {{---}} монотонная функция времени окончания работы &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; для работ &amp;lt;tex&amp;gt;i = 1, 2, \ldots , n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Нам нужно распределить &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ в разное время. Если мы назначим время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; для работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; то цена будет &amp;lt;tex&amp;gt;f_i(t + 1)&amp;lt;/tex&amp;gt;. Функция &amp;lt;tex&amp;gt;f_i&amp;lt;/tex&amp;gt; монотонно неубывающая, тогда работы в расписании надо располагать как можно раньше для получения верного решения. &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; временных интервалов &amp;lt;tex&amp;gt;t_i&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; r_1 \leqslant r_2 \leqslant \ldots \leqslant r_n&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
'''Псевдокод'''&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;tex&amp;gt;t_1 \leftarrow r_1 &amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for'''  &amp;lt;tex&amp;gt; i \leftarrow 2&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      &amp;lt;tex&amp;gt; t_i \leftarrow &amp;lt;/tex&amp;gt; '''max'''&amp;lt;tex&amp;gt;(r_i, \ t_{i-1} - 1)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм работает за &amp;lt;tex&amp;gt;O(n \log n +n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
==Основная задача== &lt;br /&gt;
===Описание алгоритма===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; {{---}} текущий момент времени.&amp;lt;br/&amp;gt;&lt;br /&gt;
Для каждого очередного значения &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt;, которое изменяется от &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; до времени окончания последней работы, будем:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Выбирать работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из множества невыполненных работ, у которой &amp;lt;tex&amp;gt;r_{i} \leqslant time&amp;lt;/tex&amp;gt;, а значение &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt; максимально.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Если мы смогли найти работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, то выполняем её в момент времени &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; и удаляем из множества невыполненных работ.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Увеличиваем &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; на один.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Доказательство корректности алгоритма===&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Расписание, построенное данным алгоритмом, является корректным и оптимальным.&lt;br /&gt;
|proof=&lt;br /&gt;
Доказательство будем вести от противного.&amp;lt;br/&amp;gt;&lt;br /&gt;
Рассмотрим расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, полученное после выполнения нашего алгоритма, и оптимальное расписание &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Возьмём первый момент времени &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;, когда расписания  различаются. Пусть в этот момент времени  в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, будет выполняться работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt;, а в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; {{---}} работа с весом &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Это первый момент, в котором расписания отличаются, значит в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; выполнится в момент времени &amp;lt;tex&amp;gt;t_{2} &amp;gt; t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Поменяем местами работы с весами &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и полуим расписание &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Это возможно, потому что время появления этих работ не меньше &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При такой перестановке ответы на задачу для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt; будут отличаться на &lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;tex&amp;gt;t_{1}w_{2} + t_{2}w_{1} - t_{1}w_{1} + t_{2}w_{2} = t_{1}(w_{2} - w_{1}) + t_{2}(w_{1} - w_{2}) = (t_{1} - t_{2})(w_{2} - w_{1})&amp;lt;/tex&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Первая скобка отрицательная: &amp;lt;tex&amp;gt;t_{1} &amp;lt; t_{2}&amp;lt;/tex&amp;gt;. Вторая скобка тоже отрицательная из того, что в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_1&amp;lt;/tex&amp;gt; выполняется раньше, значит её вес должен быть больше &amp;lt;tex&amp;gt;w_2&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Итого имеем, что ответ для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; больше, чем ответ для &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Следовательно расписание &amp;lt;tex&amp;gt;S_2&amp;lt;/tex&amp;gt; неоптимальное. Получили противоречие. Значит не существует такого момента времени, когда расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; отличается от оптимального. Следовательно мы доказали, что оно оптимальное.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Псевдокод===&lt;br /&gt;
&lt;br /&gt;
====Алгоритм 1====&lt;br /&gt;
   &amp;lt;tex&amp;gt; S \leftarrow \{1 \ldots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{time} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{answer} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''while''' &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow null &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt; i \in S&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt; r_{i} \leqslant \mathtt{time}&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt;w_i \geqslant \max\limits_{j \in S, j = 1 \ldots n} w_j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; j \leftarrow i &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; \mathtt{time++}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Алгоритм 2====&lt;br /&gt;
Этот алгоритм реализован с помощью [[Двоичная_куча|двоичной кучи]] &amp;lt;tex&amp;gt;\mathtt{Heap}&amp;lt;/tex&amp;gt; в которой операции вставки и извлечения выполняются за &amp;lt;tex&amp;gt;O(\log n)&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; S \leftarrow \{1 \ldots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{time} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{answer} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for''' &amp;lt;tex&amp;gt;i \leftarrow 1 &amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      Heap.insert(&amp;lt;tex&amp;gt;w_i&amp;lt;/tex&amp;gt;)&lt;br /&gt;
   '''while''' &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow null &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt; i \in S&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt; r_{i} \leqslant \mathtt{time}&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt;w_i \geqslant &amp;lt;/tex&amp;gt; Heap.Max()&lt;br /&gt;
         &amp;lt;tex&amp;gt; j \leftarrow i &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         Heap.ExtractMax()&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; \mathtt{time++}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В начале алгоритма мы добавляем все элементы &amp;lt;tex&amp;gt;w_i&amp;lt;/tex&amp;gt; в двоичную кучу тратя на это &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt; времени. Затем мы тратим &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt; на получение ответа. Тогда суммарное время работы алгоритма составит &amp;lt;tex&amp;gt;O(n \log n + n \log n)&amp;lt;/tex&amp;gt; что есть &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;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;n + \max\limits_{i = 1 \ldots n} r_{i}&amp;lt;/tex&amp;gt; шагов цикла. Определить максимум в множестве можно за время &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, используя , например, [[:Категория:Приоритетные_очереди|очередь с приоритетами]]. Значит общее время работы алгоритма &amp;lt;tex&amp;gt;O((n + \max\limits_{i = 1 \ldots n} r_{i})\log n)&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;
* [[1ridipi1|&amp;lt;tex&amp;gt;1 | r_{i}, d_{i}, p_{i}=1 | -&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 19-20&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 38-39&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 84-85&lt;br /&gt;
* Лазарев А.А., Мусатова Е.Г., Кварацхелия А.Г., Гафаров Е.Р. Пособие по теории расписаний.&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47324</id>
		<title>1ripi1sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47324"/>
				<updated>2015-06-03T13:52:41Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt; и вес &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum w_{i} C_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;C_{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;
===Вариант 1===&lt;br /&gt;
&amp;lt;tex&amp;gt; 1 \mid p_i = 1\mid \sum C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот случай простейший. Ответом будет &amp;lt;tex&amp;gt;\sum\limits_{k = 1}^n(k)&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; членов арифметической прогрессии алгоритм &amp;lt;tex&amp;gt;S_n=\frac{a_1+a_n}2 \cdot n&amp;lt;/tex&amp;gt; будет работает за &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Вариант 2===&lt;br /&gt;
&amp;lt;tex&amp;gt; 1 \mid p_i = 1\mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для верного выполнения просто выставим работы по порядку невозрастания весов, тогда ответом будет &amp;lt;tex&amp;gt; \sum\limits_{i = 1}^n(w_i C_i)&amp;lt;/tex&amp;gt;, так как мы &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; раз сложим время окончания выполнения одной работы (которое в нашем случае &amp;lt;tex&amp;gt;C_{i-1}+1&amp;lt;/tex&amp;gt;) домноженное на вес этой работы. Вес работ [[Сортировка|отсортировали]] за &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt;. Алгоритм работает за &amp;lt;tex&amp;gt;O(n + n \log n)&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
===Вариант 3===&lt;br /&gt;
&amp;lt;tex&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum f_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_{i}&amp;lt;/tex&amp;gt; {{---}} монотонная функция времени окончания работы &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; для работ &amp;lt;tex&amp;gt;i = 1, 2, \ldots , n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Нам нужно распределить &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ в разное время. Если мы назначим время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; для работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; то цена будет &amp;lt;tex&amp;gt;f_i(t + 1)&amp;lt;/tex&amp;gt;. Функция &amp;lt;tex&amp;gt;f_i&amp;lt;/tex&amp;gt; монотонно неубывающая, тогда работы в расписании надо располагать как можно раньше для получения верного решения. &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; временных интервалов &amp;lt;tex&amp;gt;t_i&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; r_1 \leqslant r_2 \leqslant \ldots \leqslant r_n&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
'''Псевдокод'''&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;tex&amp;gt;t_1 \leftarrow r_1 &amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for'''  &amp;lt;tex&amp;gt; i \leftarrow 2&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      &amp;lt;tex&amp;gt; t_i \leftarrow &amp;lt;/tex&amp;gt; '''max'''&amp;lt;tex&amp;gt;(r_i, \ t_{i-1} - 1)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм работает за &amp;lt;tex&amp;gt;O(n \log n +n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
==Основная задача== &lt;br /&gt;
===Описание алгоритма===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; {{---}} текущий момент времени.&amp;lt;br/&amp;gt;&lt;br /&gt;
Для каждого очередного значения &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt;, которое изменяется от &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; до времени окончания последней работы, будем:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Выбирать работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из множества невыполненных работ, у которой &amp;lt;tex&amp;gt;r_{i} \leqslant time&amp;lt;/tex&amp;gt;, а значение &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt; максимально.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Если мы смогли найти работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, то выполняем её в момент времени &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; и удаляем из множества невыполненных работ.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Увеличиваем &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; на один.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Доказательство корректности алгоритма===&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Расписание, построенное данным алгоритмом, является корректным и оптимальным.&lt;br /&gt;
|proof=&lt;br /&gt;
Доказательство будем вести от противного.&amp;lt;br/&amp;gt;&lt;br /&gt;
Рассмотрим расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, полученное после выполнения нашего алгоритма, и оптимальное расписание &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Возьмём первый момент времени &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;, когда расписания  различаются. Пусть в этот момент времени  в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, будет выполняться работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt;, а в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; {{---}} работа с весом &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Это первый момент, в котором расписания отличаются, значит в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; выполнится в момент времени &amp;lt;tex&amp;gt;t_{2} &amp;gt; t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Поменяем местами работы с весами &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и полуим расписание &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Это возможно, потому что время появления этих работ не меньше &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При такой перестановке ответы на задачу для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt; будут отличаться на &lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;tex&amp;gt;t_{1}w_{2} + t_{2}w_{1} - t_{1}w_{1} + t_{2}w_{2} = t_{1}(w_{2} - w_{1}) + t_{2}(w_{1} - w_{2}) = (t_{1} - t_{2})(w_{2} - w_{1})&amp;lt;/tex&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Первая скобка отрицательная: &amp;lt;tex&amp;gt;t_{1} &amp;lt; t_{2}&amp;lt;/tex&amp;gt;. Вторая скобка тоже отрицательная из того, что в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_1&amp;lt;/tex&amp;gt; выполняется раньше, значит её вес должен быть больше &amp;lt;tex&amp;gt;w_2&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Итого имеем, что ответ для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; больше, чем ответ для &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Следовательно расписание &amp;lt;tex&amp;gt;S_2&amp;lt;/tex&amp;gt; неоптимальное. Получили противоречие. Значит не существует такого момента времени, когда расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; отличается от оптимального. Следовательно мы доказали, что оно оптимальное.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Псевдокод===&lt;br /&gt;
&lt;br /&gt;
====Алгоритм 1====&lt;br /&gt;
   &amp;lt;tex&amp;gt; S \leftarrow \{1 \ldots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{time} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{answer} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''while''' &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow null &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt; i \in S&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt; r_{i} \leqslant \mathtt{time}&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt;w_i \geqslant \max\limits_{j \in S, j = 1 \ldots n} w_j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; j \leftarrow i &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; \mathtt{time++}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Алгоритм 2====&lt;br /&gt;
Этот алгоритм реализован с помощью [[Двоичная_куча|двоичной кучи]] &amp;lt;tex&amp;gt;\mathtt{Heap}&amp;lt;/tex&amp;gt; в которой операции вставки и извлечения выполняются за &amp;lt;tex&amp;gt;O(\log n)&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; S \leftarrow \{1 \ldots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{time} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{answer} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for''' &amp;lt;tex&amp;gt;i \leftarrow 1 &amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      Heap.insert(&amp;lt;tex&amp;gt;w_i&amp;lt;/tex&amp;gt;)&lt;br /&gt;
   '''while''' &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow null &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt; i \in S&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt; r_{i} \leqslant \mathtt{time}&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt;w_i \geqslant &amp;lt;/tex&amp;gt; Heap.Max()&lt;br /&gt;
         &amp;lt;tex&amp;gt; j \leftarrow i &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         Heap.extractMax()&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; \mathtt{time++}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В начале алгоритма мы добавляем все элементы &amp;lt;tex&amp;gt;w_i&amp;lt;/tex&amp;gt; в двоичную кучу тратя на это &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt; времени. Затем мы тратим &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt; на получение ответа. Тогда суммарное время работы алгоритма составит &amp;lt;tex&amp;gt;O(n \log n + n \log n)&amp;lt;/tex&amp;gt; что равно &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;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;n + \max\limits_{i = 1 \ldots n} r_{i}&amp;lt;/tex&amp;gt; шагов цикла. Определить максимум в множестве можно за время &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, используя , например, [[:Категория:Приоритетные_очереди|очередь с приоритетами]]. Значит общее время работы алгоритма &amp;lt;tex&amp;gt;O((n + \max\limits_{i = 1 \ldots n} r_{i})\log n)&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;
* [[1ridipi1|&amp;lt;tex&amp;gt;1 | r_{i}, d_{i}, p_{i}=1 | -&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 19-20&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 38-39&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 84-85&lt;br /&gt;
* Лазарев А.А., Мусатова Е.Г., Кварацхелия А.Г., Гафаров Е.Р. Пособие по теории расписаний.&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47321</id>
		<title>1ripi1sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47321"/>
				<updated>2015-06-03T12:43:15Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt; и вес &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum w_{i} C_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;C_{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;
===Вариант 1===&lt;br /&gt;
&amp;lt;tex&amp;gt; 1 \mid p_i = 1\mid \sum C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот случай простейший. Ответом будет &amp;lt;tex&amp;gt;\sum\limits_{k = 1}^n(k)&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; членов арифметической прогрессии алгоритм &amp;lt;tex&amp;gt;S_n=\frac{a_1+a_n}2 \cdot n&amp;lt;/tex&amp;gt; будет работает за &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Вариант 2===&lt;br /&gt;
&amp;lt;tex&amp;gt; 1 \mid p_i = 1\mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для верного выполнения просто выставим работы по порядку невозрастания весов, тогда ответом будет &amp;lt;tex&amp;gt; \sum\limits_{i = 1}^n(w_i C_i)&amp;lt;/tex&amp;gt;, так как мы &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; раз сложим время окончания выполнения одной работы (которое в нашем случае &amp;lt;tex&amp;gt;C_{i-1}+1&amp;lt;/tex&amp;gt;) домноженное на вес этой работы. Вес работ [[Сортировка|отсортировали]] за &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt;. Алгоритм работает за &amp;lt;tex&amp;gt;O(n + n \log n)&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
===Вариант 3===&lt;br /&gt;
&amp;lt;tex&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum f_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_{i}&amp;lt;/tex&amp;gt; {{---}} монотонная функция времени окончания работы &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; для работ &amp;lt;tex&amp;gt;i = 1, 2, \ldots , n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Нам нужно распределить &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ в разное время. Если мы назначим время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; для работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; то цена будет &amp;lt;tex&amp;gt;f_i(t + 1)&amp;lt;/tex&amp;gt;. Функция &amp;lt;tex&amp;gt;f_i&amp;lt;/tex&amp;gt; монотонно неубывающая, тогда работы в расписании надо располагать как можно раньше для получения верного решения. &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; временных интервалов &amp;lt;tex&amp;gt;t_i&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; r_1 \leqslant r_2 \leqslant \ldots \leqslant r_n&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
'''Псевдокод'''&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;tex&amp;gt;t_1 \leftarrow r_1 &amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for'''  &amp;lt;tex&amp;gt; i \leftarrow 2&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      &amp;lt;tex&amp;gt; t_i \leftarrow &amp;lt;/tex&amp;gt; '''max'''&amp;lt;tex&amp;gt;(r_i, \ t_{i-1} - 1)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот алгоритм работает за &amp;lt;tex&amp;gt;O(n \log n +n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
==Основная задача== &lt;br /&gt;
===Описание алгоритма===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; {{---}} текущий момент времени.&amp;lt;br/&amp;gt;&lt;br /&gt;
Для каждого очередного значения &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt;, которое изменяется от &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; до времени окончания последней работы, будем:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Выбирать работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из множества невыполненных работ, у которой &amp;lt;tex&amp;gt;r_{i} \leqslant time&amp;lt;/tex&amp;gt;, а значение &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt; максимально.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Если мы смогли найти работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, то выполняем её в момент времени &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; и удаляем из множества невыполненных работ.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Увеличиваем &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; на один.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Доказательство корректности алгоритма===&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Расписание, построенное данным алгоритмом, является корректным и оптимальным.&lt;br /&gt;
|proof=&lt;br /&gt;
Доказательство будем вести от противного.&amp;lt;br/&amp;gt;&lt;br /&gt;
Рассмотрим расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, полученное после выполнения нашего алгоритма, и оптимальное расписание &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Возьмём первый момент времени &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;, когда расписания  различаются. Пусть в этот момент времени  в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, будет выполняться работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt;, а в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; {{---}} работа с весом &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Это первый момент, в котором расписания отличаются, значит в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; выполнится в момент времени &amp;lt;tex&amp;gt;t_{2} &amp;gt; t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Поменяем местами работы с весами &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и полуим расписание &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Это возможно, потому что время появления этих работ не меньше &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При такой перестановке ответы на задачу для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt; будут отличаться на &lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;tex&amp;gt;t_{1}w_{2} + t_{2}w_{1} - t_{1}w_{1} + t_{2}w_{2} = t_{1}(w_{2} - w_{1}) + t_{2}(w_{1} - w_{2}) = (t_{1} - t_{2})(w_{2} - w_{1})&amp;lt;/tex&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Первая скобка отрицательная: &amp;lt;tex&amp;gt;t_{1} &amp;lt; t_{2}&amp;lt;/tex&amp;gt;. Вторая скобка тоже отрицательная из того, что в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_1&amp;lt;/tex&amp;gt; выполняется раньше, значит её вес должен быть больше &amp;lt;tex&amp;gt;w_2&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Итого имеем, что ответ для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; больше, чем ответ для &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Следовательно расписание &amp;lt;tex&amp;gt;S_2&amp;lt;/tex&amp;gt; неоптимальное. Получили противоречие. Значит не существует такого момента времени, когда расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; отличается от оптимального. Следовательно мы доказали, что оно оптимальное.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Псевдокод===&lt;br /&gt;
   &amp;lt;tex&amp;gt; S \leftarrow \{1 \ldots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{time} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{answer} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''while''' &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow null &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt; i \in S&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt; r_{i} \leqslant \mathtt{time}&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt;w_i \geqslant \max\limits_{j \in S, j = 1 \ldots n} w_j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; j \leftarrow i &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; \mathtt{time++}&amp;lt;/tex&amp;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;n + \max\limits_{i = 1 \ldots n} r_{i}&amp;lt;/tex&amp;gt; шагов цикла. Определить максимум в множестве можно за время &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, используя , например, [[:Категория:Приоритетные_очереди|очередь с приоритетами]]. Значит общее время работы алгоритма &amp;lt;tex&amp;gt;O((n + \max\limits_{i = 1 \ldots n} r_{i})\log n)&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;
* [[1ridipi1|&amp;lt;tex&amp;gt;1 | r_{i}, d_{i}, p_{i}=1 | -&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 19-20&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 38-39&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 84-85&lt;br /&gt;
* Лазарев А.А., Мусатова Е.Г., Кварацхелия А.Г., Гафаров Е.Р. Пособие по теории расписаний.&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Fpij1sumwu&amp;diff=47309</id>
		<title>Fpij1sumwu</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Fpij1sumwu&amp;diff=47309"/>
				<updated>2015-06-03T11:45:08Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;F \mid p_{ij} = 1 \mid \sum w_iu_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; станков, на которых нужно обработать &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; деталей. Каждую деталь нужно обработать по очереди на всех станках. Любая работа на любом станке выполняется единицу времени. Для каждой работы есть дедлайн &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; {{---}} время, до которого она должна быть закончена, и штраф &amp;lt;tex&amp;gt;w_i&amp;lt;/tex&amp;gt;, который нужно будет выплатить в случае, если работа была закончена после &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt;. Необходимо минимизировать суммарный штраф, который придется выплатить.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Алгоритм==&lt;br /&gt;
&lt;br /&gt;
===Эвристика NEH===&lt;br /&gt;
&lt;br /&gt;
Одним из наиболее известных алгоритмов решения этой задачи является эвристика Наваза, Энскора и Хама (Nawaz, Enscore, Ham)&lt;br /&gt;
&lt;br /&gt;
Первое что нужно сделать это упорядочить требования по &amp;lt;tex&amp;gt;\sum\limits_{j = 1}^n p_{i j}&amp;lt;/tex&amp;gt; и пронумеровать их в соответствии с этим порядком. Затем нужно определить порядок обслуживания двух первых требований так, чтобы минимизировать время их обслуживания. После этого использовать алгоритм&lt;br /&gt;
&lt;br /&gt;
   '''for''' &amp;lt;tex&amp;gt; i = 3&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      Поместить требование &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; на позицию &amp;lt;tex&amp;gt;k \in [1 , i]&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;
===Описание алгоритма===&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Существует оптимальное расписание, в котором каждая работа делается непрерывно.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим расписание, в котором есть работы, которые делаются не непрерывно. Рассмотрим самый ранний разрыв: работа &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; делалась в моменты &amp;lt;tex&amp;gt;t(i), t(i) + 1, \ldots, t(i) + k&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;k &amp;lt; m&amp;lt;/tex&amp;gt;, но не делалась в момент времени &amp;lt;tex&amp;gt;t(i) + k + 1&amp;lt;/tex&amp;gt;. Докажем, что в момент времени &amp;lt;tex&amp;gt;t(i) + k + 1&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;k + 1&amp;lt;/tex&amp;gt;-й станок простаивает и можно продолжить делать &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ю работу. &lt;br /&gt;
&lt;br /&gt;
Пусть в момент времени &amp;lt;tex&amp;gt;t(i) + k + 1&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;k + 1&amp;lt;/tex&amp;gt;-м станке делается работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;. &lt;br /&gt;
В &amp;lt;tex&amp;gt;t(i) + k&amp;lt;/tex&amp;gt;-й момент времени &amp;lt;tex&amp;gt;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;t(i) + k + 1&amp;lt;/tex&amp;gt;-й момент &amp;lt;tex&amp;gt;k + 1&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;
&lt;br /&gt;
По этому утверждению, если работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; начали делать в &amp;lt;tex&amp;gt;t(i)&amp;lt;/tex&amp;gt;, то закончена она будет в &amp;lt;tex&amp;gt;t(i) + m&amp;lt;/tex&amp;gt;. Найдем время &amp;lt;tex&amp;gt;d'_i&amp;lt;/tex&amp;gt; такое, что начав выполнять в него работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, мы успеем выполнить ее до &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;d'_i = d_i - m&amp;lt;/tex&amp;gt;. Таким образом, вычтя из всех &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; число &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;, мы свели задачу к &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum w_i U_i&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Построив оптимальное расписание для &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum w_i U_i&amp;lt;/tex&amp;gt;, мы найдем времена, в которые нужно начинать выполнять работы. По утверждению выше, работы можно выполнять непрерывно.&lt;br /&gt;
&lt;br /&gt;
===Сложность алгоритма===&lt;br /&gt;
Задача &amp;lt;tex&amp;gt;F \mid p_{i j} = 1 \mid \sum w_iu_i&amp;lt;/tex&amp;gt; за &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; сводится к задаче &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum w_i u_i&amp;lt;/tex&amp;gt;. Задача &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum u_iw_i&amp;lt;/tex&amp;gt; решается за &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt;. После решения этой задачи, нужно вывести ответ, имеющий размер &amp;lt;tex&amp;gt;O(nm)&amp;lt;/tex&amp;gt;. Значит, итоговая сложность алгоритма {{---}} &amp;lt;tex&amp;gt;O(n \log n + nm)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==См. также.==&lt;br /&gt;
* [[Классификация задач]]&lt;br /&gt;
* [[Flow shop]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* Лазарев А.А., Мусатова Е.Г., Кварацхелия А.Г., Гафаров Е.Р. Пособие по теории расписаний.&lt;br /&gt;
* Vladimír Modrák, R. Sudhakara Pandian. FLOW SHOP SCHEDULING ALGORITHM TO MINIMIZE COMPLETION TIME FOR -JOBS -MACHINES PROBLEM&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Fpij1sumwu&amp;diff=47307</id>
		<title>Fpij1sumwu</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Fpij1sumwu&amp;diff=47307"/>
				<updated>2015-06-03T11:42:35Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;F \mid p_{ij} = 1 \mid \sum w_iu_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; станков, на которых нужно обработать &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; деталей. Каждую деталь нужно обработать по очереди на всех станках. Любая работа на любом станке выполняется единицу времени. Для каждой работы есть дедлайн &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; {{---}} время, до которого она должна быть закончена, и штраф &amp;lt;tex&amp;gt;w_i&amp;lt;/tex&amp;gt;, который нужно будет выплатить в случае, если работа была закончена после &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt;. Необходимо минимизировать суммарный штраф, который придется выплатить.&lt;br /&gt;
}}&lt;br /&gt;
==Эвристика NEH==&lt;br /&gt;
&lt;br /&gt;
Одним из наиболее известных алгоритмов решения этой задачи является эвристика Наваза, Энскора и Хама (Nawaz, Enscore, Ham)&lt;br /&gt;
&lt;br /&gt;
Первое что нужно сделать это упорядочить требования по &amp;lt;tex&amp;gt;\sum\limits_{j = 1}^n p_{i j}&amp;lt;/tex&amp;gt; и пронумеровать их в соответствии с этим порядком. Затем нужно определить порядок обслуживания двух первых требований так, чтобы минимизировать время их обслуживания. После этого использовать алгоритм&lt;br /&gt;
&lt;br /&gt;
   '''for''' &amp;lt;tex&amp;gt; i = 3&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      Поместить требование &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; на позицию &amp;lt;tex&amp;gt;k \in [1 , i]&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;
{{Утверждение&lt;br /&gt;
|statement=Существует оптимальное расписание, в котором каждая работа делается непрерывно.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим расписание, в котором есть работы, которые делаются не непрерывно. Рассмотрим самый ранний разрыв: работа &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; делалась в моменты &amp;lt;tex&amp;gt;t(i), t(i) + 1, \ldots, t(i) + k&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;k &amp;lt; m&amp;lt;/tex&amp;gt;, но не делалась в момент времени &amp;lt;tex&amp;gt;t(i) + k + 1&amp;lt;/tex&amp;gt;. Докажем, что в момент времени &amp;lt;tex&amp;gt;t(i) + k + 1&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;k + 1&amp;lt;/tex&amp;gt;-й станок простаивает и можно продолжить делать &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ю работу. &lt;br /&gt;
&lt;br /&gt;
Пусть в момент времени &amp;lt;tex&amp;gt;t(i) + k + 1&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;k + 1&amp;lt;/tex&amp;gt;-м станке делается работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;. &lt;br /&gt;
В &amp;lt;tex&amp;gt;t(i) + k&amp;lt;/tex&amp;gt;-й момент времени &amp;lt;tex&amp;gt;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;t(i) + k + 1&amp;lt;/tex&amp;gt;-й момент &amp;lt;tex&amp;gt;k + 1&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;
&lt;br /&gt;
По этому утверждению, если работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; начали делать в &amp;lt;tex&amp;gt;t(i)&amp;lt;/tex&amp;gt;, то закончена она будет в &amp;lt;tex&amp;gt;t(i) + m&amp;lt;/tex&amp;gt;. Найдем время &amp;lt;tex&amp;gt;d'_i&amp;lt;/tex&amp;gt; такое, что начав выполнять в него работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, мы успеем выполнить ее до &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;d'_i = d_i - m&amp;lt;/tex&amp;gt;. Таким образом, вычтя из всех &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; число &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;, мы свели задачу к &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum w_i U_i&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Построив оптимальное расписание для &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum w_i U_i&amp;lt;/tex&amp;gt;, мы найдем времена, в которые нужно начинать выполнять работы. По утверждению выше, работы можно выполнять непрерывно.&lt;br /&gt;
&lt;br /&gt;
==Сложность алгоритма==&lt;br /&gt;
Задача &amp;lt;tex&amp;gt;F \mid p_{i j} = 1 \mid \sum w_iu_i&amp;lt;/tex&amp;gt; за &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; сводится к задаче &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum w_i u_i&amp;lt;/tex&amp;gt;. Задача &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum u_iw_i&amp;lt;/tex&amp;gt; решается за &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt;. После решения этой задачи, нужно вывести ответ, имеющий размер &amp;lt;tex&amp;gt;O(nm)&amp;lt;/tex&amp;gt;. Значит, итоговая сложность алгоритма {{---}} &amp;lt;tex&amp;gt;O(n \log n + nm)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==См. также.==&lt;br /&gt;
* [[Классификация задач]]&lt;br /&gt;
* [[Flow shop]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* Лазарев А.А., Мусатова Е.Г., Кварацхелия А.Г., Гафаров Е.Р. Пособие по теории расписаний.&lt;br /&gt;
* Vladimír Modrák, R. Sudhakara Pandian. FLOW SHOP SCHEDULING ALGORITHM TO MINIMIZE COMPLETION TIME FOR -JOBS -MACHINES PROBLEM&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Fpij1sumwu&amp;diff=47306</id>
		<title>Fpij1sumwu</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Fpij1sumwu&amp;diff=47306"/>
				<updated>2015-06-03T11:38:42Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;F \mid p_{ij} = 1 \mid \sum w_iu_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; станков, на которых нужно обработать &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; деталей. Каждую деталь нужно обработать по очереди на всех станках. Любая работа на любом станке выполняется единицу времени. Для каждой работы есть дедлайн &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; {{---}} время, до которого она должна быть закончена, и штраф &amp;lt;tex&amp;gt;w_i&amp;lt;/tex&amp;gt;, который нужно будет выплатить в случае, если работа была закончена после &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt;. Необходимо минимизировать суммарный штраф, который придется выплатить.&lt;br /&gt;
}}&lt;br /&gt;
==Эвристика NEH==&lt;br /&gt;
&lt;br /&gt;
Одним из наиболее известных алгоритмов решения этой задачи является эвристика Наваза, Энскора и Хама (Nawaz, Enscore, Ham)&lt;br /&gt;
Первое что нужно сделать это упорядочить требования по &amp;lt;tex&amp;gt;\sum\limits_{j = 1}^n p_{i j}&amp;lt;/tex&amp;gt; и пронумеровать их в соответствии с этим порядком. Затем нужно определить порядок обслуживания двух первых требований так, чтобы минимизировать время их обслуживания. После этого использовать алгоритм&lt;br /&gt;
&lt;br /&gt;
   '''for''' &amp;lt;tex&amp;gt; i = 3&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      Поместить требование &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; на позицию &amp;lt;tex&amp;gt;k \in [1 , i]&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;
{{Утверждение&lt;br /&gt;
|statement=Существует оптимальное расписание, в котором каждая работа делается непрерывно.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим расписание, в котором есть работы, которые делаются не непрерывно. Рассмотрим самый ранний разрыв: работа &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; делалась в моменты &amp;lt;tex&amp;gt;t(i), t(i)+1, \ldots, t(i)+k&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;k&amp;lt;m&amp;lt;/tex&amp;gt;, но не делалась в момент времени &amp;lt;tex&amp;gt;t(i)+k+1&amp;lt;/tex&amp;gt;. Докажем, что в момент времени &amp;lt;tex&amp;gt;t(i)+k+1&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;k+1&amp;lt;/tex&amp;gt;-й станок простаивает и можно продолжить делать &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ю работу. &lt;br /&gt;
&lt;br /&gt;
Пусть в момент времени &amp;lt;tex&amp;gt;t(i)+k+1&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;k+1&amp;lt;/tex&amp;gt;-м станке делается работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;. &lt;br /&gt;
В &amp;lt;tex&amp;gt;t(i)+k&amp;lt;/tex&amp;gt;-й момент времени &amp;lt;tex&amp;gt;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;t(i)+k+1&amp;lt;/tex&amp;gt;-й момент &amp;lt;tex&amp;gt;k+1&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;
&lt;br /&gt;
По этому утверждению, если работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; начали делать в &amp;lt;tex&amp;gt;t(i)&amp;lt;/tex&amp;gt;, то закончена она будет в &amp;lt;tex&amp;gt;t(i)+m&amp;lt;/tex&amp;gt;. Найдем время &amp;lt;tex&amp;gt;d'_i&amp;lt;/tex&amp;gt; такое, что начав выполнять в него работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, мы успеем выполнить ее до &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;d'_i = d_i - m&amp;lt;/tex&amp;gt;. Таким образом, вычтя из всех &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; число &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;, мы свели задачу к &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum w_i U_i&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Построив оптимальное расписание для &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum w_i U_i&amp;lt;/tex&amp;gt;, мы найдем времена, в которые нужно начинать выполнять работы. По утверждению выше, работы можно выполнять непрерывно.&lt;br /&gt;
&lt;br /&gt;
==Сложность алгоритма==&lt;br /&gt;
Задача &amp;lt;tex&amp;gt;F \mid p_{ij} = 1 \mid \sum w_iu_i&amp;lt;/tex&amp;gt; за &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; сводится к задаче &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum w_iu_i&amp;lt;/tex&amp;gt;. Задача &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum u_iw_i&amp;lt;/tex&amp;gt; решается за &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt;. После решения этой задачи, нужно вывести ответ, имеющий размер &amp;lt;tex&amp;gt;O(nm)&amp;lt;/tex&amp;gt;. Значит, итоговая сложность алгоритма {{---}} &amp;lt;tex&amp;gt;O(n \log n + nm)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==См. также.==&lt;br /&gt;
* [[Классификация задач]]&lt;br /&gt;
* [[Flow shop]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* Лазарев А.А., Мусатова Е.Г., Кварацхелия А.Г., Гафаров Е.Р. Пособие по теории расписаний.&lt;br /&gt;
* Vladimír Modrák, R. Sudhakara Pandian. FLOW SHOP SCHEDULING ALGORITHM TO MINIMIZE COMPLETION TIME FOR -JOBS -MACHINES PROBLEM&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Fpij1sumwu&amp;diff=47305</id>
		<title>Fpij1sumwu</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Fpij1sumwu&amp;diff=47305"/>
				<updated>2015-06-03T11:21:15Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;F \mid p_{ij} = 1 \mid \sum w_iu_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; станков, на которых нужно обработать &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; деталей. Каждую деталь нужно обработать по очереди на всех станках. Любая работа на любом станке выполняется единицу времени. Для каждой работы есть дедлайн &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; {{---}} время, до которого она должна быть закончена, и штраф &amp;lt;tex&amp;gt;w_i&amp;lt;/tex&amp;gt;, который нужно будет выплатить в случае, если работа была закончена после &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt;. Необходимо минимизировать суммарный штраф, который придется выплатить.&lt;br /&gt;
}}&lt;br /&gt;
==Описание алгоритма==&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Существует оптимальное расписание, в котором каждая работа делается непрерывно.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим расписание, в котором есть работы, которые делаются не непрерывно. Рассмотрим самый ранний разрыв: работа &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; делалась в моменты &amp;lt;tex&amp;gt;t(i), t(i)+1, \ldots, t(i)+k&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;k&amp;lt;m&amp;lt;/tex&amp;gt;, но не делалась в момент времени &amp;lt;tex&amp;gt;t(i)+k+1&amp;lt;/tex&amp;gt;. Докажем, что в момент времени &amp;lt;tex&amp;gt;t(i)+k+1&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;k+1&amp;lt;/tex&amp;gt;-й станок простаивает и можно продолжить делать &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ю работу. &lt;br /&gt;
&lt;br /&gt;
Пусть в момент времени &amp;lt;tex&amp;gt;t(i)+k+1&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;k+1&amp;lt;/tex&amp;gt;-м станке делается работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;. &lt;br /&gt;
В &amp;lt;tex&amp;gt;t(i)+k&amp;lt;/tex&amp;gt;-й момент времени &amp;lt;tex&amp;gt;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;t(i)+k+1&amp;lt;/tex&amp;gt;-й момент &amp;lt;tex&amp;gt;k+1&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;
&lt;br /&gt;
По этому утверждению, если работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; начали делать в &amp;lt;tex&amp;gt;t(i)&amp;lt;/tex&amp;gt;, то закончена она будет в &amp;lt;tex&amp;gt;t(i)+m&amp;lt;/tex&amp;gt;. Найдем время &amp;lt;tex&amp;gt;d'_i&amp;lt;/tex&amp;gt; такое, что начав выполнять в него работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, мы успеем выполнить ее до &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;d'_i = d_i - m&amp;lt;/tex&amp;gt;. Таким образом, вычтя из всех &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; число &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;, мы свели задачу к &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum w_i U_i&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Построив оптимальное расписание для &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum w_i U_i&amp;lt;/tex&amp;gt;, мы найдем времена, в которые нужно начинать выполнять работы. По утверждению выше, работы можно выполнять непрерывно.&lt;br /&gt;
&lt;br /&gt;
==Сложность алгоритма==&lt;br /&gt;
Задача &amp;lt;tex&amp;gt;F \mid p_{ij} = 1 \mid \sum w_iu_i&amp;lt;/tex&amp;gt; за &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; сводится к задаче &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum w_iu_i&amp;lt;/tex&amp;gt;. Задача &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum u_iw_i&amp;lt;/tex&amp;gt; решается за &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt;. После решения этой задачи, нужно вывести ответ, имеющий размер &amp;lt;tex&amp;gt;O(nm)&amp;lt;/tex&amp;gt;. Значит, итоговая сложность алгоритма {{---}} &amp;lt;tex&amp;gt;O(n \log n + nm)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==См. также.==&lt;br /&gt;
* [[Классификация задач]]&lt;br /&gt;
* [[Flow shop]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* Лазарев А.А., Мусатова Е.Г., Кварацхелия А.Г., Гафаров Е.Р. Пособие по теории расписаний.&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47304</id>
		<title>1ripi1sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47304"/>
				<updated>2015-06-03T11:19:13Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt; и вес &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum w_{i} C_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;C_{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;
===Задача 1===&lt;br /&gt;
&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid p_i = 1\mid \sum C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот случай простейший. Ответом будет &amp;lt;tex&amp;gt;\sum_{k = 1}^n(k)&amp;lt;/tex&amp;gt;, так как мы &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; раз сложим время окончания выполнения одной работы. В этом случае алгоритм работает за &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Задача 2===&lt;br /&gt;
&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid p_i = 1\mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Входные данные для этой задачи: число работ &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; и вес каждой работы &amp;lt;tex&amp;gt;w_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Для верного выполнения просто выставим работы по порядку невозрастанию весов, тогда ответом будет &amp;lt;tex&amp;gt; \sum_{i = 1}^n(w_i C_i)&amp;lt;/tex&amp;gt;, так как мы &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; раз сложим время окончания выполнения одной работы (которое в нашем случае &amp;lt;tex&amp;gt;C_{i-1}+1&amp;lt;/tex&amp;gt;) домноженное на вес этой работы. Если вес работ отсортировали за &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt; то алгоритм работает за &amp;lt;tex&amp;gt;O(n + n \log n)&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
===Задача 3===&lt;br /&gt;
&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum f_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_{i}&amp;lt;/tex&amp;gt; {{---}} монотонная функция времени окончания работы &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; для работ &amp;lt;tex&amp;gt;i = 1, 2, \ldots , n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Нам нужно распределить &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ в разное время. Если мы назначим время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; для работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; то цена будет &amp;lt;tex&amp;gt;f_i(t + 1)&amp;lt;/tex&amp;gt;. Так как нужно заполнить &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; временных промежутков, задача может быть решена за &amp;lt;tex&amp;gt;O(n^3)&amp;lt;/tex&amp;gt;. Функция &amp;lt;tex&amp;gt;f_i&amp;lt;/tex&amp;gt; монотонно неубывающая, тогда работы в расписании надо располагать как можно раньше для получения верного решения. &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; временных интервалов &amp;lt;tex&amp;gt;t_i&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; r_1 \leqslant r_2 \leqslant \ldots \leqslant r_n&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
'''Псевдокод'''&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;tex&amp;gt;t_1 \leftarrow r_1 &amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for'''  &amp;lt;tex&amp;gt; i \leftarrow 2&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      &amp;lt;tex&amp;gt; t_i \leftarrow &amp;lt;/tex&amp;gt; '''max'''&amp;lt;tex&amp;gt;(r_i, \ t_{i-1} - 1)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Основная задача== &lt;br /&gt;
===Описание алгоритма===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; {{---}} текущий момент времени.&amp;lt;br/&amp;gt;&lt;br /&gt;
Для каждого очередного значения &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt;, которое изменяется от &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; до времени окончания последней работы, будем:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Выбирать работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из множества невыполненных работ, у которой &amp;lt;tex&amp;gt;r_{i} \leqslant time&amp;lt;/tex&amp;gt;, а значение &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt; максимально.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Если мы смогли найти работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, то выполняем её в момент времени &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; и удаляем из множества невыполненных работ.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Увеличиваем &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; на один.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Доказательство корректности алгоритма===&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Расписание, построенное данным алгоритмом, является корректным и оптимальным.&lt;br /&gt;
|proof=&lt;br /&gt;
Доказательство будем вести от противного.&amp;lt;br/&amp;gt;&lt;br /&gt;
Рассмотрим расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, полученное после выполнения нашего алгоритма, и оптимальное расписание &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Возьмём первый момент времени &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;, когда расписания  различаются. Пусть в этот момент времени  в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, будет выполняться работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt;, а в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; {{---}} работа с весом &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Это первый момент, в котором расписания отличаются, значит в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; выполнится в момент времени &amp;lt;tex&amp;gt;t_{2} &amp;gt; t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Поменяем местами работы с весами &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и полуим расписание &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Это возможно, потому что время появления этих работ не меньше &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При такой перестановке ответы на задачу для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt; будут отличаться на &lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;tex&amp;gt;t_{1}w_{2} + t_{2}w_{1} - t_{1}w_{1} + t_{2}w_{2} = t_{1}(w_{2} - w_{1}) + t_{2}(w_{1} - w_{2}) = (t_{1} - t_{2})(w_{2} - w_{1})&amp;lt;/tex&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Первая скобка отрицательная: &amp;lt;tex&amp;gt;t_{1} &amp;lt; t_{2}&amp;lt;/tex&amp;gt;. Вторая скобка тоже отрицательная из того, что в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_1&amp;lt;/tex&amp;gt; выполняется раньше, значит её вес должен быть больше &amp;lt;tex&amp;gt;w_2&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Итого имеем, что ответ для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; больше, чем ответ для &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Следовательно расписание &amp;lt;tex&amp;gt;S_2&amp;lt;/tex&amp;gt; неоптимальное. Получили противоречие. Значит не существует такого момента времени, когда расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; отличается от оптимального. Следовательно мы доказали, что оно оптимальное.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Псевдокод===&lt;br /&gt;
   &amp;lt;tex&amp;gt; S \leftarrow \{1 \ldots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{time} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{answer} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''while''' &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow null &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt; i \in S&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt; r_{i} \leqslant \mathtt{time}&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt;w_i \geqslant \max\limits_{j = 1 \ldots n} w_j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; j \leftarrow i &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; \mathtt{time++}&amp;lt;/tex&amp;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;n + \max\limits_{i = 1 \ldots n} r_{i}&amp;lt;/tex&amp;gt; шагов цикла. Определить максимум в множестве можно за время &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, используя , например, [[:Категория:Приоритетные_очереди|очередь с приоритетами]]. Значит общее время работы алгоритма &amp;lt;tex&amp;gt;O((n + \max\limits_{i = 1 \ldots n} r_{i})\log n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
* [[Классификация задач]]&lt;br /&gt;
* [[1ridipi1|&amp;lt;tex&amp;gt;1 \mid outtree \mid \sum w_i C_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1ridipi1|&amp;lt;tex&amp;gt;1 | r_{i}, d_{i}, p_{i}=1 | -&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 19-20&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 38-39&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 84-85&lt;br /&gt;
* Лазарев А.А., Мусатова Е.Г., Кварацхелия А.Г., Гафаров Е.Р. Пособие по теории расписаний.&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47290</id>
		<title>1ripi1sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47290"/>
				<updated>2015-06-02T21:33:20Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt; и вес &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum w_{i} C_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;C_{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;
===Задача 1===&lt;br /&gt;
&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid p_i = 1\mid \sum C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Описание алгоритма'''&lt;br /&gt;
&lt;br /&gt;
Входные данные для этой задачи: число работ &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&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;
===Задача 2===&lt;br /&gt;
&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid p_i = 1\mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Описание алгоритма'''&lt;br /&gt;
&lt;br /&gt;
Входные данные для этой задачи: число работ &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; и вес каждой работы &amp;lt;tex&amp;gt;w_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Для верного выполнения просто выставим работы по порядку убывания весов, тогда ответом будет &amp;lt;tex&amp;gt; \sum_{i = 1}^n(w_i C_i)&amp;lt;/tex&amp;gt;, так как мы &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; раз сложим время выполнения одной работы (которое в нашем случае единица) домноженное на вес этой работы.&lt;br /&gt;
&lt;br /&gt;
===Задача 3===&lt;br /&gt;
&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum f_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum f_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;f_{i}&amp;lt;/tex&amp;gt; {{---}} монотонная функция времени окончания работы &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; для работ &amp;lt;tex&amp;gt;i = 1, 2, ..., n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
'''Описание алгоритма'''&lt;br /&gt;
&lt;br /&gt;
Нам нужно распределить &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ в разное время. Если мы назначим время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; для работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; то цена будет &amp;lt;tex&amp;gt;f_i(t + 1)&amp;lt;/tex&amp;gt;. Так как нужно заполнить &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; временных промежутков, задача может быть решена за &amp;lt;tex&amp;gt;O(n^3)&amp;lt;/tex&amp;gt;. Функция &amp;lt;tex&amp;gt;f_i&amp;lt;/tex&amp;gt; монотонно неубывающая, тогда работы в расписании надо располагать как можно раньше для получения верного решения. &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; временных интервалов &amp;lt;tex&amp;gt;t_i&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; r_1 \leqslant r_2 \leqslant \ldots \leqslant r_n&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
'''Псевдокод'''&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;tex&amp;gt;t_1 \leftarrow r_1 &amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for'''  &amp;lt;tex&amp;gt; i \leftarrow 2&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      &amp;lt;tex&amp;gt; t_i \leftarrow &amp;lt;/tex&amp;gt; '''max'''&amp;lt;tex&amp;gt;(r_i, \ t_{i-1} - 1)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Описание алгоритма==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; {{---}} текущий момент времени.&amp;lt;br/&amp;gt;&lt;br /&gt;
Для каждого очередного значения &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt;, которое изменяется от &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; до времени окончания последней работы, будем:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Выбирать работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из множества невыполненных работ, у которой &amp;lt;tex&amp;gt;r_{i} \le time&amp;lt;/tex&amp;gt;, а значение &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt; максимально.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Если мы смогли найти работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, то выполняем её в момент времени &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; и удаляем из множества невыполненных работ.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Увеличиваем &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; на один.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Доказательство корректности алгоритма==&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Расписание, построенное данным алгоритмом, является корректным и оптимальным.&lt;br /&gt;
|proof=&lt;br /&gt;
Доказательство будем вести от противного.&amp;lt;br/&amp;gt;&lt;br /&gt;
Рассмотрим расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, полученное после выполнения нашего алгоритма, и оптимальное расписание &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Возьмём первый момент времени &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;, когда расписания  различаются. Пусть в этот момент времени  в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, будет выполняться работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt;, а в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; {{---}} работа с весом &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Это первый момент, в котором расписания отличаются, значит в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; выполнится в момент времени &amp;lt;tex&amp;gt;t_{2} &amp;gt; t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Поменяем местами работы с весами &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и полуим расписание &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Это возможно, потому что время появления этих работ не меньше &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При такой перестановке ответы на задачу для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt; будут отличаться на &lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;tex&amp;gt;t_{1}w_{2} + t_{2}w_{1} - t_{1}w_{1} + t_{2}w_{2} = t_{1}(w_{2} - w_{1}) + t_{2}(w_{1} - w_{2}) = (t_{1} - t_{2})(w_{2} - w_{1})&amp;lt;/tex&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Первая скобка отрицательная: &amp;lt;tex&amp;gt;t_{1} &amp;lt; t_{2}&amp;lt;/tex&amp;gt;. Вторая скобка тоже отрицательная из того, что в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_1&amp;lt;/tex&amp;gt; выполняется раньше, значит её вес должен быть больше &amp;lt;tex&amp;gt;w_2&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Итого имеем, что ответ для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; больше, чем ответ для &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Следовательно расписание &amp;lt;tex&amp;gt;S_2&amp;lt;/tex&amp;gt; неоптимальное. Получили противоречие. Значит не существует такого момента времени, когда расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; отличается от оптимального. Следовательно мы доказали, что оно оптимальное.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Псевдокод==&lt;br /&gt;
   &amp;lt;tex&amp;gt; S \leftarrow \{1 \dots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{time} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{answer} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''while''' &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow null &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt; i \in S&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt; r_{i} \leqslant \mathtt{time}&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt;w_i \geqslant max_{j = 1}^n w_j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; j \leftarrow i &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; \mathtt{time++}&amp;lt;/tex&amp;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;n + \max_{i = 1}^n r_{i}&amp;lt;/tex&amp;gt; шагов цикла. Определить максимум в множестве можно за время &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, используя , например, [[Wikipedia:ru:Очередь с приоритетом (программирование)|очередь с приоритетами]]. Значит общее время работы алгоритма &amp;lt;tex&amp;gt;O((n + \max_{i = 1}^n r_{i})\log n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 19 - 20&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 38 - 39&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 84 - 85&lt;br /&gt;
* Лазарев А.А., Мусатова Е.Г., Кварацхелия А.Г., Гафаров Е.Р. Пособие по теории расписаний.&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Flow_shop&amp;diff=47289</id>
		<title>Flow shop</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Flow_shop&amp;diff=47289"/>
				<updated>2015-06-02T21:30:04Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Описание ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Flow shop''' ('''&amp;lt;tex&amp;gt;F_{m}&amp;lt;/tex&amp;gt;''' в нотации Грэхема): В системе находится &amp;lt;tex&amp;gt; m &amp;lt;/tex&amp;gt; машин, работающих параллельно. Машины упорядочены. Каждая работа должна быть выполнена последовательно на всех машинах с первой по последнюю.}}&lt;br /&gt;
&lt;br /&gt;
Рассмотрим пример:  &amp;lt;tex&amp;gt;F \mid p_{ij} = 1 \mid C_{max}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Допустим, у нас &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; машин. В начальный момент времени мы можем начать обрабатывать любую работу на первой машине. В следующий момент на первой машине можно обрабатывать следующую работу, а на второй перейдёт предыдущая работа с первой машины, и так далее. Таким образом, на выполнение всех работ у нас уйдёт &amp;lt;tex&amp;gt;n + m - 1&amp;lt;/tex&amp;gt; единиц времени. Проиллюстрируем это диаграммой Гантта для случая &amp;lt;tex&amp;gt;n = 6, m = 5&amp;lt;/tex&amp;gt;:&lt;br /&gt;
         '''0   1   2   3   4   5   6   7   8   9   10'''&lt;br /&gt;
         -------------------------------------------&lt;br /&gt;
  '''M_1'''   |    1   2   3   4   5   6   -   -   -   -&lt;br /&gt;
  '''M_2'''   |    -   1   2   3   4   5   6   -   -   -&lt;br /&gt;
  '''M_3'''   |    -   -   1   2   3   4   5   6   -   -&lt;br /&gt;
  '''M_4'''   |    -   -   -   1   2   3   4   5   6   -&lt;br /&gt;
  '''M_5'''   |    -   -   -   -   1   2   3   4   5   6&lt;br /&gt;
&lt;br /&gt;
Заметим, что в данном случае &amp;lt;tex&amp;gt;p_{ij}&amp;lt;/tex&amp;gt; может быть равно не только единице, но и любой константе.&lt;br /&gt;
 &lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement = Любая задача вида &amp;lt;tex&amp;gt;F \mid p_{ij} = 1 \mid ? &amp;lt;/tex&amp;gt; сводится к соответствующей задаче вида &amp;lt;tex&amp;gt;1 \mid p_{ij} = 1 \mid ?&amp;lt;/tex&amp;gt;. &lt;br /&gt;
|proof = &lt;br /&gt;
Поскольку работа всегда заканчивает выполняться на последней машине, нас интересуют только времена завершения работ на последней машине. Также очевидно, что последняя машина может начать работать только в момент времени &amp;lt;tex&amp;gt; m - 1 &amp;lt;/tex&amp;gt;. Оказывается, что любое решение задачи &amp;lt;tex&amp;gt; 1 \mid p_{ij} = 1 \mid ? &amp;lt;/tex&amp;gt; с дедлайнами, уменьшенными на &amp;lt;tex&amp;gt; m - 1 &amp;lt;/tex&amp;gt; можно преобразовать в оптимальное расписание для задачи &amp;lt;tex&amp;gt;F \mid p_{ij} = 1 \mid ? &amp;lt;/tex&amp;gt;. Докажем это.&lt;br /&gt;
&lt;br /&gt;
Возьмем оптимальное расписание для соответствующей задачи с одним станком, выполним работы в этом порядке на первой машине, затем на второй машине, начиная с момента времени &amp;lt;tex&amp;gt; 1 &amp;lt;/tex&amp;gt;, и так далее, до выполнения на последней машине, начиная с &amp;lt;tex&amp;gt; m - 1 &amp;lt;/tex&amp;gt;. Это расписание корректно и соблюдает все дедлайны. Поскольку целевая функция совпадает с соответствующей функцией для задачи на одном станке, оно оптимально и для данной задачи.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Примером применения этого утверждения может служить [[Fpij1sumwu|задача]] &lt;br /&gt;
&lt;br /&gt;
Задачи с произвольными временами выполнения работ почти все являются NP-трудными.&lt;br /&gt;
&lt;br /&gt;
== Задача Джонсона о двух станках &amp;lt;tex&amp;gt;F_2 \mid \mid C_{max}&amp;lt;/tex&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
Это единственная из flow shop задач с произвольными временами выполнения работ, которая решается за полиномиальное время.&lt;br /&gt;
&lt;br /&gt;
Приведём здесь решение задачи без доказательства, его можно посмотреть в [1].&lt;br /&gt;
&lt;br /&gt;
Оптимальное расписание для первой и второй машины будет совпадать. Таким образом, нам требуется найти порядок, в котором будут выполняться работы на каждой машине.&lt;br /&gt;
&lt;br /&gt;
Алгоритм такой: возьмём два пустых списка. Будем рассматривать работы в порядке возрастания &amp;lt;tex&amp;gt;min(p_1, p_2)&amp;lt;/tex&amp;gt;, то есть, минимума из времён выполнения данной работы на первой и второй машине. Если у работы &amp;lt;tex&amp;gt;p_1 \le p_2&amp;lt;/tex&amp;gt;, то добавим её в конец первого списка. В противном случае, добавим её в начало второго списка. Итоговое расписание — это конкатенация первого и второго списков.&lt;br /&gt;
&lt;br /&gt;
Псевдокод:&lt;br /&gt;
 J - множество работ&lt;br /&gt;
 Head &amp;lt;tex&amp;gt; \leftarrow \emptyset &amp;lt;/tex&amp;gt;&lt;br /&gt;
 Tail &amp;lt;tex&amp;gt; \leftarrow \emptyset &amp;lt;/tex&amp;gt;&lt;br /&gt;
 '''while''' J &amp;lt;tex&amp;gt; \ne \emptyset &amp;lt;/tex&amp;gt; &lt;br /&gt;
     '''do'''&lt;br /&gt;
         I &amp;lt;tex&amp;gt; \leftarrow &amp;lt;/tex&amp;gt; работа с минимальным значением &amp;lt;tex&amp;gt;min(p_1, p_2)&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''if''' &amp;lt;tex&amp;gt;p_1 &amp;lt;= p_2&amp;lt;/tex&amp;gt; Head &amp;lt;tex&amp;gt; \leftarrow &amp;lt;/tex&amp;gt; Head &amp;lt;tex&amp;gt;\circ&amp;lt;/tex&amp;gt; I&lt;br /&gt;
         '''else''' Tail &amp;lt;tex&amp;gt; \leftarrow &amp;lt;/tex&amp;gt; I &amp;lt;tex&amp;gt;\circ&amp;lt;/tex&amp;gt; Tail&lt;br /&gt;
         J &amp;lt;tex&amp;gt; \leftarrow &amp;lt;/tex&amp;gt; J &amp;lt;tex&amp;gt; \backslash &amp;lt;/tex&amp;gt; I&lt;br /&gt;
 Result &amp;lt;tex&amp;gt; \leftarrow &amp;lt;/tex&amp;gt; Head &amp;lt;tex&amp;gt;\circ&amp;lt;/tex&amp;gt; Tail&lt;br /&gt;
&lt;br /&gt;
== Задача Джонсона о двух станках с прерываниями &amp;lt;tex&amp;gt;F_2 \mid pmtn \mid C_{max}&amp;lt;/tex&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
Оптимальное решение этой задачи совпадает с решением задачи &amp;lt;tex&amp;gt;F_2 \mid \mid C_{max}&amp;lt;/tex&amp;gt;, приведённой выше. Докажем это.&lt;br /&gt;
&lt;br /&gt;
Пусть у нас есть оптимальное расписание для задачи &amp;lt;tex&amp;gt;F_2 \mid pmtn \mid C_{max}&amp;lt;/tex&amp;gt;. Покажем, что его за конечное число шагов можно преобразовать к расписанию без прерываний, не изменив при это значение &amp;lt;tex&amp;gt;C_{max}&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; 2 &amp;lt;/tex&amp;gt; или более разных промежутка времени. Тогда передвинем более ранний промежуток вправо по оси времени так, чтоб он заканчивался в тот момент, когда начинается второй промежуток, при этом работы, которые были между этими двумя промежутками, сдвинем влево на длину первого промежутка. Расписание при этом осталось корректным, так как работы на машинах по-прежнему не пересекаются, и каждая работа на второй машине делается после того, как она сделана на первой: работа &amp;lt;tex&amp;gt; J &amp;lt;/tex&amp;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;
&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;
== См. также ==&lt;br /&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;
== Литература ==&lt;br /&gt;
*[1][http://books.google.ru/books?id=FrUytMqlCv8C&amp;amp;printsec=frontcover&amp;amp;dq=scheduling+algorithms&amp;amp;hl=ru&amp;amp;sa=X&amp;amp;ei=0MPMT4HqKYSk4gSBm6gp&amp;amp;sqi=2&amp;amp;ved=0CDEQ6AEwAA#v=onepage&amp;amp;q=scheduling%20algorithms&amp;amp;f=false Scheduling Algorithms, Peter Brucker]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47288</id>
		<title>1ripi1sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47288"/>
				<updated>2015-06-02T21:27:38Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt; и вес &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum w_{i} C_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;C_{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;
===Задача 1===&lt;br /&gt;
&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid p_i = 1\mid \sum C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Описание алгоритма'''&lt;br /&gt;
&lt;br /&gt;
Входные данные для этой задачи: число работ &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&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;
===Задача 2===&lt;br /&gt;
&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid p_i = 1\mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Описание алгоритма'''&lt;br /&gt;
&lt;br /&gt;
Входные данные для этой задачи: число работ &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; и вес каждой работы &amp;lt;tex&amp;gt;w_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Для верного выполнения просто выставим работы по порядку убывания весов, тогда ответом будет &amp;lt;tex&amp;gt; \sum_{i = 1}^n(w_i C_i)&amp;lt;/tex&amp;gt;, так как мы &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; раз сложим время выполнения одной работы (которое в нашем случае единица) домноженное на вес этой работы.&lt;br /&gt;
&lt;br /&gt;
===Задача 3===&lt;br /&gt;
&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum f_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum f_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;f_{i}&amp;lt;/tex&amp;gt; {{---}} монотонная функция времени окончания работы &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; для работ &amp;lt;tex&amp;gt;i = 1, 2, ..., n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
'''Описание алгоритма'''&lt;br /&gt;
&lt;br /&gt;
Нам нужно распределить &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ в разное время. Если мы назначим время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; для работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; то цена будет &amp;lt;tex&amp;gt;f_i(t + 1)&amp;lt;/tex&amp;gt;. Так как нужно заполнить &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; временных промежутков, задача может быть решена за &amp;lt;tex&amp;gt;O(n^3)&amp;lt;/tex&amp;gt;. Функция &amp;lt;tex&amp;gt;f_i&amp;lt;/tex&amp;gt; монотонно неубывающая, тогда работы в расписании надо располагать как можно раньше для получения верного решения. &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; временных интервалов &amp;lt;tex&amp;gt;t_i&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; r_1 \leqslant r_2 \leqslant \ldots \leqslant r_n&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
'''Псевдокод'''&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;tex&amp;gt;t_1 \leftarrow r_1 &amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for'''  &amp;lt;tex&amp;gt; i \leftarrow 2&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      &amp;lt;tex&amp;gt; t_i \leftarrow &amp;lt;/tex&amp;gt; '''max'''&amp;lt;tex&amp;gt;(r_i, \ t_{i-1} - 1)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Описание алгоритма==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; {{---}} текущий момент времени.&amp;lt;br/&amp;gt;&lt;br /&gt;
Для каждого очередного значения &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt;, которое изменяется от &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; до времени окончания последней работы, будем:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Выбирать работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из множества невыполненных работ, у которой &amp;lt;tex&amp;gt;r_{i} \le time&amp;lt;/tex&amp;gt;, а значение &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt; максимально.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Если мы смогли найти работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, то выполняем её в момент времени &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; и удаляем из множества невыполненных работ.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Увеличиваем &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; на один.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Доказательство корректности алгоритма==&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Расписание, построенное данным алгоритмом, является корректным и оптимальным.&lt;br /&gt;
|proof=&lt;br /&gt;
Доказательство будем вести от противного.&amp;lt;br/&amp;gt;&lt;br /&gt;
Рассмотрим расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, полученное после выполнения нашего алгоритма, и оптимальное расписание &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Возьмём первый момент времени &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;, когда расписания  различаются. Пусть в этот момент времени  в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, будет выполняться работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt;, а в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; {{---}} работа с весом &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Это первый момент, в котором расписания отличаются, значит в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; выполнится в момент времени &amp;lt;tex&amp;gt;t_{2} &amp;gt; t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Поменяем местами работы с весами &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и полуим расписание &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Это возможно, потому что время появления этих работ не меньше &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При такой перестановке ответы на задачу для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt; будут отличаться на &lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;tex&amp;gt;t_{1}w_{2} + t_{2}w_{1} - t_{1}w_{1} + t_{2}w_{2} = t_{1}(w_{2} - w_{1}) + t_{2}(w_{1} - w_{2}) = (t_{1} - t_{2})(w_{2} - w_{1})&amp;lt;/tex&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Первая скобка отрицательная: &amp;lt;tex&amp;gt;t_{1} &amp;lt; t_{2}&amp;lt;/tex&amp;gt;. Вторая скобка тоже отрицательная из того, что в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_1&amp;lt;/tex&amp;gt; выполняется раньше, значит её вес должен быть больше &amp;lt;tex&amp;gt;w_2&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Итого имеем, что ответ для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; больше, чем ответ для &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Следовательно расписание &amp;lt;tex&amp;gt;S_2&amp;lt;/tex&amp;gt; неоптимальное. Получили противоречие. Значит не существует такого момента времени, когда расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; отличается от оптимального. Следовательно мы доказали, что оно оптимальное.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Псевдокод==&lt;br /&gt;
   &amp;lt;tex&amp;gt; S \leftarrow \{1 \dots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{time} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{answer} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''while''' &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow null &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt; i \in S&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt; r_{i} \leqslant \mathtt{time}&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt;w_i \geqslant max_{j = 1}^n w_j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; j \leftarrow i &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; \mathtt{time++}&amp;lt;/tex&amp;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;n + \max_{i = 1}^n r_{i}&amp;lt;/tex&amp;gt; шагов цикла. Определить максимум в множестве можно за время &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, используя , например, [[Wikipedia:ru:Очередь с приоритетом (программирование)|очередь с приоритетами]]. Значит общее время работы алгоритма &amp;lt;tex&amp;gt;O((n + \max_{i = 1}^n r_{i})\log n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 19 - 20&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 38 - 39&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 84 - 85&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47287</id>
		<title>1ripi1sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47287"/>
				<updated>2015-06-02T21:14:00Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt; и вес &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum w_{i} C_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;C_{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;
===Задача 1===&lt;br /&gt;
&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid p_i = 1\mid \sum C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Описание алгоритма'''&lt;br /&gt;
&lt;br /&gt;
Входные данные для этой задачи: число работ &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&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;
===Задача 2===&lt;br /&gt;
&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid p_i = 1\mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Описание алгоритма'''&lt;br /&gt;
&lt;br /&gt;
Входные данные для этой задачи: число работ &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; и вес каждой работы &amp;lt;tex&amp;gt;w_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Для верного выполнения просто выставим работы по порядку убывания весов, тогда ответом будет &amp;lt;tex&amp;gt; \sum_{i = 1}^n(w_i C_i)&amp;lt;/tex&amp;gt;, так как мы &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; раз сложим время выполнения одной работы (которое в нашем случае единица) домноженное на вес этой работы.&lt;br /&gt;
&lt;br /&gt;
===Задача 3===&lt;br /&gt;
&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum f_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum f_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;f_{i}&amp;lt;/tex&amp;gt; {{---}} монотонная функция времени окончания работы &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; для работ &amp;lt;tex&amp;gt;i = 1, 2, ..., n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
'''Описание алгоритма'''&lt;br /&gt;
&lt;br /&gt;
Нам нужно распределить &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ в разное время. Если мы назначим время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; для работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; то цена будет &amp;lt;tex&amp;gt;f_i(t + 1)&amp;lt;/tex&amp;gt;. Так как нужно рассмотреть &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; временных промежутков, задача может быть решена за &amp;lt;tex&amp;gt;O(n^3)&amp;lt;/tex&amp;gt;. Функция &amp;lt;tex&amp;gt;f_i&amp;lt;/tex&amp;gt; монотонно неубывающая, тогда работы в расписании надо располагать как можно раньше для получения верного решения. &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; временных интервалов &amp;lt;tex&amp;gt;t_i&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; r_1 \leqslant r_2 \leqslant \ldots \leqslant r_n&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
'''Псевдокод'''&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;tex&amp;gt;t_1 \leftarrow r_1 &amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for'''  &amp;lt;tex&amp;gt; i \leftarrow 2&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      &amp;lt;tex&amp;gt; t_i \leftarrow &amp;lt;/tex&amp;gt; '''max'''&amp;lt;tex&amp;gt;(r_i, \ t_{i-1} - 1)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Описание алгоритма==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; {{---}} текущий момент времени.&amp;lt;br/&amp;gt;&lt;br /&gt;
Для каждого очередного значения &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt;, которое изменяется от &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; до времени окончания последней работы, будем:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Выбирать работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из множества невыполненных работ, у которой &amp;lt;tex&amp;gt;r_{i} \le time&amp;lt;/tex&amp;gt;, а значение &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt; максимально.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Если мы смогли найти работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, то выполняем её в момент времени &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; и удаляем из множества невыполненных работ.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Увеличиваем &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; на один.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Доказательство корректности алгоритма==&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Расписание, построенное данным алгоритмом, является корректным и оптимальным.&lt;br /&gt;
|proof=&lt;br /&gt;
Доказательство будем вести от противного.&amp;lt;br/&amp;gt;&lt;br /&gt;
Рассмотрим расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, полученное после выполнения нашего алгоритма, и оптимальное расписание &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Возьмём первый момент времени &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;, когда расписания  различаются. Пусть в этот момент времени  в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, будет выполняться работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt;, а в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; {{---}} работа с весом &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Это первый момент, в котором расписания отличаются, значит в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; выполнится в момент времени &amp;lt;tex&amp;gt;t_{2} &amp;gt; t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Поменяем местами работы с весами &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и полуим расписание &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Это возможно, потому что время появления этих работ не меньше &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При такой перестановке ответы на задачу для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt; будут отличаться на &lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;tex&amp;gt;t_{1}w_{2} + t_{2}w_{1} - t_{1}w_{1} + t_{2}w_{2} = t_{1}(w_{2} - w_{1}) + t_{2}(w_{1} - w_{2}) = (t_{1} - t_{2})(w_{2} - w_{1})&amp;lt;/tex&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Первая скобка отрицательная: &amp;lt;tex&amp;gt;t_{1} &amp;lt; t_{2}&amp;lt;/tex&amp;gt;. Вторая скобка тоже отрицательная из того, что в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_1&amp;lt;/tex&amp;gt; выполняется раньше, значит её вес должен быть больше &amp;lt;tex&amp;gt;w_2&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Итого имеем, что ответ для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; больше, чем ответ для &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Следовательно расписание &amp;lt;tex&amp;gt;S_2&amp;lt;/tex&amp;gt; неоптимальное. Получили противоречие. Значит не существует такого момента времени, когда расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; отличается от оптимального. Следовательно мы доказали, что оно оптимальное.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Псевдокод==&lt;br /&gt;
   &amp;lt;tex&amp;gt; S \leftarrow \{1 \dots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{time} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{answer} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''while''' &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow null &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt; i \in S&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt; r_{i} \leqslant \mathtt{time}&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt;\max w_{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; j \leftarrow i &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; \mathtt{time++}&amp;lt;/tex&amp;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;n + \max r_{i}&amp;lt;/tex&amp;gt; шагов цикла. Определить максимум в множестве можно за время &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, используя , например, [[Wikipedia:ru:Очередь с приоритетом (программирование)|очередь с приоритетами]]. Значит общее время работы алгоритма &amp;lt;tex&amp;gt;O((n + \max r_{i})\log n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 19 - 20&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 38 - 39&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 84 - 85&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47284</id>
		<title>1ripi1sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47284"/>
				<updated>2015-06-02T19:45:20Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt; и вес &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum w_{i} C_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; {{---}} время окончания работы.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Перед решением основной задачи рассмотрим более простые.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Задача 1==&lt;br /&gt;
&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid p_i = 1\mid \sum C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Описание алгоритма'''&lt;br /&gt;
&lt;br /&gt;
Входные данные для этой задачи: число работ &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&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;
==Задача 2==&lt;br /&gt;
&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid p_i = 1\mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Описание алгоритма'''&lt;br /&gt;
&lt;br /&gt;
Входные данные для этой задачи: число работ &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; и вес каждой работы &amp;lt;tex&amp;gt;w_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Для верного выполнения просто выставим работы по порядку, тогда ответом будет &amp;lt;tex&amp;gt; \sum_{i = 1}^n(w_i)&amp;lt;/tex&amp;gt;, так как мы &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; раз сложим время выполнения одной работы (которое в нашем случае единица) домноженное на вес этой работы.&lt;br /&gt;
&lt;br /&gt;
==Задача 3==&lt;br /&gt;
&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum f_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum f_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;f_{i}&amp;lt;/tex&amp;gt; {{---}} монотонная функция времени окончания работы &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; для работ &amp;lt;tex&amp;gt;i = 1, 2, ..., n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
'''Описание алгоритма'''&lt;br /&gt;
&lt;br /&gt;
Нам нужно распределить &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ в разное время. Если мы назначим время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; для работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; то цена будет &amp;lt;tex&amp;gt;f_i(t + 1)&amp;lt;/tex&amp;gt;. Так как нужно рассмотреть &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; временных промежутков, задача может быть решена за &amp;lt;tex&amp;gt;O(n^3)&amp;lt;/tex&amp;gt;. Функция &amp;lt;tex&amp;gt;f_i&amp;lt;/tex&amp;gt; монотонно неубывающая, тогда работы в расписании надо располагать как можно раньше для получения верного решения. &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; временных интервалов &amp;lt;tex&amp;gt;t_i&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; r_1 \leqslant r_2 \leqslant \ldots \leqslant r_n&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
'''Псевдокод'''&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;tex&amp;gt;t_1 \leftarrow r_1 &amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for'''  &amp;lt;tex&amp;gt; i \leftarrow 2&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      &amp;lt;tex&amp;gt; t_i \leftarrow &amp;lt;/tex&amp;gt; '''max'''&amp;lt;tex&amp;gt;(r_i, \ t_{i-1} - 1)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Задача 4==&lt;br /&gt;
&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_j,p_j = p \mid \sum f_j&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вес всех работ &amp;lt;tex&amp;gt;w_i \geqslant 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
Для всех функций &amp;lt;tex&amp;gt;f_1, f_2, \ldots, f_n&amp;lt;/tex&amp;gt; выполняются следующие свойства:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_j&amp;lt;/tex&amp;gt; неубывающая функция для  &amp;lt;tex&amp;gt;j = 1, 2, \ldots, n&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_i - f_j&amp;lt;/tex&amp;gt; неубывающая функция для  &amp;lt;tex&amp;gt;i, j = 1, 2, \ldots, n&amp;lt;/tex&amp;gt; при &amp;lt;tex&amp;gt;i &amp;lt; j &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\sum w_i C_i&amp;lt;/tex&amp;gt; являются функцией &amp;lt;tex&amp;gt;f_j(C_j)&amp;lt;/tex&amp;gt;, так что по факту решаем задачу &amp;lt;tex&amp;gt;1 \mid r_j,p_j = p \mid \sum w_i C_i &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Описание алгоритма'''&lt;br /&gt;
&lt;br /&gt;
Пусть перед началом алгоритма работы пронумерованы в соответствии с свойствами для функций &amp;lt;tex&amp;gt;f_1, f_2, \ldots, f_n&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пояснение для псевдокода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; это множество {&amp;lt;tex&amp;gt;r_j + lp \mid j = 1, 2, \ldots, n; l = 0, 1, \ldots, n-1 &amp;lt;/tex&amp;gt;}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;F_k'(s,e)&amp;lt;/tex&amp;gt; это &amp;lt;tex&amp;gt;min(F_{k-1}(s,t_k)+F_{k-1}(t_k + p, e)+f_k(t_k + p) \mid t_k \in T, max(s, r_k) \leqslant t_k \leqslant e-p)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Псевдокод'''&lt;br /&gt;
&lt;br /&gt;
   '''for''' &amp;lt;tex&amp;gt; \forall s, e  \in T \ with \ s \leqslant e&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      &amp;lt;tex&amp;gt;F_0(s,e) \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for''' &amp;lt;tex&amp;gt;k \leftarrow 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      '''for''' &amp;lt;tex&amp;gt; \forall s, e  \in T \ with \ s \leqslant e&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
         &amp;lt;tex&amp;gt;&lt;br /&gt;
         F_k(s,e) \leftarrow&lt;br /&gt;
         \begin{cases}&lt;br /&gt;
         F_{k-1}(s,e) \ if\ r_k \notin [s - p,e);\\&lt;br /&gt;
         F_k'(s,e) \ overwise; &lt;br /&gt;
         \end{cases}&lt;br /&gt;
         &amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''Вычислить''' &amp;lt;tex&amp;gt;F_n($$ \min_{i=1}^n (r_i) $$, max_{t \in T}(t+p)  )&amp;lt;/tex&amp;gt;&lt;br /&gt;
==Описание алгоритма==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; {{---}} текущий момент времени.&amp;lt;br/&amp;gt;&lt;br /&gt;
Для каждого очередного значения &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt;, которое изменяется от &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; до времени окончания последней работы, будем:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Выбирать работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из множества невыполненных работ, у которой &amp;lt;tex&amp;gt;r_{i} \le time&amp;lt;/tex&amp;gt;, а значение &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt; максимально.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Если мы смогли найти работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, то выполняем её в момент времени &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; и удаляем из множества невыполненных работ.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Увеличиваем &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; на один.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Доказательство корректности алгоритма==&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Расписание, построенное данным алгоритмом, является корректным и оптимальным.&lt;br /&gt;
|proof=&lt;br /&gt;
Доказательство будем вести от противного.&amp;lt;br/&amp;gt;&lt;br /&gt;
Рассмотрим расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, полученное после выполнения нашего алгоритма, и оптимальное расписание &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Возьмём первый момент времени &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;, когда расписания  различаются. Пусть в этот момент времени  в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, будет выполняться работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt;, а в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; {{---}} работа с весом &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Это первый момент, в котором расписания отличаются, значит в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; выполнится в момент времени &amp;lt;tex&amp;gt;t_{2} &amp;gt; t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Поменяем местами работы с весами &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и полуим расписание &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Это возможно, потому что время появления этих работ не меньше &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При такой перестановке ответы на задачу для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt; будут отличаться на &lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;tex&amp;gt;t_{1}w_{2} + t_{2}w_{1} - t_{1}w_{1} + t_{2}w_{2} = t_{1}(w_{2} - w_{1}) + t_{2}(w_{1} - w_{2}) = (t_{1} - t_{2})(w_{2} - w_{1})&amp;lt;/tex&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Первая скобка отрицательная: &amp;lt;tex&amp;gt;t_{1} &amp;lt; t_{2}&amp;lt;/tex&amp;gt;. Вторая скобка тоже отрицательная из того, что в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_1&amp;lt;/tex&amp;gt; выполняется раньше, значит её вес должен быть больше &amp;lt;tex&amp;gt;w_2&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Итого имеем, что ответ для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; больше, чем ответ для &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Следовательно расписание &amp;lt;tex&amp;gt;S_2&amp;lt;/tex&amp;gt; неоптимальное. Получили противоречие. Значит не существует такого момента времени, когда расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; отличается от оптимального. Следовательно мы доказали, что оно оптимальное.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Псевдокод==&lt;br /&gt;
   &amp;lt;tex&amp;gt; S \leftarrow \{1 \dots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{time} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{answer} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''while''' &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow null &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt; i \in S&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt; r_{i} \leq \mathtt{time}&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt;\max w_{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; j \leftarrow i &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; \mathtt{time++}&amp;lt;/tex&amp;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;n + \max r_{i}&amp;lt;/tex&amp;gt; шагов цикла. Определить максимум в множестве можно за время &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, используя , например, очередь с приоритетами. Значит общее время работы алгоритма &amp;lt;tex&amp;gt;O((n + \max r_{i})\log n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 19 - 20&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 38 - 39&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 84 - 85&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 101 - 102&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Fpij1sumwu&amp;diff=47280</id>
		<title>Fpij1sumwu</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Fpij1sumwu&amp;diff=47280"/>
				<updated>2015-06-02T19:26:44Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;F \mid p_{ij} = 1 \mid \sum w_iu_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; станков, на которых нужно обработать &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; деталей. Каждую деталь нужно обработать по очереди на всех станках. Любая работа на любом станке выполняется единицу времени. Для каждой работы есть дедлайн &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; {{---}} время, до которого она должна быть закончена, и штраф &amp;lt;tex&amp;gt;w_i&amp;lt;/tex&amp;gt;, который нужно будет выплатить в случае, если работа была закончена после &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt;. Необходимо минимизировать суммарный штраф, который придется выплатить.&lt;br /&gt;
}}&lt;br /&gt;
==Описание алгоритма==&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Существует оптимальное расписание, в котором каждая работа делается непрерывно.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим расписание, в котором есть работы, которые делаются не непрерывно. Рассмотрим самый ранний разрыв: работа &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; делалась в моменты &amp;lt;tex&amp;gt;t(i), t(i)+1, \ldots, t(i)+k&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;k&amp;lt;m&amp;lt;/tex&amp;gt;, но не делалась в момент времени &amp;lt;tex&amp;gt;t(i)+k+1&amp;lt;/tex&amp;gt;. Докажем, что в момент времени &amp;lt;tex&amp;gt;t(i)+k+1&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;k+1&amp;lt;/tex&amp;gt;-й станок простаивает и можно продолжить делать &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ю работу. &lt;br /&gt;
&lt;br /&gt;
Пусть в момент времени &amp;lt;tex&amp;gt;t(i)+k+1&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;k+1&amp;lt;/tex&amp;gt;-м станке делается работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;. &lt;br /&gt;
В &amp;lt;tex&amp;gt;t(i)+k&amp;lt;/tex&amp;gt;-й момент времени &amp;lt;tex&amp;gt;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;t(i)+k+1&amp;lt;/tex&amp;gt;-й момент &amp;lt;tex&amp;gt;k+1&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;
&lt;br /&gt;
По этому утверждению, если работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; начали делать в &amp;lt;tex&amp;gt;t(i)&amp;lt;/tex&amp;gt;, то закончена она будет в &amp;lt;tex&amp;gt;t(i)+m&amp;lt;/tex&amp;gt;. Найдем время &amp;lt;tex&amp;gt;d'_i&amp;lt;/tex&amp;gt; такое, что начав выполнять в него работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, мы успеем выполнить ее до &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;d'_i = d_i - m&amp;lt;/tex&amp;gt;. Таким образом, вычтя из всех &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; число &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;, мы свели задачу к &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum w_i U_i&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Построив оптимальное расписание для &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum w_i U_i&amp;lt;/tex&amp;gt;, мы найдем времена, в которые нужно начинать выполнять работы. По утверждению выше, работы можно выполнять непрерывно.&lt;br /&gt;
&lt;br /&gt;
==Сложность алгоритма==&lt;br /&gt;
Задача &amp;lt;tex&amp;gt;F \mid p_{ij} = 1 \mid \sum w_iu_i&amp;lt;/tex&amp;gt; за &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; сводится к задаче &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum w_iu_i&amp;lt;/tex&amp;gt;. Задача &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum u_iw_i&amp;lt;/tex&amp;gt; решается за &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt;. После решения этой задачи, нужно вывести ответ, имеющий размер &amp;lt;tex&amp;gt;O(nm)&amp;lt;/tex&amp;gt;. Значит, итоговая сложность алгоритма {{---}} &amp;lt;tex&amp;gt;O(n \log n + nm)&amp;lt;/tex&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Flow_shop&amp;diff=47278</id>
		<title>Flow shop</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Flow_shop&amp;diff=47278"/>
				<updated>2015-06-02T19:17:55Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Описание ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Flow shop''' ('''&amp;lt;tex&amp;gt;F_{m}&amp;lt;/tex&amp;gt;''' в нотации Грэхема): В системе находится &amp;lt;tex&amp;gt; m &amp;lt;/tex&amp;gt; машин, работающих параллельно. Машины упорядочены. Каждая работа должна быть выполнена последовательно на всех машинах с первой по последнюю.}}&lt;br /&gt;
&lt;br /&gt;
Рассмотрим пример:  &amp;lt;tex&amp;gt;F \mid p_{ij} = 1 \mid C_{max}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Допустим, у нас &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; машин. В начальный момент времени мы можем начать обрабатывать любую работу на первой машине. В следующий момент на первой машине можно обрабатывать следующую работу, а на второй перейдёт предыдущая работа с первой машины, и так далее. Таким образом, на выполнение всех работ у нас уйдёт &amp;lt;tex&amp;gt;n + m - 1&amp;lt;/tex&amp;gt; единиц времени. Проиллюстрируем это диаграммой Гантта для случая &amp;lt;tex&amp;gt;n = 6, m = 5&amp;lt;/tex&amp;gt;:&lt;br /&gt;
         '''0   1   2   3   4   5   6   7   8   9   10'''&lt;br /&gt;
         -------------------------------------------&lt;br /&gt;
  '''M_1'''   |    1   2   3   4   5   6   -   -   -   -&lt;br /&gt;
  '''M_2'''   |    -   1   2   3   4   5   6   -   -   -&lt;br /&gt;
  '''M_3'''   |    -   -   1   2   3   4   5   6   -   -&lt;br /&gt;
  '''M_4'''   |    -   -   -   1   2   3   4   5   6   -&lt;br /&gt;
  '''M_5'''   |    -   -   -   -   1   2   3   4   5   6&lt;br /&gt;
&lt;br /&gt;
Заметим, что в данном случае &amp;lt;tex&amp;gt;p_{ij}&amp;lt;/tex&amp;gt; может быть равно не только единице, но и любой константе.&lt;br /&gt;
 &lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement = Любая задача вида &amp;lt;tex&amp;gt;F \mid p_{ij} = 1 \mid ? &amp;lt;/tex&amp;gt; сводится к соответствующей задаче вида &amp;lt;tex&amp;gt;1 \mid p_{ij} = 1 \mid ?&amp;lt;/tex&amp;gt;. &lt;br /&gt;
|proof = &lt;br /&gt;
Поскольку работа всегда заканчивает выполняться на последней машине, нас интересуют только времена завершения работ на последней машине. Также очевидно, что последняя машина может начать работать только в момент времени &amp;lt;tex&amp;gt; m - 1 &amp;lt;/tex&amp;gt;. Оказывается, что любое решение задачи &amp;lt;tex&amp;gt; 1 \mid p_{ij} = 1 \mid ? &amp;lt;/tex&amp;gt; с дедлайнами, уменьшенными на &amp;lt;tex&amp;gt; m - 1 &amp;lt;/tex&amp;gt; можно преобразовать в оптимальное расписание для задачи &amp;lt;tex&amp;gt;F \mid p_{ij} = 1 \mid ? &amp;lt;/tex&amp;gt;. Докажем это.&lt;br /&gt;
&lt;br /&gt;
Возьмем оптимальное расписание для соответствующей задачи с одним станком, выполним работы в этом порядке на первой машине, затем на второй машине, начиная с момента времени &amp;lt;tex&amp;gt; 1 &amp;lt;/tex&amp;gt;, и так далее, до выполнения на последней машине, начиная с &amp;lt;tex&amp;gt; m - 1 &amp;lt;/tex&amp;gt;. Это расписание корректно и соблюдает все дедлайны. Поскольку целевая функция совпадает с соответствующей функцией для задачи на одном станке, оно оптимально и для данной задачи.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Примером применения этого утверждения может служить задача [http://neerc.ifmo.ru/wiki/index.php?title=Fpij1sumwu]&lt;br /&gt;
&lt;br /&gt;
Задачи с произвольными временами выполнения работ почти все являются NP-трудными.&lt;br /&gt;
&lt;br /&gt;
== Задача Джонсона о двух станках &amp;lt;tex&amp;gt;F_2 \mid \mid C_{max}&amp;lt;/tex&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
Это единственная из flow shop задач с произвольными временами выполнения работ, которая решается за полиномиальное время.&lt;br /&gt;
&lt;br /&gt;
Приведём здесь решение задачи без доказательства, его можно посмотреть в [1].&lt;br /&gt;
&lt;br /&gt;
Оптимальное расписание для первой и второй машины будет совпадать. Таким образом, нам требуется найти порядок, в котором будут выполняться работы на каждой машине.&lt;br /&gt;
&lt;br /&gt;
Алгоритм такой: возьмём два пустых списка. Будем рассматривать работы в порядке возрастания &amp;lt;tex&amp;gt;min(p_1, p_2)&amp;lt;/tex&amp;gt;, то есть, минимума из времён выполнения данной работы на первой и второй машине. Если у работы &amp;lt;tex&amp;gt;p_1 \le p_2&amp;lt;/tex&amp;gt;, то добавим её в конец первого списка. В противном случае, добавим её в начало второго списка. Итоговое расписание — это конкатенация первого и второго списков.&lt;br /&gt;
&lt;br /&gt;
Псевдокод:&lt;br /&gt;
 J - множество работ&lt;br /&gt;
 Head &amp;lt;tex&amp;gt; \leftarrow \emptyset &amp;lt;/tex&amp;gt;&lt;br /&gt;
 Tail &amp;lt;tex&amp;gt; \leftarrow \emptyset &amp;lt;/tex&amp;gt;&lt;br /&gt;
 '''while''' J &amp;lt;tex&amp;gt; \ne \emptyset &amp;lt;/tex&amp;gt; &lt;br /&gt;
     '''do'''&lt;br /&gt;
         I &amp;lt;tex&amp;gt; \leftarrow &amp;lt;/tex&amp;gt; работа с минимальным значением &amp;lt;tex&amp;gt;min(p_1, p_2)&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''if''' &amp;lt;tex&amp;gt;p_1 &amp;lt;= p_2&amp;lt;/tex&amp;gt; Head &amp;lt;tex&amp;gt; \leftarrow &amp;lt;/tex&amp;gt; Head &amp;lt;tex&amp;gt;\circ&amp;lt;/tex&amp;gt; I&lt;br /&gt;
         '''else''' Tail &amp;lt;tex&amp;gt; \leftarrow &amp;lt;/tex&amp;gt; I &amp;lt;tex&amp;gt;\circ&amp;lt;/tex&amp;gt; Tail&lt;br /&gt;
         J &amp;lt;tex&amp;gt; \leftarrow &amp;lt;/tex&amp;gt; J &amp;lt;tex&amp;gt; \backslash &amp;lt;/tex&amp;gt; I&lt;br /&gt;
 Result &amp;lt;tex&amp;gt; \leftarrow &amp;lt;/tex&amp;gt; Head &amp;lt;tex&amp;gt;\circ&amp;lt;/tex&amp;gt; Tail&lt;br /&gt;
&lt;br /&gt;
== Задача Джонсона о двух станках с прерываниями &amp;lt;tex&amp;gt;F_2 \mid pmtn \mid C_{max}&amp;lt;/tex&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
Оптимальное решение этой задачи совпадает с решением задачи &amp;lt;tex&amp;gt;F_2 \mid \mid C_{max}&amp;lt;/tex&amp;gt;, приведённой выше. Докажем это.&lt;br /&gt;
&lt;br /&gt;
Пусть у нас есть оптимальное расписание для задачи &amp;lt;tex&amp;gt;F_2 \mid pmtn \mid C_{max}&amp;lt;/tex&amp;gt;. Покажем, что его за конечное число шагов можно преобразовать к расписанию без прерываний, не изменив при это значение &amp;lt;tex&amp;gt;C_{max}&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; 2 &amp;lt;/tex&amp;gt; или более разных промежутка времени. Тогда передвинем более ранний промежуток вправо по оси времени так, чтоб он заканчивался в тот момент, когда начинается второй промежуток, при этом работы, которые были между этими двумя промежутками, сдвинем влево на длину первого промежутка. Расписание при этом осталось корректным, так как работы на машинах по-прежнему не пересекаются, и каждая работа на второй машине делается после того, как она сделана на первой: работа &amp;lt;tex&amp;gt; J &amp;lt;/tex&amp;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;
&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;
== См. также ==&lt;br /&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;
== Литература ==&lt;br /&gt;
*[1][http://books.google.ru/books?id=FrUytMqlCv8C&amp;amp;printsec=frontcover&amp;amp;dq=scheduling+algorithms&amp;amp;hl=ru&amp;amp;sa=X&amp;amp;ei=0MPMT4HqKYSk4gSBm6gp&amp;amp;sqi=2&amp;amp;ved=0CDEQ6AEwAA#v=onepage&amp;amp;q=scheduling%20algorithms&amp;amp;f=false Scheduling Algorithms, Peter Brucker]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47277</id>
		<title>1ripi1sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47277"/>
				<updated>2015-06-02T19:11:23Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt; и вес &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum w_{i} C_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; {{---}} время окончания работы.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Перед решением основной задачи рассмотрим более простые.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Задача 1==&lt;br /&gt;
&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid p_i = 1\mid \sum C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Описание алгоритма'''&lt;br /&gt;
&lt;br /&gt;
Входные данные для этой задачи: число работ &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&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;
==Задача 2==&lt;br /&gt;
&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid p_i = 1\mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Описание алгоритма'''&lt;br /&gt;
&lt;br /&gt;
Входные данные для этой задачи: число работ &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; и вес каждой работы &amp;lt;tex&amp;gt;w_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Для верного выполнения просто выставим работы по порядку, тогда ответом будет &amp;lt;tex&amp;gt; \sum_{i = 1}^n(w_i)&amp;lt;/tex&amp;gt;, так как мы &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; раз сложим время выполнения одной работы (которое в нашем случае единица) домноженное на вес этой работы.&lt;br /&gt;
&lt;br /&gt;
==Задача 3==&lt;br /&gt;
&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum f_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum f_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;f_{i}&amp;lt;/tex&amp;gt; {{---}} монотонная функция времени окончания работы &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; для работ &amp;lt;tex&amp;gt;i = 1, 2, ..., n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
'''Описание алгоритма'''&lt;br /&gt;
&lt;br /&gt;
Нам нужно распределить &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ в разное время. Если мы назначим время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; для работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; то цена будет &amp;lt;tex&amp;gt;f_i(t + 1)&amp;lt;/tex&amp;gt;. Так как нужно рассмотреть &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; временных промежутков, задача может быть решена за &amp;lt;tex&amp;gt;O(n^3)&amp;lt;/tex&amp;gt;. Функция &amp;lt;tex&amp;gt;f_i&amp;lt;/tex&amp;gt; монотонно неубывающая, тогда работы в расписании надо располагать как можно раньше для получения верного решения. &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; временных интервалов &amp;lt;tex&amp;gt;t_i&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; r_1 \leqslant r_2 \leqslant \ldots \leqslant r_n&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
'''Псевдокод'''&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;tex&amp;gt;t_1 \leftarrow r_1 &amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for'''  &amp;lt;tex&amp;gt; i \leftarrow 2&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      &amp;lt;tex&amp;gt; t_i \leftarrow &amp;lt;/tex&amp;gt; '''max'''&amp;lt;tex&amp;gt;(r_i, \ t_{i-1} - 1)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Задача 4==&lt;br /&gt;
&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_j,p_j = p \mid \sum f_j&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вес всех работ &amp;lt;tex&amp;gt;w_i \geqslant 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
Для всех функций &amp;lt;tex&amp;gt;f_1, f_2, \ldots, f_n&amp;lt;/tex&amp;gt; выполняются следующие свойства:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_j&amp;lt;/tex&amp;gt; неубывающая функция для  &amp;lt;tex&amp;gt;j = 1, 2, \ldots, n&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_i - f_j&amp;lt;/tex&amp;gt; неубывающая функция для  &amp;lt;tex&amp;gt;i, j = 1, 2, \ldots, n&amp;lt;/tex&amp;gt; при &amp;lt;tex&amp;gt;i &amp;lt; j &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\sum w_i C_i&amp;lt;/tex&amp;gt; являются функцией &amp;lt;tex&amp;gt;f_j(C_j)&amp;lt;/tex&amp;gt;, так что по факту решаем задачу &amp;lt;tex&amp;gt;1 \mid r_j,p_j = p \mid \sum w_i C_i &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Описание алгоритма'''&lt;br /&gt;
&lt;br /&gt;
Пусть перед началом алгоритма работы пронумерованы в соответствии с свойствами для функций &amp;lt;tex&amp;gt;f_1, f_2, \ldots, f_n&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пояснение для псевдокода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; это множество {&amp;lt;tex&amp;gt;r_j + lp \mid j = 1, 2, \ldots, n; l = 0, 1, \ldots, n-1 &amp;lt;/tex&amp;gt;}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;F_k'(s,e)&amp;lt;/tex&amp;gt; это &amp;lt;tex&amp;gt;min(F_{k-1}(s,t_k)+F_{k-1}(t_k + p, e)+f_k(t_k + p) \mid t_k \in T, max(s, r_k) \leqslant t_k \leqslant e-p)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Псевдокод'''&lt;br /&gt;
&lt;br /&gt;
   '''for all''' &amp;lt;tex&amp;gt;s, e  \in T \ with \ s \leqslant e&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      &amp;lt;tex&amp;gt;F_0(s,e) \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for''' &amp;lt;tex&amp;gt;k \leftarrow 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      '''for all''' &amp;lt;tex&amp;gt;s, e  \in T \ with \ s \leqslant e&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
         &amp;lt;tex&amp;gt;&lt;br /&gt;
         F_k(s,e) \leftarrow&lt;br /&gt;
         \begin{cases}&lt;br /&gt;
         F_{k-1}(s,e) \ if\ r_k \notin [s - p,e);\\&lt;br /&gt;
         F_k'(s,e) \ overwise; &lt;br /&gt;
         \end{cases}&lt;br /&gt;
         &amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''Вычислить''' &amp;lt;tex&amp;gt;F_n($$ \min_{i=1}^n (r_i) $$, max_{t \in T}(t+p)  )&amp;lt;/tex&amp;gt;&lt;br /&gt;
==Описание алгоритма==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; {{---}} текущий момент времени.&amp;lt;br/&amp;gt;&lt;br /&gt;
Для каждого очередного значения &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt;, которое изменяется от &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; до времени окончания последней работы, будем:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Выбирать работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из множества невыполненных работ, у которой &amp;lt;tex&amp;gt;r_{i} \le time&amp;lt;/tex&amp;gt;, а значение &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt; максимально.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Если мы смогли найти работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, то выполняем её в момент времени &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; и удаляем из множества невыполненных работ.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Увеличиваем &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; на один.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Доказательство корректности алгоритма==&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Расписание, построенное данным алгоритмом, является корректным и оптимальным.&lt;br /&gt;
|proof=&lt;br /&gt;
Доказательство будем вести от противного.&amp;lt;br/&amp;gt;&lt;br /&gt;
Рассмотрим расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, полученное после выполнения нашего алгоритма, и оптимальное расписание &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Возьмём первый момент времени &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;, когда расписания  различаются. Пусть в этот момент времени  в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, будет выполняться работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt;, а в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; {{---}} работа с весом &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Это первый момент, в котором расписания отличаются, значит в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; выполнится в момент времени &amp;lt;tex&amp;gt;t_{2} &amp;gt; t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Поменяем местами работы с весами &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и полуим расписание &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Это возможно, потому что время появления этих работ не меньше &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При такой перестановке ответы на задачу для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt; будут отличаться на &lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;tex&amp;gt;t_{1}w_{2} + t_{2}w_{1} - t_{1}w_{1} + t_{2}w_{2} = t_{1}(w_{2} - w_{1}) + t_{2}(w_{1} - w_{2}) = (t_{1} - t_{2})(w_{2} - w_{1})&amp;lt;/tex&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Первая скобка отрицательная: &amp;lt;tex&amp;gt;t_{1} &amp;lt; t_{2}&amp;lt;/tex&amp;gt;. Вторая скобка тоже отрицательная из того, что в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_1&amp;lt;/tex&amp;gt; выполняется раньше, значит её вес должен быть больше &amp;lt;tex&amp;gt;w_2&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Итого имеем, что ответ для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; больше, чем ответ для &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Следовательно расписание &amp;lt;tex&amp;gt;S_2&amp;lt;/tex&amp;gt; неоптимальное. Получили противоречие. Значит не существует такого момента времени, когда расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; отличается от оптимального. Следовательно мы доказали, что оно оптимальное.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Псевдокод==&lt;br /&gt;
   &amp;lt;tex&amp;gt; S \leftarrow \{1 \dots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{time} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{answer} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''while''' &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow null &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt; i \in S&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt; r_{i} \leq \mathtt{time}&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt;\max w_{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; j \leftarrow i &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; \mathtt{time++}&amp;lt;/tex&amp;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;n + \max r_{i}&amp;lt;/tex&amp;gt; шагов цикла. Определить максимум в множестве можно за время &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, используя , например, очередь с приоритетами. Значит общее время работы алгоритма &amp;lt;tex&amp;gt;O((n + \max r_{i})\log n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 19 - 20&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 38 - 39&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 84 - 85&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 101 - 102&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47276</id>
		<title>1ripi1sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47276"/>
				<updated>2015-06-02T19:00:27Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt; и вес &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum w_{i} C_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; {{---}} время окончания работы.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Перед решением основной задачи рассмотрим более простые.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Задача 1==&lt;br /&gt;
&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid p_i = 1\mid \sum C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Описание алгоритма'''&lt;br /&gt;
&lt;br /&gt;
Входные данные для этой задачи: число работ &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&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;
==Задача 2==&lt;br /&gt;
&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum f_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum f_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;f_{i}&amp;lt;/tex&amp;gt; {{---}} монотонная функция времени окончания работы &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; для работ &amp;lt;tex&amp;gt;i = 1, 2, ..., n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
'''Описание алгоритма'''&lt;br /&gt;
&lt;br /&gt;
Нам нужно распределить &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ в разное время. Если мы назначим время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; для работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; то цена будет &amp;lt;tex&amp;gt;f_i(t + 1)&amp;lt;/tex&amp;gt;. Так как нужно рассмотреть &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; временных промежутков, задача может быть решена за &amp;lt;tex&amp;gt;O(n^3)&amp;lt;/tex&amp;gt;. Функция &amp;lt;tex&amp;gt;f_i&amp;lt;/tex&amp;gt; монотонно неубывающая, тогда работы в расписании надо располагать как можно раньше для получения верного решения. &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; временных интервалов &amp;lt;tex&amp;gt;t_i&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; r_1 \leqslant r_2 \leqslant \ldots \leqslant r_n&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
'''Псевдокод'''&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;tex&amp;gt;t_1 \leftarrow r_1 &amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for'''  &amp;lt;tex&amp;gt; i \leftarrow 2&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      &amp;lt;tex&amp;gt; t_i \leftarrow &amp;lt;/tex&amp;gt; '''max'''&amp;lt;tex&amp;gt;(r_i, \ t_{i-1} - 1)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Задача 3==&lt;br /&gt;
&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_j,p_j = p \mid \sum f_j&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вес всех работ &amp;lt;tex&amp;gt;w_i \geqslant 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
Для всех функций &amp;lt;tex&amp;gt;f_1, f_2, \ldots, f_n&amp;lt;/tex&amp;gt; выполняются следующие свойства:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_j&amp;lt;/tex&amp;gt; неубывающая функция для  &amp;lt;tex&amp;gt;j = 1, 2, \ldots, n&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_i - f_j&amp;lt;/tex&amp;gt; неубывающая функция для  &amp;lt;tex&amp;gt;i, j = 1, 2, \ldots, n&amp;lt;/tex&amp;gt; при &amp;lt;tex&amp;gt;i &amp;lt; j &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\sum w_i C_i&amp;lt;/tex&amp;gt; являются функцией &amp;lt;tex&amp;gt;f_j(C_j)&amp;lt;/tex&amp;gt;, так что по факту решаем задачу &amp;lt;tex&amp;gt;1 \mid r_j,p_j = p \mid \sum w_i C_i &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Описание алгоритма'''&lt;br /&gt;
&lt;br /&gt;
Пусть перед началом алгоритма работы пронумерованы в соответствии с свойствами для функций &amp;lt;tex&amp;gt;f_1, f_2, \ldots, f_n&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пояснение для псевдокода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; это множество {&amp;lt;tex&amp;gt;r_j + lp \mid j = 1, 2, \ldots, n; l = 0, 1, \ldots, n-1 &amp;lt;/tex&amp;gt;}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;F_k'(s,e)&amp;lt;/tex&amp;gt; это &amp;lt;tex&amp;gt;min(F_{k-1}(s,t_k)+F_{k-1}(t_k + p, e)+f_k(t_k + p) \mid t_k \in T, max(s, r_k) \leqslant t_k \leqslant e-p)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Псевдокод'''&lt;br /&gt;
&lt;br /&gt;
   '''for all''' &amp;lt;tex&amp;gt;s, e  \in T \ with \ s \leqslant e&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      &amp;lt;tex&amp;gt;F_0(s,e) \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for''' &amp;lt;tex&amp;gt;k \leftarrow 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
      '''for all''' &amp;lt;tex&amp;gt;s, e  \in T \ with \ s \leqslant e&amp;lt;/tex&amp;gt; '''do'''&lt;br /&gt;
         &amp;lt;tex&amp;gt;&lt;br /&gt;
         F_k(s,e) \leftarrow&lt;br /&gt;
         \begin{cases}&lt;br /&gt;
         F_{k-1}(s,e) \ if\ r_k \notin [s - p,e);\\&lt;br /&gt;
         F_k'(s,e) \ overwise; &lt;br /&gt;
         \end{cases}&lt;br /&gt;
         &amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''Вычислить''' &amp;lt;tex&amp;gt;F_n($$ \min_{i=1}^n (r_i) $$, max_{t \in T}(t+p)  )&amp;lt;/tex&amp;gt;&lt;br /&gt;
==Описание алгоритма==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; {{---}} текущий момент времени.&amp;lt;br/&amp;gt;&lt;br /&gt;
Для каждого очередного значения &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt;, которое изменяется от &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; до времени окончания последней работы, будем:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Выбирать работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из множества невыполненных работ, у которой &amp;lt;tex&amp;gt;r_{i} \le time&amp;lt;/tex&amp;gt;, а значение &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt; максимально.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Если мы смогли найти работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, то выполняем её в момент времени &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; и удаляем из множества невыполненных работ.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Увеличиваем &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; на один.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Доказательство корректности алгоритма==&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Расписание, построенное данным алгоритмом, является корректным и оптимальным.&lt;br /&gt;
|proof=&lt;br /&gt;
Доказательство будем вести от противного.&amp;lt;br/&amp;gt;&lt;br /&gt;
Рассмотрим расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, полученное после выполнения нашего алгоритма, и оптимальное расписание &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Возьмём первый момент времени &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;, когда расписания  различаются. Пусть в этот момент времени  в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, будет выполняться работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt;, а в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; {{---}} работа с весом &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Это первый момент, в котором расписания отличаются, значит в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; выполнится в момент времени &amp;lt;tex&amp;gt;t_{2} &amp;gt; t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Поменяем местами работы с весами &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и полуим расписание &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Это возможно, потому что время появления этих работ не меньше &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При такой перестановке ответы на задачу для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt; будут отличаться на &lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;tex&amp;gt;t_{1}w_{2} + t_{2}w_{1} - t_{1}w_{1} + t_{2}w_{2} = t_{1}(w_{2} - w_{1}) + t_{2}(w_{1} - w_{2}) = (t_{1} - t_{2})(w_{2} - w_{1})&amp;lt;/tex&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Первая скобка отрицательная: &amp;lt;tex&amp;gt;t_{1} &amp;lt; t_{2}&amp;lt;/tex&amp;gt;. Вторая скобка тоже отрицательная из того, что в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_1&amp;lt;/tex&amp;gt; выполняется раньше, значит её вес должен быть больше &amp;lt;tex&amp;gt;w_2&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Итого имеем, что ответ для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; больше, чем ответ для &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Следовательно расписание &amp;lt;tex&amp;gt;S_2&amp;lt;/tex&amp;gt; неоптимальное. Получили противоречие. Значит не существует такого момента времени, когда расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; отличается от оптимального. Следовательно мы доказали, что оно оптимальное.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Псевдокод==&lt;br /&gt;
   &amp;lt;tex&amp;gt; S \leftarrow \{1 \dots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{time} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; \mathtt{answer} \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''while''' &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow null &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt; i \in S&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt; r_{i} \leq \mathtt{time}&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt;\max w_{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; j \leftarrow i &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; \mathtt{time++}&amp;lt;/tex&amp;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;n + \max r_{i}&amp;lt;/tex&amp;gt; шагов цикла. Определить максимум в множестве можно за время &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, используя , например, очередь с приоритетами. Значит общее время работы алгоритма &amp;lt;tex&amp;gt;O((n + \max r_{i})\log n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 19 - 20&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 38 - 39&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 84 - 85&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 101 - 102&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Flow_shop&amp;diff=47221</id>
		<title>Flow shop</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Flow_shop&amp;diff=47221"/>
				<updated>2015-06-02T09:36:55Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Описание ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Flow shop''' ('''&amp;lt;tex&amp;gt;F_{m}&amp;lt;/tex&amp;gt;''' в нотации Грэхема): В системе находится &amp;lt;tex&amp;gt; m &amp;lt;/tex&amp;gt; машин, работающих параллельно. Машины упорядочены. Каждая работа должна быть выполнена последовательно на всех машинах с первой по последнюю.}}&lt;br /&gt;
&lt;br /&gt;
Рассмотрим пример:  &amp;lt;tex&amp;gt;F \mid p_{ij} = 1 \mid C_{max}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Допустим, у нас &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; машин. В начальный момент времени мы можем начать обрабатывать любую работу на первой машине. В следующий момент на первой машине можно обрабатывать следующую работу, а на второй перейдёт предыдущая работа с первой машины, и так далее. Таким образом, на выполнение всех работ у нас уйдёт &amp;lt;tex&amp;gt;n + m - 1&amp;lt;/tex&amp;gt; единиц времени. Проиллюстрируем это диаграммой Гантта для случая &amp;lt;tex&amp;gt;n = 6, m = 5&amp;lt;/tex&amp;gt;:&lt;br /&gt;
         '''0   1   2   3   4   5   6   7   8   9   10'''&lt;br /&gt;
         -------------------------------------------&lt;br /&gt;
  '''M_1'''   |    1   2   3   4   5   6   -   -   -   -&lt;br /&gt;
  '''M_2'''   |    -   1   2   3   4   5   6   -   -   -&lt;br /&gt;
  '''M_3'''   |    -   -   1   2   3   4   5   6   -   -&lt;br /&gt;
  '''M_4'''   |    -   -   -   1   2   3   4   5   6   -&lt;br /&gt;
  '''M_5'''   |    -   -   -   -   1   2   3   4   5   6&lt;br /&gt;
&lt;br /&gt;
Заметим, что в данном случае &amp;lt;tex&amp;gt;p_{ij}&amp;lt;/tex&amp;gt; может быть равно не только единице, но и любой константе.&lt;br /&gt;
 &lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement = Любая задача вида &amp;lt;tex&amp;gt;F \mid p_{ij} = 1 \mid ? &amp;lt;/tex&amp;gt; сводится к соответствующей задаче вида &amp;lt;tex&amp;gt;1 \mid p_{ij} = 1 \mid ?&amp;lt;/tex&amp;gt;. &lt;br /&gt;
|proof = &lt;br /&gt;
Поскольку работа всегда заканчивает выполняться на последней машине, нас интересуют только времена завершения работ на последней машине. Также очевидно, что последняя машина может начать работать только в момент времени &amp;lt;tex&amp;gt; m - 1 &amp;lt;/tex&amp;gt;. Оказывается, что любое решение задачи &amp;lt;tex&amp;gt; 1 \mid p_{ij} = 1 \mid ? &amp;lt;/tex&amp;gt; с дедлайнами, уменьшенными на &amp;lt;tex&amp;gt; m - 1 &amp;lt;/tex&amp;gt; можно преобразовать в оптимальное расписание для задачи &amp;lt;tex&amp;gt;F \mid p_{ij} = 1 \mid ? &amp;lt;/tex&amp;gt;. Докажем это.&lt;br /&gt;
&lt;br /&gt;
Возьмем оптимальное расписание для соответствующей задачи с одним станком, выполним работы в этом порядке на первой машине, затем на второй машине, начиная с момента времени &amp;lt;tex&amp;gt; 1 &amp;lt;/tex&amp;gt;, и так далее, до выполнения на последней машине, начиная с &amp;lt;tex&amp;gt; m - 1 &amp;lt;/tex&amp;gt;. Это расписание корректно и соблюдает все дедлайны. Поскольку целевая функция совпадает с соответствующей функцией для задачи на одном станке, оно оптимально и для данной задачи.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Задачи с произвольными временами выполнения работ почти все являются NP-трудными.&lt;br /&gt;
&lt;br /&gt;
== Задача Джонсона о двух станках &amp;lt;tex&amp;gt;F_2 \mid \mid C_{max}&amp;lt;/tex&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
Это единственная из flow shop задач с произвольными временами выполнения работ, которая решается за полиномиальное время.&lt;br /&gt;
&lt;br /&gt;
Приведём здесь решение задачи без доказательства, его можно посмотреть в [1].&lt;br /&gt;
&lt;br /&gt;
Оптимальное расписание для первой и второй машины будет совпадать. Таким образом, нам требуется найти порядок, в котором будут выполняться работы на каждой машине.&lt;br /&gt;
&lt;br /&gt;
Алгоритм такой: возьмём два пустых списка. Будем рассматривать работы в порядке возрастания &amp;lt;tex&amp;gt;min(p_1, p_2)&amp;lt;/tex&amp;gt;, то есть, минимума из времён выполнения данной работы на первой и второй машине. Если у работы &amp;lt;tex&amp;gt;p_1 \le p_2&amp;lt;/tex&amp;gt;, то добавим её в конец первого списка. В противном случае, добавим её в начало второго списка. Итоговое расписание — это конкатенация первого и второго списков.&lt;br /&gt;
&lt;br /&gt;
Псевдокод:&lt;br /&gt;
 J - множество работ&lt;br /&gt;
 Head &amp;lt;tex&amp;gt; \leftarrow \emptyset &amp;lt;/tex&amp;gt;&lt;br /&gt;
 Tail &amp;lt;tex&amp;gt; \leftarrow \emptyset &amp;lt;/tex&amp;gt;&lt;br /&gt;
 '''while''' J &amp;lt;tex&amp;gt; \ne \emptyset &amp;lt;/tex&amp;gt; &lt;br /&gt;
     '''do'''&lt;br /&gt;
         I &amp;lt;tex&amp;gt; \leftarrow &amp;lt;/tex&amp;gt; работа с минимальным значением &amp;lt;tex&amp;gt;min(p_1, p_2)&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''if''' &amp;lt;tex&amp;gt;p_1 &amp;lt;= p_2&amp;lt;/tex&amp;gt; Head &amp;lt;tex&amp;gt; \leftarrow &amp;lt;/tex&amp;gt; Head &amp;lt;tex&amp;gt;\circ&amp;lt;/tex&amp;gt; I&lt;br /&gt;
         '''else''' Tail &amp;lt;tex&amp;gt; \leftarrow &amp;lt;/tex&amp;gt; I &amp;lt;tex&amp;gt;\circ&amp;lt;/tex&amp;gt; Tail&lt;br /&gt;
         J &amp;lt;tex&amp;gt; \leftarrow &amp;lt;/tex&amp;gt; J &amp;lt;tex&amp;gt; \backslash &amp;lt;/tex&amp;gt; I&lt;br /&gt;
 Result &amp;lt;tex&amp;gt; \leftarrow &amp;lt;/tex&amp;gt; Head &amp;lt;tex&amp;gt;\circ&amp;lt;/tex&amp;gt; Tail&lt;br /&gt;
&lt;br /&gt;
== Задача Джонсона о двух станках с прерываниями &amp;lt;tex&amp;gt;F_2 \mid pmtn \mid C_{max}&amp;lt;/tex&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
Оптимальное решение этой задачи совпадает с решением задачи &amp;lt;tex&amp;gt;F_2 \mid \mid C_{max}&amp;lt;/tex&amp;gt;, приведённой выше. Докажем это.&lt;br /&gt;
&lt;br /&gt;
Пусть у нас есть оптимальное расписание для задачи &amp;lt;tex&amp;gt;F_2 \mid pmtn \mid C_{max}&amp;lt;/tex&amp;gt;. Покажем, что его за конечное число шагов можно преобразовать к расписанию без прерываний, не изменив при это значение &amp;lt;tex&amp;gt;C_{max}&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; 2 &amp;lt;/tex&amp;gt; или более разных промежутка времени. Тогда передвинем более ранний промежуток вправо по оси времени так, чтоб он заканчивался в тот момент, когда начинается второй промежуток, при этом работы, которые были между этими двумя промежутками, сдвинем влево на длину первого промежутка. Расписание при этом осталось корректным, так как работы на машинах по-прежнему не пересекаются, и каждая работа на второй машине делается после того, как она сделана на первой: работа &amp;lt;tex&amp;gt; J &amp;lt;/tex&amp;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;
&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;F \mid p_{ij} = 1 \mid \sum w_iu_i&amp;lt;/tex&amp;gt; ==&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; станков, на которых нужно обработать &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; деталей. Каждую деталь нужно обработать по очереди на всех станках. Любая работа на любом станке выполняется единицу времени. Для каждой работы есть дедлайн &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; {{---}} время, до которого она должна быть закончена, и штраф &amp;lt;tex&amp;gt;w_i&amp;lt;/tex&amp;gt;, который нужно будет выплатить в случае, если работа была закончена после &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt;. Необходимо минимизировать суммарный штраф, который придется выплатить.&lt;br /&gt;
}}&lt;br /&gt;
Задача &amp;lt;tex&amp;gt;F \mid p_{ij} = 1 \mid \sum w_iu_i&amp;lt;/tex&amp;gt; за &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; сводится к задаче &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum w_iu_i&amp;lt;/tex&amp;gt;. Задача &amp;lt;tex&amp;gt;1 \mid p_i = 1 \mid \sum u_iw_i&amp;lt;/tex&amp;gt; решается за &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt;. После решения этой задачи, нужно вывести ответ, имеющий размер &amp;lt;tex&amp;gt;O(nm)&amp;lt;/tex&amp;gt;. Итоговая сложность алгоритма {{---}} &amp;lt;tex&amp;gt;O(n \log n + nm)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&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;
== Литература ==&lt;br /&gt;
*[1][http://books.google.ru/books?id=FrUytMqlCv8C&amp;amp;printsec=frontcover&amp;amp;dq=scheduling+algorithms&amp;amp;hl=ru&amp;amp;sa=X&amp;amp;ei=0MPMT4HqKYSk4gSBm6gp&amp;amp;sqi=2&amp;amp;ved=0CDEQ6AEwAA#v=onepage&amp;amp;q=scheduling%20algorithms&amp;amp;f=false Scheduling Algorithms, Peter Brucker]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47220</id>
		<title>1ripi1sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47220"/>
				<updated>2015-06-02T09:26:40Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt; и вес &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum w_{i} C_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; {{---}} время окончания работы.&lt;br /&gt;
}}&lt;br /&gt;
Перед решением этой задачи рассмотрим более простую.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum f_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum f_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;f_{i}&amp;lt;/tex&amp;gt; {{---}} монотонная функция времени окончания работы &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; для работ &amp;lt;tex&amp;gt;i = 1, 2, ..., n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Описание алгоритма простой задачи==&lt;br /&gt;
Нам нужно распределить &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ в разное время. Если мы назначим время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; для работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; то цена будет &amp;lt;tex&amp;gt;f_i(t + 1)&amp;lt;/tex&amp;gt;. Так как нужно рассмотреть &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; временных промежутков, задача может быть решена за &amp;lt;tex&amp;gt;O(n^3)&amp;lt;/tex&amp;gt;. Функция &amp;lt;tex&amp;gt;f_i&amp;lt;/tex&amp;gt; монотонно неубывающая, тогда работы в расписании надо располагать как можно раньше для получения верного решения. &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; временных интервалов &amp;lt;tex&amp;gt;t_i&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; r_1 &amp;lt;= r_2 &amp;lt;=... &amp;lt;= r_n&amp;lt;/tex&amp;gt; &lt;br /&gt;
==Псевдокод простой задачи==&lt;br /&gt;
   &amp;lt;tex&amp;gt;t_1 \leftarrow r_1 &amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''FOR'''  &amp;lt;tex&amp;gt; i \leftarrow 2&amp;lt;/tex&amp;gt; '''TO''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; '''DO'''&lt;br /&gt;
      &amp;lt;tex&amp;gt; t_i \leftarrow &amp;lt;/tex&amp;gt; '''MAX'''&amp;lt;tex&amp;gt;(r_i, \ t_{i-1} - 1)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Описание алгоритма основной задачи==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; {{---}} текущий момент времени.&amp;lt;br/&amp;gt;&lt;br /&gt;
Для каждого очередного значения &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt;, которое изменяется от &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; до времени окончания последней работы, будем:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Выбирать работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из множества невыполненных работ, у которой &amp;lt;tex&amp;gt;r_{i} \le time&amp;lt;/tex&amp;gt;, а значение &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt; максимально.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Если мы смогли найти работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, то выполняем её в момент времени &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; и удаляем из множества невыполненных работ.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Увеличиваем &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; на один.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Доказательство корректности алгоритма основной задачи==&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Расписание, построенное данным алгоритмом, является корректным и оптимальным.&lt;br /&gt;
|proof=&lt;br /&gt;
Доказательство будем вести от противного.&amp;lt;br/&amp;gt;&lt;br /&gt;
Рассмотрим расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, полученное после выполнения нашего алгоритма, и оптимальное расписание &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Возьмём первый момент времени &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;, когда расписания  различаются. Пусть в этот момент времени  в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, будет выполняться работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt;, а в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; {{---}} работа с весом &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Это первый момент, в котором расписания отличаются, значит в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; выполнится в момент времени &amp;lt;tex&amp;gt;t_{2} &amp;gt; t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Поменяем местами работы с весами &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и полуим расписание &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Это возможно, потому что время появления этих работ не меньше &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При такой перестановке ответы на задачу для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt; будут отличаться на &lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;tex&amp;gt;t_{1}w_{2} + t_{2}w_{1} - t_{1}w_{1} + t_{2}w_{2} = t_{1}(w_{2} - w_{1}) + t_{2}(w_{1} - w_{2}) = (t_{1} - t_{2})(w_{2} - w_{1})&amp;lt;/tex&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Первая скобка отрицательная: &amp;lt;tex&amp;gt;t_{1} &amp;lt; t_{2}&amp;lt;/tex&amp;gt;. Вторая скобка тоже отрицательная из того, что в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_1&amp;lt;/tex&amp;gt; выполняется раньше, значит её вес должен быть больше &amp;lt;tex&amp;gt;w_2&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Итого имеем, что ответ для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; больше, чем ответ для &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Следовательно расписание &amp;lt;tex&amp;gt;S_2&amp;lt;/tex&amp;gt; неоптимальное. Получили противоречие. Значит не существует такого момента времени, когда расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; отличается от оптимального. Следовательно мы доказали, что оно оптимальное.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Псевдокод основной задачи==&lt;br /&gt;
   &amp;lt;tex&amp;gt; S \leftarrow \{1 \dots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; time \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; answer \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''WHILE''' &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow null &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''IF''' &amp;lt;tex&amp;gt; i \in S&amp;lt;/tex&amp;gt; '''AND''' &amp;lt;tex&amp;gt; r_{i} \leq time&amp;lt;/tex&amp;gt; '''AND''' &amp;lt;tex&amp;gt;\max w_{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; j \leftarrow i &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''IF''' &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; Answer \leftarrow Answer + time \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; time++&amp;lt;/tex&amp;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;n + \max r_{i}&amp;lt;/tex&amp;gt; шагов цикла. Определить максимум в множестве можно за время &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, используя , например, очередь с приоритетами. Значит общее время работы алгоритма &amp;lt;tex&amp;gt;O((n + \max r_{i})\log n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 19 - 20&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 84 - 85&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47219</id>
		<title>1ripi1sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47219"/>
				<updated>2015-06-02T09:14:07Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt; и вес &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum w_{i} C_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; {{---}} время окончания работы.&lt;br /&gt;
}}&lt;br /&gt;
Перед решением этой задачи рассмотрим более простую.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum f_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum f_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;f_{i}&amp;lt;/tex&amp;gt; {{---}} монотонная функция времени окончания работы &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Описание алгоритма простой задачи==&lt;br /&gt;
Нам нужно распределить &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ в разное время. Если мы назначим время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; для работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; то цена будет &amp;lt;tex&amp;gt;f_i(t + 1)&amp;lt;/tex&amp;gt;. Далее покажем что &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; временных промежутков будут рассмотрены. Таким образом, задача может быть решена за &amp;lt;tex&amp;gt;O(n^3)&amp;lt;/tex&amp;gt;. Так как функция &amp;lt;tex&amp;gt;f_i&amp;lt;/tex&amp;gt; монотонно неубывающая, то работы в расписании будем располагать как можно раньше. &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; временных интервалов &amp;lt;tex&amp;gt;t_i&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; r_1 &amp;lt;= r_2 &amp;lt;=... &amp;lt;= r_n&amp;lt;/tex&amp;gt; &lt;br /&gt;
==Псевдокод простой задачи==&lt;br /&gt;
   &amp;lt;tex&amp;gt;t_1 \leftarrow r_1 &amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''FOR'''  &amp;lt;tex&amp;gt; i \leftarrow 2&amp;lt;/tex&amp;gt; '''TO''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; '''DO'''&lt;br /&gt;
      &amp;lt;tex&amp;gt; t_i \leftarrow &amp;lt;/tex&amp;gt; '''MAX'''&amp;lt;tex&amp;gt;(r_i, \ t_{i-1} - 1)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Описание алгоритма основной задачи==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; {{---}} текущий момент времени.&amp;lt;br/&amp;gt;&lt;br /&gt;
Для каждого очередного значения &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt;, которое изменяется от &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; до времени окончания последней работы, будем:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Выбирать работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из множества невыполненных работ, у которой &amp;lt;tex&amp;gt;r_{i} \le time&amp;lt;/tex&amp;gt;, а значение &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt; максимально.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Если мы смогли найти работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, то выполняем её в момент времени &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; и удаляем из множества невыполненных работ.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Увеличиваем &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; на один.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Доказательство корректности алгоритма основной задачи==&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Расписание, построенное данным алгоритмом, является корректным и оптимальным.&lt;br /&gt;
|proof=&lt;br /&gt;
Доказательство будем вести от противного.&amp;lt;br/&amp;gt;&lt;br /&gt;
Рассмотрим расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, полученное после выполнения нашего алгоритма, и оптимальное расписание &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Возьмём первый момент времени &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;, когда расписания  различаются. Пусть в этот момент времени  в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, будет выполняться работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt;, а в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; {{---}} работа с весом &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Это первый момент, в котором расписания отличаются, значит в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; выполнится в момент времени &amp;lt;tex&amp;gt;t_{2} &amp;gt; t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Поменяем местами работы с весами &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и полуим расписание &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Это возможно, потому что время появления этих работ не меньше &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При такой перестановке ответы на задачу для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt; будут отличаться на &lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;tex&amp;gt;t_{1}w_{2} + t_{2}w_{1} - t_{1}w_{1} + t_{2}w_{2} = t_{1}(w_{2} - w_{1}) + t_{2}(w_{1} - w_{2}) = (t_{1} - t_{2})(w_{2} - w_{1})&amp;lt;/tex&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Первая скобка отрицательная: &amp;lt;tex&amp;gt;t_{1} &amp;lt; t_{2}&amp;lt;/tex&amp;gt;. Вторая скобка тоже отрицательная из того, что в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_1&amp;lt;/tex&amp;gt; выполняется раньше, значит её вес должен быть больше &amp;lt;tex&amp;gt;w_2&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Итого имеем, что ответ для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; больше, чем ответ для &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Следовательно расписание &amp;lt;tex&amp;gt;S_2&amp;lt;/tex&amp;gt; неоптимальное. Получили противоречие. Значит не существует такого момента времени, когда расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; отличается от оптимального. Следовательно мы доказали, что оно оптимальное.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Псевдокод основной задачи==&lt;br /&gt;
   &amp;lt;tex&amp;gt; S \leftarrow \{1 \dots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; time \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; answer \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''WHILE''' &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow null &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''IF''' &amp;lt;tex&amp;gt; i \in S&amp;lt;/tex&amp;gt; '''AND''' &amp;lt;tex&amp;gt; r_{i} \leq time&amp;lt;/tex&amp;gt; '''AND''' &amp;lt;tex&amp;gt;\max w_{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; j \leftarrow i &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''IF''' &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; Answer \leftarrow Answer + time \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; time++&amp;lt;/tex&amp;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;n + \max r_{i}&amp;lt;/tex&amp;gt; шагов цикла. Определить максимум в множестве можно за время &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, используя , например, очередь с приоритетами. Значит общее время работы алгоритма &amp;lt;tex&amp;gt;O((n + \max r_{i})\log n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 19 - 20&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 84 - 85&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47016</id>
		<title>1ripi1sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47016"/>
				<updated>2015-05-29T12:28:53Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt; и вес &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum w_{i} C_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; {{---}} время окончания работы.&lt;br /&gt;
}}&lt;br /&gt;
Это задание может быть сведено к более простому - Задаче о назначениях. По этой причине можно решить задачу за &amp;lt;tex&amp;gt;O(n^3)&amp;lt;/tex&amp;gt;. Теперь рассмотрим как решить её эффективнее.&lt;br /&gt;
&lt;br /&gt;
==Описание алгоритма==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; {{---}} текущий момент времени.&amp;lt;br/&amp;gt;&lt;br /&gt;
Для каждого очередного значения &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt;, которое изменяется от &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; до времени окончания последней работы, будем:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Выбирать работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из множества невыполненных работ, у которой &amp;lt;tex&amp;gt;r_{i} \le time&amp;lt;/tex&amp;gt;, а значение &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt; максимально.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Если мы смогли найти работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, то выполняем её в момент времени &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; и удаляем из множества невыполненных работ.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Увеличиваем &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; на один.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Доказательство корректности алгоритма==&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Расписание, построенное данным алгоритмом, является корректным и оптимальным.&lt;br /&gt;
|proof=&lt;br /&gt;
Доказательство будем вести от противного.&amp;lt;br/&amp;gt;&lt;br /&gt;
Рассмотрим расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, полученное после выполнения нашего алгоритма, и оптимальное расписание &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Возьмём первый момент времени &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;, когда расписания  различаются. Пусть в этот момент времени  в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, будет выполняться работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt;, а в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; {{---}} работа с весом &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Это первый момент, в котором расписания отличаются, значит в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; выполнится в момент времени &amp;lt;tex&amp;gt;t_{2} &amp;gt; t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Поменяем местами работы с весами &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и полуим расписание &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Это возможно, потому что время появления этих работ не меньше &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При такой перестановке ответы на задачу для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt; будут отличаться на &lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;tex&amp;gt;t_{1}w_{2} + t_{2}w_{1} - t_{1}w_{1} + t_{2}w_{2} = t_{1}(w_{2} - w_{1}) + t_{2}(w_{1} - w_{2}) = (t_{1} - t_{2})(w_{2} - w_{1})&amp;lt;/tex&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Первая скобка отрицательная: &amp;lt;tex&amp;gt;t_{1} &amp;lt; t_{2}&amp;lt;/tex&amp;gt;. Вторая скобка тоже отрицательная из того, что в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_1&amp;lt;/tex&amp;gt; выполняется раньше, значит её вес должен быть больше &amp;lt;tex&amp;gt;w_2&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Итого имеем, что ответ для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; больше, чем ответ для &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Следовательно расписание &amp;lt;tex&amp;gt;S_2&amp;lt;/tex&amp;gt; неоптимальное. Получили противоречие. Значит не существует такого момента времени, когда расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; отличается от оптимального. Следовательно мы доказали, что оно оптимальное.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Псевдокод==&lt;br /&gt;
   &amp;lt;tex&amp;gt; S \leftarrow \{1 \dots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; time \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; answer \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''WHILE''' &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow null &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''IF''' &amp;lt;tex&amp;gt; i \in S&amp;lt;/tex&amp;gt; '''AND''' &amp;lt;tex&amp;gt; r_{i} \leq time&amp;lt;/tex&amp;gt; '''AND''' &amp;lt;tex&amp;gt;\max w_{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; j \leftarrow i &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''IF''' &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; Answer \leftarrow Answer + time \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; time++&amp;lt;/tex&amp;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;n + \max r_{i}&amp;lt;/tex&amp;gt; шагов цикла. Определить максимум в множестве можно за время &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, используя , например, очередь с приоритетами. Значит общее время работы алгоритма &amp;lt;tex&amp;gt;O((n + \max r_{i})\log n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 84 - 85&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47012</id>
		<title>1ripi1sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47012"/>
				<updated>2015-05-29T12:14:13Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt; и вес &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum w_{i} C_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; {{---}} время окончания работы.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Описание алгоритма==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; {{---}} текущий момент времени.&amp;lt;br/&amp;gt;&lt;br /&gt;
Для каждого очередного значения &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt;, которое изменяется от &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; до времени окончания последней работы, будем:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Выбирать работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из множества невыполненных работ, у которой &amp;lt;tex&amp;gt;r_{i} \le time&amp;lt;/tex&amp;gt;, а значение &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt; максимально.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Если мы смогли найти работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, то выполняем её в момент времени &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; и удаляем из множества невыполненных работ.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Увеличиваем &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; на один.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Доказательство корректности алгоритма==&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Расписание, построенное данным алгоритмом, является корректным и оптимальным.&lt;br /&gt;
|proof=&lt;br /&gt;
Доказательство будем вести от противного.&amp;lt;br/&amp;gt;&lt;br /&gt;
Рассмотрим расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, полученное после выполнения нашего алгоритма, и оптимальное расписание &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Возьмём первый момент времени &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;, когда расписания  различаются. Пусть в этот момент времени  в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, будет выполняться работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt;, а в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; {{---}} работа с весом &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Это первый момент, в котором расписания отличаются, значит в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; выполнится в момент времени &amp;lt;tex&amp;gt;t_{2} &amp;gt; t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Поменяем местами работы с весами &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и полуим расписание &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Это возможно, потому что время появления этих работ не меньше &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При такой перестановке ответы на задачу для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt; будут отличаться на &lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;tex&amp;gt;t_{1}w_{2} + t_{2}w_{1} - t_{1}w_{1} + t_{2}w_{2} = t_{1}(w_{2} - w_{1}) + t_{2}(w_{1} - w_{2}) = (t_{1} - t_{2})(w_{2} - w_{1})&amp;lt;/tex&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Первая скобка отрицательная: &amp;lt;tex&amp;gt;t_{1} &amp;lt; t_{2}&amp;lt;/tex&amp;gt;. Вторая скобка тоже отрицательная из того, что в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_1&amp;lt;/tex&amp;gt; выполняется раньше, значит её вес должен быть больше &amp;lt;tex&amp;gt;w_2&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Итого имеем, что ответ для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; больше, чем ответ для &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Следовательно расписание &amp;lt;tex&amp;gt;S_2&amp;lt;/tex&amp;gt; неоптимальное. Получили противоречие. Значит не существует такого момента времени, когда расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; отличается от оптимального. Следовательно мы доказали, что оно оптимальное.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Псевдокод==&lt;br /&gt;
   &amp;lt;tex&amp;gt; S \leftarrow \{1 \dots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; time \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; answer \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''WHILE''' &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow null &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''IF''' &amp;lt;tex&amp;gt; i \in S&amp;lt;/tex&amp;gt; '''AND''' &amp;lt;tex&amp;gt; r_{i} \leq time&amp;lt;/tex&amp;gt; '''AND''' &amp;lt;tex&amp;gt;\max w_{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; j \leftarrow i &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''IF''' &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; Answer \leftarrow Answer + time \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; time++&amp;lt;/tex&amp;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;n + \max r_{i}&amp;lt;/tex&amp;gt; шагов цикла. Определить максимум в множестве можно за время &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, используя , например, очередь с приоритетами. Значит общее время работы алгоритма &amp;lt;tex&amp;gt;O((n + \max r_{i})\log n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 84 - 85&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47011</id>
		<title>1ripi1sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47011"/>
				<updated>2015-05-29T12:13:12Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt; и вес &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum w_{i} C_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; {{---}} время окончания работы.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Описание алгоритма==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; {{---}} текущий момент времени.&amp;lt;br/&amp;gt;&lt;br /&gt;
Для каждого очередного значения &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt;, которое изменяется от &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; до времени окончания последней работы, будем:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Выбирать работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из множества невыполненных работ, у которой &amp;lt;tex&amp;gt;r_{i} \le time&amp;lt;/tex&amp;gt;, а значение &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt; максимально.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Если мы смогли найти работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, то выполняем её в момент времени &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; и удаляем из множества невыполненных работ.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Увеличиваем &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; на один.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Доказательство корректности алгоритма==&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Расписание, построенное данным алгоритмом, является корректным и оптимальным.&lt;br /&gt;
|proof=&lt;br /&gt;
Доказательство будем вести от противного.&amp;lt;br/&amp;gt;&lt;br /&gt;
Рассмотрим расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, полученное после выполнения нашего алгоритма, и оптимальное расписание &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Возьмём первый момент времени &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;, когда расписания  различаются. Пусть в этот момент времени  в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, будет выполняться работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt;, а в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; {{---}} работа с весом &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Это первый момент, в котором расписания отличаются, значит в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; выполнится в момент времени &amp;lt;tex&amp;gt;t_{2} &amp;gt; t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Поменяем местами работы с весами &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и полуим расписание &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Это возможно, потому что время появления этих работ не меньше &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При такой перестановке ответы на задачу для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt; будут отличаться на &lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;tex&amp;gt;t_{1}w_{2} + t_{2}w_{1} - t_{1}w_{1} + t_{2}w_{2} = t_{1}(w_{2} - w_{1}) + t_{2}(w_{1} - w_{2}) = (t_{1} - t_{2})(w_{2} - w_{1})&amp;lt;/tex&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Первая скобка отрицательная: &amp;lt;tex&amp;gt;t_{1} &amp;lt; t_{2}&amp;lt;/tex&amp;gt;. Вторая скобка тоже отрицательная из того, что в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_1&amp;lt;/tex&amp;gt; выполняется раньше, значит её вес должен быть больше &amp;lt;tex&amp;gt;w_2&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Итого имеем, что ответ для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; больше, чем ответ для &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Следовательно расписание &amp;lt;tex&amp;gt;S_2&amp;lt;/tex&amp;gt; неоптимальное. Получили противоречие. Значит не существует такого момента времени, когда расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; отличается от оптимального. Следовательно мы доказали, что оно оптимальное.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Псевдокод==&lt;br /&gt;
   &amp;lt;tex&amp;gt; S \leftarrow \{1 \dots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; time \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; answer \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''WHILE''' &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow null &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt; i \in S&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt; r_{i} \leq time&amp;lt;/tex&amp;gt; '''and''' &amp;lt;tex&amp;gt;\max w_{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; j \leftarrow i &amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; Answer \leftarrow Answer + time \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; time++&amp;lt;/tex&amp;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;n + \max r_{i}&amp;lt;/tex&amp;gt; шагов цикла. Определить максимум в множестве можно за время &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, используя , например, очередь с приоритетами. Значит общее время работы алгоритма &amp;lt;tex&amp;gt;O((n + \max r_{i})\log n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 84 - 85&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47010</id>
		<title>1ripi1sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47010"/>
				<updated>2015-05-29T11:47:38Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt; и вес &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum w_{i} C_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; {{---}} время окончания работы.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Описание алгоритма==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; {{---}} текущий момент времени.&amp;lt;br/&amp;gt;&lt;br /&gt;
Для каждого очередного значения &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt;, которое изменяется от &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; до времени окончания последней работы, будем:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Выбирать работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из множества невыполненных работ, у которой &amp;lt;tex&amp;gt;r_{i} \le time&amp;lt;/tex&amp;gt;, а значение &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt; максимально.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Если мы смогли найти работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, то выполняем её в момент времени &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; и удаляем из множества невыполненных работ.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Увеличиваем &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; на один.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Доказательство корректности алгоритма==&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Расписание, построенное данным алгоритмом, является корректным и оптимальным.&lt;br /&gt;
|proof=&lt;br /&gt;
Доказательство будем вести от противного.&amp;lt;br/&amp;gt;&lt;br /&gt;
Рассмотрим расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, полученное после выполнения нашего алгоритма, и оптимальное расписание &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Возьмём первый момент времени &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;, когда расписания  различаются. Пусть в этот момент времени  в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, будет выполняться работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt;, а в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; {{---}} работа с весом &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Это первый момент, в котором расписания отличаются, значит в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; выполнится в момент времени &amp;lt;tex&amp;gt;t_{2} &amp;gt; t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Поменяем местами работы с весами &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и полуим расписание &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Это возможно, потому что время появления этих работ не меньше &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При такой перестановке ответы на задачу для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt; будут отличаться на &lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;tex&amp;gt;t_{1}w_{2} + t_{2}w_{1} - t_{1}w_{1} + t_{2}w_{2} = t_{1}(w_{2} - w_{1}) + t_{2}(w_{1} - w_{2}) = (t_{1} - t_{2})(w_{2} - w_{1})&amp;lt;/tex&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Первая скобка отрицательная: &amp;lt;tex&amp;gt;t_{1} &amp;lt; t_{2}&amp;lt;/tex&amp;gt;. Вторая скобка тоже отрицательная из того, что в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_1&amp;lt;/tex&amp;gt; выполняется раньше, значит её вес должен быть больше &amp;lt;tex&amp;gt;w_2&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Итого имеем, что ответ для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; больше, чем ответ для &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Следовательно расписание &amp;lt;tex&amp;gt;S_2&amp;lt;/tex&amp;gt; неоптимальное. Получили противоречие. Значит не существует такого момента времени, когда расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; отличается от оптимального. Следовательно мы доказали, что оно оптимальное.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Псевдокод==&lt;br /&gt;
   &amp;lt;tex&amp;gt; S \leftarrow \{1 \dots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; time \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; answer \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   while &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow i : (\max \limits_{i \in S, r_{i} \leq time} w_{i})&amp;lt;/tex&amp;gt;&lt;br /&gt;
      if &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; Answer \leftarrow Answer + time \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; time++&amp;lt;/tex&amp;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;n + \max r_{i}&amp;lt;/tex&amp;gt; шагов цикла. Определить максимум в множестве можно за время &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, используя , например, очередь с приоритетами. Значит общее время работы алгоритма &amp;lt;tex&amp;gt;O((n + \max r_{i})\log n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 84 - 85&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47009</id>
		<title>1ripi1sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47009"/>
				<updated>2015-05-29T11:34:26Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; 1 \mid r_i,p_i = 1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt; и вес &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum w_{i} C_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; {{---}} время окончания работы.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Описание алгоритма==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; {{---}} текущий момент времени.&amp;lt;br/&amp;gt;&lt;br /&gt;
Для каждого очередного значения &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt;, которое изменяется от &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; до времени окончания последней работы, будем:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Выбирать работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из множества невыполненных работ, у которой &amp;lt;tex&amp;gt;r_{i} \le time&amp;lt;/tex&amp;gt;, а значение &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt; максимально.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Если мы смогли найти работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, то выполняем её в момент времени &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; и удаляем из множества невыполненных работ.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Увеличиваем &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; на один.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Доказательство корректности алгоритма==&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Расписание, построенное данным алгоритмом, является корректным и оптимальным.&lt;br /&gt;
|proof=&lt;br /&gt;
Доказательство будем вести от противного.&amp;lt;br/&amp;gt;&lt;br /&gt;
Рассмотрим расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, полученное после выполнения нашего алгоритма, и оптимальное расписание &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Возьмём первый момент времени &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;, когда расписания  различаются. Пусть в этот момент времени  в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, будет выполняться работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt;, а в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; {{---}} работа с весом &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Это первый момент, в котором расписания отличаются, значит в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; выполнится в момент времени &amp;lt;tex&amp;gt;t_{2} &amp;gt; t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Поменяем местами работы с весами &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и полуим расписание &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Это возможно, потому что время появления этих работ не меньше &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При такой перестановке ответы на задачу для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt; будут отличаться на &lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;tex&amp;gt;t_{1}w_{2} + t_{2}w_{1} - t_{1}w_{1} + t_{2}w_{2} = t_{1}(w_{2} - w_{1}) + t_{2}(w_{1} - w_{2}) = (t_{1} - t_{2})(w_{2} - w_{1})&amp;lt;/tex&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Первая скобка отрицательная: &amp;lt;tex&amp;gt;t_{1} &amp;lt; t_{2}&amp;lt;/tex&amp;gt;. Вторая скобка тоже отрицательная из того, что в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_1&amp;lt;/tex&amp;gt; выполняется раньше, значит её вес должен быть больше &amp;lt;tex&amp;gt;w_2&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Итого имеем, что ответ для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; больше, чем ответ для &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Следовательно расписание &amp;lt;tex&amp;gt;S_2&amp;lt;/tex&amp;gt; неоптимальное. Получили противоречие. Значит не существует такого момента времени, когда расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; отличается от оптимального. Следовательно мы доказали, что оно оптимальное.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Псевдокод==&lt;br /&gt;
   &amp;lt;tex&amp;gt; S \leftarrow \{1 \dots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; time \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; answer \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   while &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow i : (\max \limits_{i \in S, r_{i} \leq time} w_{i})&amp;lt;/tex&amp;gt;&lt;br /&gt;
      if &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; Answer \leftarrow Answer + time \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; time++&amp;lt;/tex&amp;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;n + \max r_{i}&amp;lt;/tex&amp;gt; шагов цикла. Определить максимум в множестве можно за время &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, используя , например, очередь с приоритетами. Значит общее время работы алгоритма &amp;lt;tex&amp;gt;O((n + \max r_{i})\log n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47008</id>
		<title>1ripi1sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47008"/>
				<updated>2015-05-29T11:33:50Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;\mid r_i,p_i = 1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt; и вес &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum w_{i} C_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; {{---}} время окончания работы.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Описание алгоритма==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; {{---}} текущий момент времени.&amp;lt;br/&amp;gt;&lt;br /&gt;
Для каждого очередного значения &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt;, которое изменяется от &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; до времени окончания последней работы, будем:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Выбирать работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из множества невыполненных работ, у которой &amp;lt;tex&amp;gt;r_{i} \le time&amp;lt;/tex&amp;gt;, а значение &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt; максимально.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Если мы смогли найти работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, то выполняем её в момент времени &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; и удаляем из множества невыполненных работ.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Увеличиваем &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; на один.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Доказательство корректности алгоритма==&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Расписание, построенное данным алгоритмом, является корректным и оптимальным.&lt;br /&gt;
|proof=&lt;br /&gt;
Доказательство будем вести от противного.&amp;lt;br/&amp;gt;&lt;br /&gt;
Рассмотрим расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, полученное после выполнения нашего алгоритма, и оптимальное расписание &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Возьмём первый момент времени &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;, когда расписания  различаются. Пусть в этот момент времени  в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, будет выполняться работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt;, а в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; {{---}} работа с весом &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Это первый момент, в котором расписания отличаются, значит в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; выполнится в момент времени &amp;lt;tex&amp;gt;t_{2} &amp;gt; t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Поменяем местами работы с весами &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и полуим расписание &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Это возможно, потому что время появления этих работ не меньше &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При такой перестановке ответы на задачу для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt; будут отличаться на &lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;tex&amp;gt;t_{1}w_{2} + t_{2}w_{1} - t_{1}w_{1} + t_{2}w_{2} = t_{1}(w_{2} - w_{1}) + t_{2}(w_{1} - w_{2}) = (t_{1} - t_{2})(w_{2} - w_{1})&amp;lt;/tex&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Первая скобка отрицательная: &amp;lt;tex&amp;gt;t_{1} &amp;lt; t_{2}&amp;lt;/tex&amp;gt;. Вторая скобка тоже отрицательная из того, что в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_1&amp;lt;/tex&amp;gt; выполняется раньше, значит её вес должен быть больше &amp;lt;tex&amp;gt;w_2&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Итого имеем, что ответ для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; больше, чем ответ для &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Следовательно расписание &amp;lt;tex&amp;gt;S_2&amp;lt;/tex&amp;gt; неоптимальное. Получили противоречие. Значит не существует такого момента времени, когда расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; отличается от оптимального. Следовательно мы доказали, что оно оптимальное.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Псевдокод==&lt;br /&gt;
   &amp;lt;tex&amp;gt; S \leftarrow \{1 \dots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; time \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; answer \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   while &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow i : (\max \limits_{i \in S, r_{i} \leq time} w_{i})&amp;lt;/tex&amp;gt;&lt;br /&gt;
      if &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; Answer \leftarrow Answer + time \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; time++&amp;lt;/tex&amp;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;n + \max r_{i}&amp;lt;/tex&amp;gt; шагов цикла. Определить максимум в множестве можно за время &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, используя , например, очередь с приоритетами. Значит общее время работы алгоритма &amp;lt;tex&amp;gt;O((n + \max r_{i})\log n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47007</id>
		<title>1ripi1sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47007"/>
				<updated>2015-05-29T11:33:28Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;\mid r_i,p_i = 1 \mid \sum w_i C_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt; и вес &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum w_{i} C_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; {{---}} время окончания работы.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Описание алгоритма==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; {{---}} текущий момент времени.&amp;lt;br/&amp;gt;&lt;br /&gt;
Для каждого очередного значения &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt;, которое изменяется от &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; до времени окончания последней работы, будем:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Выбирать работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из множества невыполненных работ, у которой &amp;lt;tex&amp;gt;r_{i} \le time&amp;lt;/tex&amp;gt;, а значение &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt; максимально.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Если мы смогли найти работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, то выполняем её в момент времени &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; и удаляем из множества невыполненных работ.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Увеличиваем &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; на один.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Доказательство корректности алгоритма==&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Расписание, построенное данным алгоритмом, является корректным и оптимальным.&lt;br /&gt;
|proof=&lt;br /&gt;
Доказательство будем вести от противного.&amp;lt;br/&amp;gt;&lt;br /&gt;
Рассмотрим расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, полученное после выполнения нашего алгоритма, и оптимальное расписание &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Возьмём первый момент времени &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;, когда расписания  различаются. Пусть в этот момент времени  в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, будет выполняться работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt;, а в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; {{---}} работа с весом &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Это первый момент, в котором расписания отличаются, значит в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; выполнится в момент времени &amp;lt;tex&amp;gt;t_{2} &amp;gt; t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Поменяем местами работы с весами &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и полуим расписание &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Это возможно, потому что время появления этих работ не меньше &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При такой перестановке ответы на задачу для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt; будут отличаться на &lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;tex&amp;gt;t_{1}w_{2} + t_{2}w_{1} - t_{1}w_{1} + t_{2}w_{2} = t_{1}(w_{2} - w_{1}) + t_{2}(w_{1} - w_{2}) = (t_{1} - t_{2})(w_{2} - w_{1})&amp;lt;/tex&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Первая скобка отрицательная: &amp;lt;tex&amp;gt;t_{1} &amp;lt; t_{2}&amp;lt;/tex&amp;gt;. Вторая скобка тоже отрицательная из того, что в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_1&amp;lt;/tex&amp;gt; выполняется раньше, значит её вес должен быть больше &amp;lt;tex&amp;gt;w_2&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Итого имеем, что ответ для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; больше, чем ответ для &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Следовательно расписание &amp;lt;tex&amp;gt;S_2&amp;lt;/tex&amp;gt; неоптимальное. Получили противоречие. Значит не существует такого момента времени, когда расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; отличается от оптимального. Следовательно мы доказали, что оно оптимальное.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Псевдокод==&lt;br /&gt;
   &amp;lt;tex&amp;gt; S \leftarrow \{1 \dots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; time \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; answer \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   while &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow i : (\max \limits_{i \in S, r_{i} \leq time} w_{i})&amp;lt;/tex&amp;gt;&lt;br /&gt;
      if &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; Answer \leftarrow Answer + time \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; time++&amp;lt;/tex&amp;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;n + \max r_{i}&amp;lt;/tex&amp;gt; шагов цикла. Определить максимум в множестве можно за время &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, используя , например, очередь с приоритетами. Значит общее время работы алгоритма &amp;lt;tex&amp;gt;O((n + \max r_{i})\log n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47004</id>
		<title>1ripi1sumwc</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=1ripi1sumwc&amp;diff=47004"/>
				<updated>2015-05-29T11:21:47Z</updated>
		
		<summary type="html">&lt;p&gt;Sergej Arkhipov: /* Постановка задачи */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ и один станок. Для каждой работы известно её время появления &amp;lt;tex&amp;gt;r_{i}&amp;lt;/tex&amp;gt; и вес &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt;. Время выполнения всех работ &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; равно &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.Требуется выполнить все работы, чтобы значение &amp;lt;tex&amp;gt;\sum w_{i} C_{i}&amp;lt;/tex&amp;gt; было минимальным, где &amp;lt;tex&amp;gt;C_{i}&amp;lt;/tex&amp;gt; {{---}} время окончания работы.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Описание алгоритма==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; {{---}} текущий момент времени.&amp;lt;br/&amp;gt;&lt;br /&gt;
Для каждого очередного значения &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt;, которое изменяется от &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; до времени окончания последней работы, будем:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Выбирать работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из множества невыполненных работ, у которой &amp;lt;tex&amp;gt;r_{i} \le time&amp;lt;/tex&amp;gt;, а значение &amp;lt;tex&amp;gt;w_{i}&amp;lt;/tex&amp;gt; максимально.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Если мы смогли найти работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, то выполняем её в момент времени &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; и удаляем из множества невыполненных работ.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Увеличиваем &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; на один.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Доказательство корректности алгоритма==&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Расписание, построенное данным алгоритмом, является корректным и оптимальным.&lt;br /&gt;
|proof=&lt;br /&gt;
Доказательство будем вести от противного.&amp;lt;br/&amp;gt;&lt;br /&gt;
Рассмотрим расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, полученное после выполнения нашего алгоритма, и оптимальное расписание &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Возьмём первый момент времени &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;, когда расписания  различаются. Пусть в этот момент времени  в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt;, будет выполняться работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt;, а в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; {{---}} работа с весом &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Это первый момент, в котором расписания отличаются, значит в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; выполнится в момент времени &amp;lt;tex&amp;gt;t_{2} &amp;gt; t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Поменяем местами работы с весами &amp;lt;tex&amp;gt;w_{1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w_{2}&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и полуим расписание &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Это возможно, потому что время появления этих работ не меньше &amp;lt;tex&amp;gt;t_{1}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
При такой перестановке ответы на задачу для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt; будут отличаться на &lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;tex&amp;gt;t_{1}w_{2} + t_{2}w_{1} - t_{1}w_{1} + t_{2}w_{2} = t_{1}(w_{2} - w_{1}) + t_{2}(w_{1} - w_{2}) = (t_{1} - t_{2})(w_{2} - w_{1})&amp;lt;/tex&amp;gt;&amp;lt;/ul&amp;gt;&lt;br /&gt;
Первая скобка отрицательная: &amp;lt;tex&amp;gt;t_{1} &amp;lt; t_{2}&amp;lt;/tex&amp;gt;. Вторая скобка тоже отрицательная из того, что в &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; работа с весом &amp;lt;tex&amp;gt;w_1&amp;lt;/tex&amp;gt; выполняется раньше, значит её вес должен быть больше &amp;lt;tex&amp;gt;w_2&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
Итого имеем, что ответ для &amp;lt;tex&amp;gt;S_{2}&amp;lt;/tex&amp;gt; больше, чем ответ для &amp;lt;tex&amp;gt;S_{3}&amp;lt;/tex&amp;gt;. Следовательно расписание &amp;lt;tex&amp;gt;S_2&amp;lt;/tex&amp;gt; неоптимальное. Получили противоречие. Значит не существует такого момента времени, когда расписание &amp;lt;tex&amp;gt;S_{1}&amp;lt;/tex&amp;gt; отличается от оптимального. Следовательно мы доказали, что оно оптимальное.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Псевдокод==&lt;br /&gt;
   &amp;lt;tex&amp;gt; S \leftarrow \{1 \dots n\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; time \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   &amp;lt;tex&amp;gt; answer \leftarrow 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   while &amp;lt;tex&amp;gt; S \neq \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; j \leftarrow i : (\max \limits_{i \in S, r_{i} \leq time} w_{i})&amp;lt;/tex&amp;gt;&lt;br /&gt;
      if &amp;lt;tex&amp;gt;j \neq null &amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; S \leftarrow S \setminus j&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt; Answer \leftarrow Answer + time \cdot w_{j}&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt; time++&amp;lt;/tex&amp;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;n + \max r_{i}&amp;lt;/tex&amp;gt; шагов цикла. Определить максимум в множестве можно за время &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;, используя , например, очередь с приоритетами. Значит общее время работы алгоритма &amp;lt;tex&amp;gt;O((n + \max r_{i})\log n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Sergej Arkhipov</name></author>	</entry>

	</feed>