Методы решения задач теории расписаний — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
(Выделены задачи в конспекты, добавлены ссылки, разделы в конце конспекта)
(Фиксы)
Строка 1: Строка 1:
 
== Сведение к другой задаче ==
 
== Сведение к другой задаче ==
При сведении текущей задачи теории расписаний <tex> S </tex> к какой-то другой <tex> S' </tex>(не обязательно задаче теории расписаний) необходимо доказать два пункта:
+
При сведении текущей задачи теории расписаний <tex> S </tex> к какой-то другой <tex> S' </tex> (не обязательно задаче теории расписаний) необходимо доказать два пункта:
 
# Допустимость расписания, построенного с помощью задачи <tex> S' </tex>, или существование способа его трансформации в допустимое без нарушения оптимальности.
 
# Допустимость расписания, построенного с помощью задачи <tex> S' </tex>, или существование способа его трансформации в допустимое без нарушения оптимальности.
 
# Следствие того, что если мы оптимизируем <tex> S' </tex>, мы также оптимизируем ответ для <tex> S </tex>.
 
# Следствие того, что если мы оптимизируем <tex> S' </tex>, мы также оптимизируем ответ для <tex> S </tex>.
Примечание — если требуется полиномиальное время для решения задачи, требуется, чтобы сведение к другой задаче и трансформация расписания в допустимое также происходили за полиномиальное время.
+
'''Примечание''': если требуется полиномиальное время для решения задачи, сведение к другой задаче и трансформация расписания в допустимое также должны происходить за полиномиальное время.
  
 
С помощью этого метода решаются:
 
С помощью этого метода решаются:
 
* Некоторые задачи класса Open Shop при условии <tex>p_{ij}=1</tex> сводятся к задачам равной длительности на параллельных станках.
 
* Некоторые задачи класса Open Shop при условии <tex>p_{ij}=1</tex> сводятся к задачам равной длительности на параллельных станках.
** <tex> O \mid p_{ij} = 1 \mid \sum w_i C_i </tex> ([[Opij1Sumwc|ссылка]])
+
*:[[Opij1Sumwc|<tex> O \mid p_{ij} = 1 \mid \sum w_i C_i </tex>]]
** <tex> O \mid p_{ij} = 1, r_i \mid C_{max} </tex> <ref>Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 161</ref>
+
*:<tex> O \mid p_{ij} = 1, r_i \mid C_{max} </tex> <ref>Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 161</ref>
 
* Некоторые задачи класса Flow Shop при условии <tex>p_{ij}=1</tex> сводятся к задаче на одном станке.  
 
* Некоторые задачи класса Flow Shop при условии <tex>p_{ij}=1</tex> сводятся к задаче на одном станке.  
** <tex> F \mid p_{ij} = 1 \mid \sum w_i U_i </tex> ([[Fpij1sumwu|ссылка]])
+
*:[[Fpij1sumwu|<tex> F \mid p_{ij} = 1 \mid \sum w_i U_i </tex>]]
 
* Часто в задачах, в которых допускаются прерывания, оптимальный ответ совпадает с соответствующими задачами без прерываний:
 
* Часто в задачах, в которых допускаются прерывания, оптимальный ответ совпадает с соответствующими задачами без прерываний:
** <tex> P \mid pmtn \mid \sum w_i C_i </tex> <ref>Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 121</ref>
+
*:<tex> P \mid pmtn \mid \sum w_i C_i </tex> <ref>Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 121</ref>
** <tex> F2 \mid pmtn \mid C_{max} </tex> ([[Flow_shop|ссылка]])
+
*:[[Flow shop|<tex> F2 \mid pmtn \mid C_{max} </tex>]]
 
* Некоторые задачи проверки существования расписания сводятся к задаче поиска максимального потока:
 
* Некоторые задачи проверки существования расписания сводятся к задаче поиска максимального потока:
** <tex> Q \mid pmtn, r_i\mid L_{max} </tex> <ref>Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 129-133</ref>
+
*:<tex> Q \mid pmtn, r_i\mid L_{max} </tex> <ref>Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 129-133</ref>
** <tex> R \mid \mid \sum C_i </tex> ([[RSumCi|ссылка]])
+
*:[[RSumCi|<tex> R \mid \mid \sum C_i </tex>]]
* <tex> 1 \mid intree \mid \sum w_i C_i </tex> ([[1outtreesumwc|ссылка]])
+
* Некоторые задачи сводятся к другим похожим задачам теории расписаний путем преобразования их расписаний:
 +
*:[[1outtreesumwc|<tex> 1 \mid intree \mid \sum w_i C_i </tex>]]
  
 
== Построение расписания по нижней оценке ==
 
== Построение расписания по нижней оценке ==
Этот метод обычно применим к задачам, в которых целевая функция — <tex> C_{max}</tex>. Построим какой-то набор нижних ограничений на произвольное расписание для задачи <tex> S </tex> и возьмем из них максимальное. Затем построим произвольное допустимое расписание, достигающее этой оценки.
+
Этот метод обычно применим к задачам, в которых целевая функция — <tex> C_{max}</tex>.  
 +
Обычно построение расписания по нижней оценке происходит в два этапа:
 +
# Построение некоторого набора нижних ограничений на произвольное расписание для задачи <tex> S </tex>.  
 +
# Построение произвольного допустимого расписания, достигающего максимального ограничения из построенного набора.
  
С помощью этого метода решаются:
+
С помощью этого метода решаются следующие задачи:
 
* <tex> P \mid pmtn \mid C_{max}</tex> <ref>Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 108</ref>
 
* <tex> P \mid pmtn \mid C_{max}</tex> <ref>Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 108</ref>
 
* <tex> R \mid pmtn \mid C_{max}</tex> <ref>Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 137-139</ref>
 
* <tex> R \mid pmtn \mid C_{max}</tex> <ref>Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 137-139</ref>
* <tex> O \mid p_{ij}=1 \mid C_{max}</tex> ([[Opij1Cmax|ссылка]])
+
* [[Opij1Cmax|<tex> O \mid p_{ij}=1 \mid C_{max}</tex>]]
* <tex> Q \mid pmtn \mid C_{max}</tex> ([[QpmtnCmax|ссылка]])
+
* [[QpmtnCmax|<tex> Q \mid pmtn \mid C_{max}</tex>]]
  
 
=== P | pmtn | C_max ===
 
=== P | pmtn | C_max ===
# В допустимом расписании выполнение всех работ не может завершиться раньше одной из них, поэтому <tex> T \ge p_i </tex>.
+
Найдем набор ограничений на значение <tex> C_{max} </tex> для произвольного допустимого расписания <tex> S </tex> :
# Если все станки работали время <tex> T </tex>, на них могло выполниться не больше <tex> Tm </tex> работы, то есть <tex> \sum\limits_i p_i \le Tm </tex> и <tex> T \ge \frac1m \sum\limits_i p_i </tex>.
+
# В допустимом расписании выполнение всех работ не может завершиться раньше одной из них, поэтому <tex> C_{max} \geqslant p_i </tex>.
# Тогда <tex> T_{min} = \max {(\max\limits_i p_i, \frac1m \sum\limits_i p_i)} </tex>.
+
# Если все станки работали время <tex> C_{max} </tex>, на них могло выполниться не больше <tex> C_{max} \cdot m </tex> работы, то есть <tex> \sum\limits_i p_i \leqslant C_{max} \cdot m </tex> и <tex> C_{max} \geqslant \dfrac1m \sum\limits_i p_i </tex>.
Построим расписание, подходящее под эту границу: будем по очереди заполнять машины работами в произвольном порядке, и если очередная работа не помещается на текущей машине полностью, перенесем ее выходящую за <tex> T_{min} </tex> часть на следующую машину. Благодаря первому ограничению никакая работа не будет выполняться одновременно на двух станках, а благодаря второму — не останется работы, которую мы не сможем выполнить.
+
Из этих ограничений следует, что <tex> C_{max} = \max {\left( \max\limits_i p_i; \dfrac1m \sum\limits_i p_i \right)} </tex>.
 +
 
 +
Построим расписание, подходящее под эту границу: будем по очереди заполнять машины работами в произвольном порядке, и если очередная работа не помещается на текущей машине полностью, перенесем ее выходящую за <tex> C_{max} </tex> часть на следующую машину. Благодаря первому ограничению никакая работа не будет выполняться одновременно на двух станках, а благодаря второму — не останется работы, которую мы не сможем выполнить.
  
 
== Бинарный поиск по ответу ==
 
== Бинарный поиск по ответу ==
 
Этот способ часто подходит для задач, в которых надо минимизировать <tex>C_{max} </tex> (если мы умеем решать соответствующую задачу существования расписания), реже для <tex> \sum w_i U_i </tex>. Важно помнить, что если требуется полиномиальное по <tex> n </tex> решение, оно не должно зависеть от логарифма ответа, но иногда ответ ограничен полиномом от <tex>n</tex>, и мы можем применить этот метод.
 
Этот способ часто подходит для задач, в которых надо минимизировать <tex>C_{max} </tex> (если мы умеем решать соответствующую задачу существования расписания), реже для <tex> \sum w_i U_i </tex>. Важно помнить, что если требуется полиномиальное по <tex> n </tex> решение, оно не должно зависеть от логарифма ответа, но иногда ответ ограничен полиномом от <tex>n</tex>, и мы можем применить этот метод.
  
Этим методом решаются:
+
Примером решения задач подобным методом служит следующая задача:
* <tex> Q \mid pmtn, r_i \mid L_{max} </tex> ([[QpmtnriLmax |ссылка]])
+
[[QpmtnriLmax|<tex> Q \mid pmtn, r_i \mid L_{max} </tex>]]
  
 
== Жадное построение расписания ==
 
== Жадное построение расписания ==
 
{{Определение
 
{{Определение
|definition=
+
|definition=[[Теорема Радо-Эдмондса (жадный алгоритм)|'''Жадный алгоритм''']] — алгоритм решения задач путем выбора локально оптимальных решений на каждом этапе алгоритма.
'''Жадный алгоритм''' — алгоритм, в котором локальные оптимизации решения достигают глобального оптимума.
 
 
}}
 
}}
 
 
Естественно, далеко не все оптимизационные задачи можно решать жадно — для этого сначала необходимо доказать оптимальность жадного выбора.  
 
Естественно, далеко не все оптимизационные задачи можно решать жадно — для этого сначала необходимо доказать оптимальность жадного выбора.  
  
 
С помощью этого метода решаются:
 
С помощью этого метода решаются:
* <tex> 1 \mid prec \mid f_{max} </tex> ([[Правило Лаулера|''Lawler's algorithm]])
+
* [[Правило Лаулера|<tex> 1 \mid prec \mid f_{max} </tex>]]
* <tex> 1 \mid outtree \mid \sum w_i C_i </tex> ([[1outtreesumwc|ссылка]])
+
* [[1outtreesumwc|<tex> 1 \mid outtree \mid \sum w_i C_i </tex>]]
* <tex> 1 \mid p_i = 1 \mid \sum w_i U_i </tex> ([[1pi1sumwu|''Earliest Due Date rule'']])
+
* [[1pi1sumwu|<tex> 1 \mid p_i = 1 \mid \sum w_i U_i </tex>]]
* <tex> 1 \mid \mid \sum U_i </tex> ([[1sumu|ссылка]])
+
* [[1sumu|<tex> 1 \mid \mid \sum U_i </tex>]]
  
 
Обычно оптимальность жадного выбора доказывают двумя способами:  
 
Обычно оптимальность жадного выбора доказывают двумя способами:  
Строка 59: Строка 63:
 
Приведем пример часто распространенных '''неправильных''' действий при доказательстве оптимальности жадного алгоритма:
 
Приведем пример часто распространенных '''неправильных''' действий при доказательстве оптимальности жадного алгоритма:
  
Пусть предложенным нами алгоритмом мы получили какое-то решение <tex> S </tex>. Атомарными изменениями в этом решении <tex> S </tex> будем получать другие допустимые решения <tex> S' </tex> и докажем, что <tex> f(S) \le f(S') </tex>. Тогда решение <tex> S </tex> — оптимально.
+
Пусть предложенным нами алгоритмом мы получили какое-то решение <tex> S </tex>. Атомарными изменениями в этом решении <tex> S </tex> будем получать другие допустимые решения <tex> S' </tex> и докажем, что <tex> f(S) \leqslant f(S') </tex>. Тогда решение <tex> S </tex> — оптимально.
  
Проблема в этих рассуждениях в том, что ими мы доказываем локальную оптимальность алгоритма в решении <tex> S </tex>. Получение же глобального минимума может потребовать нескольких атомарных изменений в расписании, поэтому доказать оптимальность таким образом в общем случае невозможно. Как ближайшую аналогию, можно привести '''неправильное''' утверждение для произвольной функции <tex> f(\bar x) </tex> — «если все частные производные <tex> \frac{\partial f}{\partial x_1} \dots \frac{\partial f}{\partial x_n} </tex> неотрицательны, то в точке <tex> \bar x </tex> наблюдается глобальный минимум».
+
Проблема в этих рассуждениях в том, что ими мы доказываем локальную оптимальность алгоритма в решении <tex> S </tex>. Получение же глобального минимума может потребовать нескольких атомарных изменений в расписании, поэтому доказать оптимальность таким образом в общем случае невозможно. Как ближайшую аналогию, можно привести '''неправильное''' утверждение для произвольной функции <tex> f(\bar x) </tex> — «если все частные производные <tex> \dfrac{\partial f}{\partial x_1} \dots \dfrac{\partial f}{\partial x_n} </tex> неотрицательны, то в точке <tex> \bar x </tex> наблюдается глобальный минимум».
  
 
=== Правильно ===
 
=== Правильно ===
 
При доказательстве оптимательности применима стратегия '''аргумент замены''' (англ. ''exchange argument''). Стратегия заключается в рассмотрении текущего решения <tex> S </tex> и оптимального решения <tex> O </tex>. Далее предлагается способ модификации <tex> O </tex> в <tex> O'</tex> так, что:
 
При доказательстве оптимательности применима стратегия '''аргумент замены''' (англ. ''exchange argument''). Стратегия заключается в рассмотрении текущего решения <tex> S </tex> и оптимального решения <tex> O </tex>. Далее предлагается способ модификации <tex> O </tex> в <tex> O'</tex> так, что:
# <tex> f(O') \le f(O) </tex>, то есть <tex> O' </tex> также оптимально.
+
# <tex> f(O') \leqslant f(O) </tex>, то есть <tex> O' </tex> также оптимально.
 
# <tex> O' </tex> «более похоже» на <tex> S </tex>, чем на <tex> O </tex>.
 
# <tex> O' </tex> «более похоже» на <tex> S </tex>, чем на <tex> O </tex>.
  
Если такой способ найден, получаем, что какой-то последовательностью модификаций <tex> O \to O_t' \to \dots \to O_1' \to S </tex> получим <tex> f(S) \le f(O_1') \le \dots \le f(O_t') \le f(O) </tex>, из чего следует оптимальность <tex> S </tex>.
+
Если такой способ найден, получаем, что какой-то последовательностью модификаций <tex> O \to O_t' \to \dots \to O_1' \to S </tex> получим <tex> f(S) \leqslant f(O_1') \leqslant \dots \leqslant f(O_t') \leqslant f(O) </tex>, из чего следует оптимальность <tex> S </tex>.
  
 
Отношение «более похоже» должно быть [[Отношение порядка | отношением частичного строгого порядка]]. Часто в качестве него можно выбрать отношение «длина наибольшего общего префикса решения <tex> A </tex> и <tex> S </tex> меньше наибольшего общего префикса решения <tex> B </tex> и <tex> S </tex>». Тогда если мы сможем увеличить длину наибольшего общего префикса для оптимального решения, не нарушив оптимальности, мы приблизимся к <tex> S </tex>. Можно выбирать и более сложные отношения, например, в доказательстве оптимальности алгоритма <tex> P \mid \mid \sum w_i C_i </tex> для решения задачи <tex> P \mid pmtn \mid \sum w_i C_i </tex> используется отношение «время последнего прерывания больше или количество прерываний меньше».
 
Отношение «более похоже» должно быть [[Отношение порядка | отношением частичного строгого порядка]]. Часто в качестве него можно выбрать отношение «длина наибольшего общего префикса решения <tex> A </tex> и <tex> S </tex> меньше наибольшего общего префикса решения <tex> B </tex> и <tex> S </tex>». Тогда если мы сможем увеличить длину наибольшего общего префикса для оптимального решения, не нарушив оптимальности, мы приблизимся к <tex> S </tex>. Можно выбирать и более сложные отношения, например, в доказательстве оптимальности алгоритма <tex> P \mid \mid \sum w_i C_i </tex> для решения задачи <tex> P \mid pmtn \mid \sum w_i C_i </tex> используется отношение «время последнего прерывания больше или количество прерываний меньше».
Строка 83: Строка 87:
 
* Peter Brucker «Scheduling Algorithms», fifth edition, Springer ISBN 978-3-540-69515-8
 
* Peter Brucker «Scheduling Algorithms», fifth edition, Springer ISBN 978-3-540-69515-8
  
[[Категория: Дискретная математика и алгоритмы]]
+
[[Категория: Алгоритмы и структуры данных]]
 
[[Категория: Теория расписаний]]
 
[[Категория: Теория расписаний]]

Версия 05:38, 7 июня 2016

Сведение к другой задаче

При сведении текущей задачи теории расписаний [math] S [/math] к какой-то другой [math] S' [/math] (не обязательно задаче теории расписаний) необходимо доказать два пункта:

  1. Допустимость расписания, построенного с помощью задачи [math] S' [/math], или существование способа его трансформации в допустимое без нарушения оптимальности.
  2. Следствие того, что если мы оптимизируем [math] S' [/math], мы также оптимизируем ответ для [math] S [/math].

Примечание: если требуется полиномиальное время для решения задачи, сведение к другой задаче и трансформация расписания в допустимое также должны происходить за полиномиальное время.

С помощью этого метода решаются:

  • Некоторые задачи класса Open Shop при условии [math]p_{ij}=1[/math] сводятся к задачам равной длительности на параллельных станках.
    [math] O \mid p_{ij} = 1 \mid \sum w_i C_i [/math]
    [math] O \mid p_{ij} = 1, r_i \mid C_{max} [/math] [1]
  • Некоторые задачи класса Flow Shop при условии [math]p_{ij}=1[/math] сводятся к задаче на одном станке.
    [math] F \mid p_{ij} = 1 \mid \sum w_i U_i [/math]
  • Часто в задачах, в которых допускаются прерывания, оптимальный ответ совпадает с соответствующими задачами без прерываний:
    [math] P \mid pmtn \mid \sum w_i C_i [/math] [2]
    [math] F2 \mid pmtn \mid C_{max} [/math]
  • Некоторые задачи проверки существования расписания сводятся к задаче поиска максимального потока:
    [math] Q \mid pmtn, r_i\mid L_{max} [/math] [3]
    [math] R \mid \mid \sum C_i [/math]
  • Некоторые задачи сводятся к другим похожим задачам теории расписаний путем преобразования их расписаний:
    [math] 1 \mid intree \mid \sum w_i C_i [/math]

Построение расписания по нижней оценке

Этот метод обычно применим к задачам, в которых целевая функция — [math] C_{max}[/math]. Обычно построение расписания по нижней оценке происходит в два этапа:

  1. Построение некоторого набора нижних ограничений на произвольное расписание для задачи [math] S [/math].
  2. Построение произвольного допустимого расписания, достигающего максимального ограничения из построенного набора.

С помощью этого метода решаются следующие задачи:

P | pmtn | C_max

Найдем набор ограничений на значение [math] C_{max} [/math] для произвольного допустимого расписания [math] S [/math] :

  1. В допустимом расписании выполнение всех работ не может завершиться раньше одной из них, поэтому [math] C_{max} \geqslant p_i [/math].
  2. Если все станки работали время [math] C_{max} [/math], на них могло выполниться не больше [math] C_{max} \cdot m [/math] работы, то есть [math] \sum\limits_i p_i \leqslant C_{max} \cdot m [/math] и [math] C_{max} \geqslant \dfrac1m \sum\limits_i p_i [/math].

Из этих ограничений следует, что [math] C_{max} = \max {\left( \max\limits_i p_i; \dfrac1m \sum\limits_i p_i \right)} [/math].

Построим расписание, подходящее под эту границу: будем по очереди заполнять машины работами в произвольном порядке, и если очередная работа не помещается на текущей машине полностью, перенесем ее выходящую за [math] C_{max} [/math] часть на следующую машину. Благодаря первому ограничению никакая работа не будет выполняться одновременно на двух станках, а благодаря второму — не останется работы, которую мы не сможем выполнить.

Бинарный поиск по ответу

Этот способ часто подходит для задач, в которых надо минимизировать [math]C_{max} [/math] (если мы умеем решать соответствующую задачу существования расписания), реже для [math] \sum w_i U_i [/math]. Важно помнить, что если требуется полиномиальное по [math] n [/math] решение, оно не должно зависеть от логарифма ответа, но иногда ответ ограничен полиномом от [math]n[/math], и мы можем применить этот метод.

Примером решения задач подобным методом служит следующая задача: [math] Q \mid pmtn, r_i \mid L_{max} [/math]

Жадное построение расписания

Определение:
Жадный алгоритм — алгоритм решения задач путем выбора локально оптимальных решений на каждом этапе алгоритма.

Естественно, далеко не все оптимизационные задачи можно решать жадно — для этого сначала необходимо доказать оптимальность жадного выбора.

С помощью этого метода решаются:

Обычно оптимальность жадного выбора доказывают двумя способами:

Неправильно

Приведем пример часто распространенных неправильных действий при доказательстве оптимальности жадного алгоритма:

Пусть предложенным нами алгоритмом мы получили какое-то решение [math] S [/math]. Атомарными изменениями в этом решении [math] S [/math] будем получать другие допустимые решения [math] S' [/math] и докажем, что [math] f(S) \leqslant f(S') [/math]. Тогда решение [math] S [/math] — оптимально.

Проблема в этих рассуждениях в том, что ими мы доказываем локальную оптимальность алгоритма в решении [math] S [/math]. Получение же глобального минимума может потребовать нескольких атомарных изменений в расписании, поэтому доказать оптимальность таким образом в общем случае невозможно. Как ближайшую аналогию, можно привести неправильное утверждение для произвольной функции [math] f(\bar x) [/math] — «если все частные производные [math] \dfrac{\partial f}{\partial x_1} \dots \dfrac{\partial f}{\partial x_n} [/math] неотрицательны, то в точке [math] \bar x [/math] наблюдается глобальный минимум».

Правильно

При доказательстве оптимательности применима стратегия аргумент замены (англ. exchange argument). Стратегия заключается в рассмотрении текущего решения [math] S [/math] и оптимального решения [math] O [/math]. Далее предлагается способ модификации [math] O [/math] в [math] O'[/math] так, что:

  1. [math] f(O') \leqslant f(O) [/math], то есть [math] O' [/math] также оптимально.
  2. [math] O' [/math] «более похоже» на [math] S [/math], чем на [math] O [/math].

Если такой способ найден, получаем, что какой-то последовательностью модификаций [math] O \to O_t' \to \dots \to O_1' \to S [/math] получим [math] f(S) \leqslant f(O_1') \leqslant \dots \leqslant f(O_t') \leqslant f(O) [/math], из чего следует оптимальность [math] S [/math].

Отношение «более похоже» должно быть отношением частичного строгого порядка. Часто в качестве него можно выбрать отношение «длина наибольшего общего префикса решения [math] A [/math] и [math] S [/math] меньше наибольшего общего префикса решения [math] B [/math] и [math] S [/math]». Тогда если мы сможем увеличить длину наибольшего общего префикса для оптимального решения, не нарушив оптимальности, мы приблизимся к [math] S [/math]. Можно выбирать и более сложные отношения, например, в доказательстве оптимальности алгоритма [math] P \mid \mid \sum w_i C_i [/math] для решения задачи [math] P \mid pmtn \mid \sum w_i C_i [/math] используется отношение «время последнего прерывания больше или количество прерываний меньше».

См. также.

Примечания

  1. Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 161
  2. Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 121
  3. Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 129-133
  4. Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 108
  5. Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 137-139

Источники информации

  • Peter Brucker «Scheduling Algorithms», fifth edition, Springer ISBN 978-3-540-69515-8