1ripmtnsumwu — различия между версиями
Zernov (обсуждение | вклад) |
м (rollbackEdits.php mass rollback) |
||
(не показано 18 промежуточных версий 3 участников) | |||
Строка 3: | Строка 3: | ||
{{Задача | {{Задача | ||
|definition=Дана задача на нахождение расписания: | |definition=Дана задача на нахождение расписания: | ||
− | # У нас есть несколько работ, | + | # У нас есть несколько работ, которые необходимо выполнить на одном станке. |
# У работ есть время появления <tex>r_i</tex>. | # У работ есть время появления <tex>r_i</tex>. | ||
# Работы разрешается прерывать в любой момент времени. | # Работы разрешается прерывать в любой момент времени. | ||
Строка 15: | Строка 15: | ||
Пусть работы заданы в порядке неубывания их дедлайнов, то есть <tex>d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n</tex>. За <tex>k</tex> обозначим количество различных <tex>r_{i}</tex>. За <tex>W = \sum\limits_{j = 1}^{n} {w_j}</tex> | Пусть работы заданы в порядке неубывания их дедлайнов, то есть <tex>d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n</tex>. За <tex>k</tex> обозначим количество различных <tex>r_{i}</tex>. За <tex>W = \sum\limits_{j = 1}^{n} {w_j}</tex> | ||
− | Назовем множество работ <tex>S</tex> '''выполнимым''' (англ. ''feasible''), если существует такое расписание для работ из <tex>S</tex>, что все работы будут выполнены без опозданий. Чтобы проверить, является ли множество работ выполнимым, воспользуемся упрощенной версией <tex>\mathrm{EDD}</tex> правила<ref> | + | Назовем множество работ <tex>S</tex> '''выполнимым''' (англ. ''feasible''), если существует такое расписание для работ из <tex>S</tex>, что все работы будут выполнены без опозданий. Чтобы проверить, является ли множество работ выполнимым, воспользуемся упрощенной версией <tex>\mathrm{EDD}</tex> правила <ref>Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 70</ref> (<tex>\mathrm{EDD}</tex> (''earliest due date'') правило {{---}} правило наименьшего срока): |
:''Составим расписание работ таким образом, чтобы первой в расписании стояла работа с наименьшим значением <tex>r_{i}</tex>. В любой момент времени, когда появляется новая работа, либо заканчивает выполняться текущая, вставим в расписание работу с наименьшим оставшимся сроком.'' | :''Составим расписание работ таким образом, чтобы первой в расписании стояла работа с наименьшим значением <tex>r_{i}</tex>. В любой момент времени, когда появляется новая работа, либо заканчивает выполняться текущая, вставим в расписание работу с наименьшим оставшимся сроком.'' | ||
− | <tex>S</tex> выполнимо тогда и только тогда, когда все работы в <tex>\mathrm{EDD}</tex> расписании выполняются без опозданий. Это прямое следствие из | + | <tex>S</tex> выполнимо тогда и только тогда, когда все работы в <tex>\mathrm{EDD}</tex> расписании выполняются без опозданий. Это прямое следствие из теоремы 4.4 <ref>Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 70</ref>. Если в <tex>S</tex> содержится <tex>n</tex> работ, то построение <tex>\mathrm{EDD}</tex> расписание может быть выполнено за <tex>O(n \log n)</tex> времени. Наша задача сводится к тому, чтобы найти выполнимое множество работ с максимальным суммарным весом. |
Для данного непустого множества <tex>S</tex> определим следующие величины: | Для данного непустого множества <tex>S</tex> определим следующие величины: | ||
Строка 27: | Строка 27: | ||
Кроме того, обозначим за <tex>C(S)</tex> время последней выполненной работы из <tex>S</tex> в <tex>\mathrm{EDD}</tex> расписании. Оно состоит из периодов непрерывного выполнения работы, разделенных периодами бездействия, когда нет доступных работ для выполнения. Это означает, что <tex>S</tex> может быть разделено на множества <tex>S_{1} \ldots S_{x}</tex>, для которых выполняется <tex>C(S_{i}) = r(S_{i}) + p(S_{i}) < r(S_{i + 1})</tex> для <tex>i = 1 \ldots x - 1 </tex>. | Кроме того, обозначим за <tex>C(S)</tex> время последней выполненной работы из <tex>S</tex> в <tex>\mathrm{EDD}</tex> расписании. Оно состоит из периодов непрерывного выполнения работы, разделенных периодами бездействия, когда нет доступных работ для выполнения. Это означает, что <tex>S</tex> может быть разделено на множества <tex>S_{1} \ldots S_{x}</tex>, для которых выполняется <tex>C(S_{i}) = r(S_{i}) + p(S_{i}) < r(S_{i + 1})</tex> для <tex>i = 1 \ldots x - 1 </tex>. | ||
− | Выполнимое множество <tex>S</tex> является '''блоком''' (англ. ''block''), если работы из <tex>S</tex> обрабатываются непрерывно с начала и до конца, и <tex>S</tex> не может быть разделен на подмножества, расписания для которых не пересекаются, например, если <tex>C(S) = r(S)+ p(S)</tex> и <tex>S</tex> не является объединением <tex>S_{1}</tex> и <tex>S_{2}</tex> таких, что <tex>C(S_{1}) < r(S_{2})</tex>. Решим задачу <tex dpi>1 \mid r_i, pmtn \mid \sum w_{i}U_{i}</tex> методами динамического программирования. | + | Выполнимое множество <tex>S</tex> является '''блоком''' (англ. ''block''), если работы из <tex>S</tex> обрабатываются непрерывно с начала и до конца, и <tex>S</tex> не может быть разделен на подмножества, расписания для которых не пересекаются, например, если <tex>C(S) = r(S)+ p(S)</tex> и <tex>S</tex> не является объединением <tex>S_{1}</tex> и <tex>S_{2}</tex> таких, что <tex>C(S_{1}) < r(S_{2})</tex>. Решим задачу <tex dpi>1 \mid r_i, pmtn \mid \sum w_{i}U_{i}</tex> методами [[Динамическое программирование|динамического программирования]]. |
− | Введем величину <tex>C_{i}(r, w) = \min \{C(S) \mid S \subseteq \{ 1 \ldots i \} </tex> {{---}} выполнимое <tex> | + | Введем величину <tex>C_{i}(r, w) = \min \{C(S) \mid S \subseteq \{ 1 \ldots i \} </tex> {{---}} выполнимое, причём выполняется <tex> r(S) \geqslant r \wedge w(S) \geqslant w \}</tex> и <tex>C_{i}(r, w) = \infty</tex>, если множеств, удовлетворяющих условиям, нет. |
− | Максимальный вес выполнимого множества задается максимальным значением <tex>w</tex> такого, что <tex>C_{n}(r_{\min}, w</tex> конечно, где <tex>r_{\min} = \min\limits_{j = 1 \ldots n} r_{i}</tex>. Посчитаем значения <tex>C_{j}(r, w)</tex> за <tex>n</tex> итераций с начальными значениями | + | Максимальный вес выполнимого множества задается максимальным значением <tex>w</tex> такого, что <tex>C_{n}(r_{\min}, w)</tex> конечно, где <tex>r_{\min} = \min\limits_{j = 1 \ldots n} r_{i}</tex>. Посчитаем значения <tex>C_{j}(r, w)</tex> за <tex>n</tex> итераций с начальными значениями: |
:<tex>C_{0}(r, 0) = 0</tex> для всех <tex>r</tex> | :<tex>C_{0}(r, 0) = 0</tex> для всех <tex>r</tex> | ||
:<tex>C_{0}(r, w) = \infty</tex> для всех <tex>r</tex> и <tex>w > 0</tex> | :<tex>C_{0}(r, w) = \infty</tex> для всех <tex>r</tex> и <tex>w > 0</tex> | ||
− | <tex>j</tex> не может содержаться в выполнимом множестве, если <tex>r(S) > r_{j}</tex>. Следовательно, | + | <tex>j</tex> не может содержаться в выполнимом множестве, если <tex>r(S) > r_{j}</tex>. Следовательно, |
:<p> | :<p> | ||
<tex>C_{j}(r, w) | <tex>C_{j}(r, w) | ||
− | \left \{\begin{array}{ll} = C_{j - 1}(r, w) & \text{if } r > r_{j} \\ | + | \left \{\begin{array}{ll} = C_{j - 1}(r, w), & \text{if } r > r_{j} \\ |
\leqslant C_{j - 1}(r, w), & \text{otherwise} \end{array} \right. | \leqslant C_{j - 1}(r, w), & \text{otherwise} \end{array} \right. | ||
</tex> | </tex> | ||
Строка 45: | Строка 45: | ||
Отсюда следует, что нам нужно посчитать только такие значения <tex>C_{j} (r, w)</tex> для которых <tex>r \leqslant r_{j}</tex>. Пусть <tex> S \subseteq \{ 1 \ldots j \} </tex> и <tex>C_{j}(r, w) = C(S)</tex>. Если <tex>j \notin S</tex>, тогда <tex>C_{j}(r, w) = C_{j - 1}(r, w)</tex>. Иначе рассмотрим два случая. | Отсюда следует, что нам нужно посчитать только такие значения <tex>C_{j} (r, w)</tex> для которых <tex>r \leqslant r_{j}</tex>. Пусть <tex> S \subseteq \{ 1 \ldots j \} </tex> и <tex>C_{j}(r, w) = C(S)</tex>. Если <tex>j \notin S</tex>, тогда <tex>C_{j}(r, w) = C_{j - 1}(r, w)</tex>. Иначе рассмотрим два случая. | ||
− | === Первый случай === | + | === Разбор случаев === |
+ | |||
+ | ==== Первый случай ==== | ||
Работа <tex>j</tex> начинается после <tex>C(S \setminus \{j\})</tex>. | Работа <tex>j</tex> начинается после <tex>C(S \setminus \{j\})</tex>. | ||
− | Рассмотрим два подслучая | + | Рассмотрим два подслучая: |
− | # | + | # <tex>C(S \setminus \{j\}) \leqslant r_{j}</tex> <br> В этом случае <tex>C(S) = r_{j} + p_{j}</tex> |
− | + | # <tex>C(S \setminus \{j\}) > r_{j}</tex> <br>Работы из <tex>C(S \setminus \{j\})</tex> обрабатываются непрерывно в интервале <tex>[r_{j}, C(S \setminus \{j\})]</tex>, потому что иначе <tex>j</tex> начнет обрабатываться до <tex>C(S \setminus \{j\})</tex>. | |
Делаем вывод, что <tex>C_{j} (r, w) = \max(r_{j} , C(S \setminus \{j\}) + p_{j}</tex>. Предположим, что <tex>C(S \setminus \{j\})</tex> такое, что <tex>C(S \setminus \{j\}) = C_{j - 1}(r, w - w_{j})</tex> и, если это не так, заменим <tex>C(S \setminus \{j\})</tex> на выполнимое подмножество из <tex>1 \ldots j - 1</tex> для которого это выполняется. Из этого следует, что | Делаем вывод, что <tex>C_{j} (r, w) = \max(r_{j} , C(S \setminus \{j\}) + p_{j}</tex>. Предположим, что <tex>C(S \setminus \{j\})</tex> такое, что <tex>C(S \setminus \{j\}) = C_{j - 1}(r, w - w_{j})</tex> и, если это не так, заменим <tex>C(S \setminus \{j\})</tex> на выполнимое подмножество из <tex>1 \ldots j - 1</tex> для которого это выполняется. Из этого следует, что | ||
:<tex>C_{j}(r, w) = \max(r_{j} , C_{j - 1}(r, w − w_{j})) + p_{j}</tex>. | :<tex>C_{j}(r, w) = \max(r_{j} , C_{j - 1}(r, w − w_{j})) + p_{j}</tex>. | ||
− | === Второй случай === | + | ==== Второй случай ==== |
Работа <tex>j</tex> начинается перед <tex>C(S \setminus \{j\})</tex>. | Работа <tex>j</tex> начинается перед <tex>C(S \setminus \{j\})</tex>. | ||
Строка 103: | Строка 105: | ||
</p> | </p> | ||
− | С начальными значениями | + | С начальными значениями: |
: <tex>P_{j - 1}(r, r', 0) = 0</tex> для <tex>j = 1 \ldots n</tex> | : <tex>P_{j - 1}(r, r', 0) = 0</tex> для <tex>j = 1 \ldots n</tex> | ||
: <tex>P_{0}(r, r', w'') = \infty</tex> для <tex>w'' > 0\ldots n</tex> | : <tex>P_{0}(r, r', w'') = \infty</tex> для <tex>w'' > 0\ldots n</tex> |
Текущая версия на 19:27, 4 сентября 2022
Задача: |
Дана задача на нахождение расписания:
|
Содержание
Описание алгоритма
Идея
Пусть работы заданы в порядке неубывания их дедлайнов, то есть
. За обозначим количество различных . ЗаНазовем множество работ [1] ( (earliest due date) правило — правило наименьшего срока):
выполнимым (англ. feasible), если существует такое расписание для работ из , что все работы будут выполнены без опозданий. Чтобы проверить, является ли множество работ выполнимым, воспользуемся упрощенной версией правила- Составим расписание работ таким образом, чтобы первой в расписании стояла работа с наименьшим значением . В любой момент времени, когда появляется новая работа, либо заканчивает выполняться текущая, вставим в расписание работу с наименьшим оставшимся сроком.
[2]. Если в содержится работ, то построение расписание может быть выполнено за времени. Наша задача сводится к тому, чтобы найти выполнимое множество работ с максимальным суммарным весом.
выполнимо тогда и только тогда, когда все работы в расписании выполняются без опозданий. Это прямое следствие из теоремы 4.4Для данного непустого множества
определим следующие величины:Кроме того, обозначим за
время последней выполненной работы из в расписании. Оно состоит из периодов непрерывного выполнения работы, разделенных периодами бездействия, когда нет доступных работ для выполнения. Это означает, что может быть разделено на множества , для которых выполняется для .Выполнимое множество динамического программирования.
является блоком (англ. block), если работы из обрабатываются непрерывно с начала и до конца, и не может быть разделен на подмножества, расписания для которых не пересекаются, например, если и не является объединением и таких, что . Решим задачу методамиВведем величину
— выполнимое, причём выполняется и , если множеств, удовлетворяющих условиям, нет.Максимальный вес выполнимого множества задается максимальным значением
такого, что конечно, где . Посчитаем значения за итераций с начальными значениями:- для всех
- для всех и
не может содержаться в выполнимом множестве, если . Следовательно,
Отсюда следует, что нам нужно посчитать только такие значения
для которых . Пусть и . Если , тогда . Иначе рассмотрим два случая.Разбор случаев
Первый случай
Работа
начинается после .Рассмотрим два подслучая:
-
В этом случае -
Работы из обрабатываются непрерывно в интервале , потому что иначе начнет обрабатываться до .
Делаем вывод, что
. Предположим, что такое, что и, если это не так, заменим на выполнимое подмножество из для которого это выполняется. Из этого следует, что- .
Второй случай
Работа
начинается перед .В этом случае существует простой в
расписании для множества после . Пусть — последний блок в , то есть является блоком в . Тогда , в таком случае обязано выполняться равенство , иначе расписание для будет не оптимально.Кроме того, мы можем предположить, что общее количество сделанной работы в
, лежащих в интервале , — минимально, учитвая выполнимые множества такие, что .Пусть
— даты появления , и — некоторое целочисленное значение . За возьмем минимальное число сделанной работы в итервале , учитвая выполнимые множества такие, что . Если таких выполнимых множеств нет, то .Используя данную запись, количество времен доступнух для обработки работы
в интервале записывается формулой- .
Количество готовности работы (какое количество уже сделано)
после времени- .
И время выполнения последней работы
из- .
Конечная формула
Собирая все написаное выше, приходим к рекуррентной формуле:
В этой формуле внутренняя минимизация берется по всем различным датам появления
таких, что и целочисленным значениям , . Важно, что формула корректна только в том случае, если правая часть не превышает и, если это не так, то .Рассмотрим, как посчитать значения
для и . Если , то . Иначе значение можно посчитать, используя непустое множество . Если , то . Кроме того, в общем случае, заметим, что выполнятся- .
Где за
берется наименьшая дата появления, меньшая чем , если такая существует.Если
, то пусть будет блоком таким, что . Можно предположить, что . Следовательно, общее количество сделанной работы из в интервале будет равно- .
Пусть
будет наименьшей датой появления, меньшей или равной . Тогда общее количество сделанной работы в в интервале будет равно . Следовательно, общее количество сделанной работы в в интервале будет равно- .
Правая часть выражения должна быть минимальной для множеств
и . Собирая все вместе, получим формулу
С начальными значениями:
- для
- для
Максимальный вес вычислимого множества может быть посчитан с помощью нахождения максимального значения
такого, что — конечно.Ассимптотика
На каждой из
итераций для существует вычислямых значений , по одному на каждую комбинацию из . По представленной выше формуле, каждое значение находится с помощью минимизации из выборов . Следовательно, время, требуемое для вычисления значений , ограниченно на каждой итерации. Всего нам нужно посчитать значений , по одному на каждую комбинацию и . Из формулы, приведенной для вычисления , каждое значение считается с помощью минимизации выборов . Следовательно, время, требуемое для вычисления значений на каждой итерации, ограниченно . Максимальный вес вычислимого множества может быть посчитан с помощью нахождения максимального значения такого, что — конечно. Сделать это мы можем за . Итоговая сложность составляет .Чтобы создать вычислимое множество с максимальным весом, мы считаем характеристический вектор, учитывая значения
и . Вычисляем веторы за , это значение меньше, чем .Специальные случаи
Если времена появления и дедлайны идут в одинаковом порядке, то есть
и , то второй случай никогда не возникает. В этом случае, формула для вычисления может быть упрощена:
Либо, если мы примем
, то:
Отсюда следует, что мы делаем
вычислений в этом случае, когда максимальный вес вычислимого множества такой, что — конечно. В случае, если все веса одинаковы, но время уменьшается до .Когда все времена появления работ равны нулю, рекурретная формула упрощается до
Отсюда следует альтернативное решение для задачи , которое работает за .
См. также
Примечания
Источники информации
- Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 88-93 ISBN 978-3-540-69515-8