Ppi1sumwu — различия между версиями
Анна (обсуждение | вклад) (→Псевдокод) |
м (rollbackEdits.php mass rollback) |
||
(не показаны 3 промежуточные версии 2 участников) | |||
Строка 9: | Строка 9: | ||
=== Псевдокод === | === Псевдокод === | ||
− | Пусть есть работы <tex>1 \ldots n</tex> с временами окончания <tex>d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n</tex>. Будем называть ''простоем '' временной интервал, в который на машине ничего не обрабатывается. Для определения работ, не укладывающихся в срок, заведем счетчик времени <tex>t</tex>, который будем модифицировать так, как показано ниже. Тогда работа <tex>j</tex> опаздывает, если <tex>\left | + | Пусть есть работы <tex>1 \ldots n</tex> с временами окончания <tex>d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n</tex>. Будем называть ''простоем '' временной интервал, в который на машине ничего не обрабатывается. Для определения работ, не укладывающихся в срок, заведем счетчик времени <tex>t</tex>, который будем модифицировать так, как показано ниже. Тогда работа <tex>j</tex> опаздывает, если <tex>\left\lfloor \dfrac{t}{m} \right\rfloor + p_j > d_j</tex>, где <tex>p_j = 1</tex>. Следующий алгоритм вычислит оптимальное множество <tex>S</tex>. |
<tex>S = \varnothing</tex> | <tex>S = \varnothing</tex> | ||
Строка 35: | Строка 35: | ||
* <tex>l</tex> {{---}} первая работа в <tex>S</tex>: <tex>l \notin S^*</tex> | * <tex>l</tex> {{---}} первая работа в <tex>S</tex>: <tex>l \notin S^*</tex> | ||
* <tex>k</tex> {{---}} первая работа в <tex>S^*</tex>: <tex>k \notin S</tex> | * <tex>k</tex> {{---}} первая работа в <tex>S^*</tex>: <tex>k \notin S</tex> | ||
− | Покажем, что в <tex>S^*</tex> работа <tex>k</tex> может быть заменена работой <tex>l</tex> без увеличения значения целевой функции. Рассмотрим два случая: | + | Покажем, что в <tex>S^*</tex> работа <tex>k</tex> может быть заменена работой <tex>l</tex> без увеличения значения целевой функции. Рассмотрим два случая: |
− | # Пусть <tex>l < k</tex>. | + | # Пусть <tex>l < k</tex>. |
− | #:То, что <tex>k</tex> не принадлежит множеству <tex>S</tex>, значит, что либо на некотором шаге появилась опаздывающая работа <tex>j</tex>, которая заменила <tex>k</tex>, либо работа <tex>k</tex> опаздывала и <tex>w_k</tex> было меньше <tex>\min\limits_{i \in S}w_i</tex>, и поэтому она не была добавлена. В любом случае в это время работа <tex>l</tex> уже принадлежала <tex>S</tex>. Во втором случае очевидно, что <tex>w_k \leqslant w_l</tex>. То же неравенство выполняется и в первом случае, так как на этапе замены мы выбрали <tex>k</tex>, а не <tex>l</tex>. Следовательно, мы не ухудшим целевую функцию заменой <tex>k</tex> на <tex>l</tex>. | + | #:То, что <tex>k</tex> не принадлежит множеству <tex>S</tex>, значит, что либо на некотором шаге появилась опаздывающая работа <tex>j</tex>, которая заменила <tex>k</tex>, либо работа <tex>k</tex> опаздывала и <tex>w_k</tex> было меньше <tex>\min\limits_{i \in S}w_i</tex>, и поэтому она не была добавлена. В любом случае в это время работа <tex>l</tex> уже принадлежала <tex>S</tex>. Во втором случае очевидно, что <tex>w_k \leqslant w_l</tex>. То же неравенство выполняется и в первом случае, так как на этапе замены мы выбрали <tex>k</tex>, а не <tex>l</tex>. Следовательно, мы не ухудшим целевую функцию заменой <tex>k</tex> на <tex>l</tex>. |
− | # Пусть <tex>l > k</tex>. | + | # Пусть <tex>l > k</tex>. |
− | #:Замена работы <tex>k</tex> в <tex>S^*</tex> на работу <tex>l</tex> не противоречит условию, что за все работы в этом множестве штраф налагаться не будет, так как <tex>k</tex> выполнялась в срок, а <tex>d_k \leqslant d_l</tex> и все работы выполняются одинаковое количество времени. Следовательно, <tex>l</tex> так же будет выполнена в срок. Осталось доказать, что <tex>w_k \leqslant w_l</tex>. | + | #:Замена работы <tex>k</tex> в <tex>S^*</tex> на работу <tex>l</tex> не противоречит условию, что за все работы в этом множестве штраф налагаться не будет, так как <tex>k</tex> выполнялась в срок, а <tex>d_k \leqslant d_l</tex> и все работы выполняются одинаковое количество времени. Следовательно, <tex>l</tex> так же будет выполнена в срок. Осталось доказать, что <tex>w_k \leqslant w_l</tex>. |
− | #:Пусть работа <tex>k_{i_0} = k</tex> была заменена работой <tex>i_0</tex>, а так же <tex>k_{i_1} \ldots k_{i_r}</tex> {{---}} последовательность работ из <tex>S</tex>, каждая из которых была на некотором шаге заменена работой <tex>i_1 \ldots i_r</tex> соответственно. Тогда <tex>i_0 < i_1 < \ldots < i_r</tex>. | + | #:Пусть работа <tex>k_{i_0} = k</tex> была заменена работой <tex>i_0</tex>, а так же <tex>k_{i_1} \ldots k_{i_r}</tex> {{---}} последовательность работ из <tex>S</tex>, каждая из которых была на некотором шаге заменена работой <tex>i_1 \ldots i_r</tex> соответственно. Тогда <tex>i_0 < i_1 < \ldots < i_r</tex>. |
#:[[Файл:Sh.jpg|370px|thumb|right|Рис. 1. <tex>i_v</tex> превосходит <tex>i_u</tex>.]] | #:[[Файл:Sh.jpg|370px|thumb|right|Рис. 1. <tex>i_v</tex> превосходит <tex>i_u</tex>.]] | ||
− | #:Будем говорить <tex>i_v</tex> ''превосходит'' <tex>i_u</tex>, где <tex>u < v</tex>, если <tex>k_{i_v} \leqslant i_u</tex>. Тогда <tex>w_{k_{i_v}} \geqslant w_{k_{i_u}}</tex>, так как когда мы вставляли работу <tex>i_u</tex> мы выбрали для замены <tex>k_{i_u}</tex>, то есть ее вес был минимальным среди всех работ, находившихся на тот момент в <tex>S</tex>, включая <tex>k_{i_v}</tex>. Для большей ясности на рисунке 1 показано, в каком порядке располагаются эти работы относительно друг друга согласно их номерам. | + | #:Будем говорить <tex>i_v</tex> ''превосходит'' <tex>i_u</tex>, где <tex>u < v</tex>, если <tex>k_{i_v} \leqslant i_u</tex>. Тогда <tex>w_{k_{i_v}} \geqslant w_{k_{i_u}}</tex>, так как когда мы вставляли работу <tex>i_u</tex> мы выбрали для замены <tex>k_{i_u}</tex>, то есть ее вес был минимальным среди всех работ, находившихся на тот момент в <tex>S</tex>, включая <tex>k_{i_v}</tex>. Для большей ясности на рисунке 1 показано, в каком порядке располагаются эти работы относительно друг друга согласно их номерам. |
#:Если из последовательности <tex>i_0 < i_1 < \ldots < i_r</tex> можно выделить подпоследовательность <tex>j_0 = i_0 < j_1 < \ldots < j_s</tex> со свойствами: | #:Если из последовательности <tex>i_0 < i_1 < \ldots < i_r</tex> можно выделить подпоследовательность <tex>j_0 = i_0 < j_1 < \ldots < j_s</tex> со свойствами: | ||
#:* <tex>j_{v + 1}</tex> превосходит <tex>j_v</tex>, где <tex>v \in [0 \ldots s - 1]</tex> | #:* <tex>j_{v + 1}</tex> превосходит <tex>j_v</tex>, где <tex>v \in [0 \ldots s - 1]</tex> | ||
#:* <tex>j_{s - 1} < l \leqslant j_s</tex> , | #:* <tex>j_{s - 1} < l \leqslant j_s</tex> , | ||
− | #:то <tex>w_l \geqslant w_{k_{j_s}} \geqslant \ldots \geqslant w_{k_{j_0}} = w_k</tex>, что доказывает теорему. | + | #:то <tex>w_l \geqslant w_{k_{j_s}} \geqslant \ldots \geqslant w_{k_{j_0}} = w_k</tex>, что доказывает теорему. |
− | #:В противном случае найдем такую работу <tex>i_t</tex> с наименьшим <tex>t</tex>, что никакая работа <tex>i_v</tex>, где <tex>v > t</tex>, не превосходит <tex>i_t</tex>, причем <tex>i_t < l</tex>. По определению это значит, что после того, как работа <tex>i_t</tex> будет добавлена в <tex>S</tex>, ни одна работа <tex>i \leqslant i_t</tex> не будет удалена из этого множества. Так как <tex>i_t < l</tex>, то по определению <tex>l</tex> все работы, которые на момент добавления <tex>i_t</tex> находятся в <tex>S</tex>, так же должны принадлежать <tex>S^*</tex>. Покажем, что это приведет нас к противоречию. | + | #:В противном случае найдем такую работу <tex>i_t</tex> с наименьшим <tex>t</tex>, что никакая работа <tex>i_v</tex>, где <tex>v > t</tex>, не превосходит <tex>i_t</tex>, причем <tex>i_t < l</tex>. По определению это значит, что после того, как работа <tex>i_t</tex> будет добавлена в <tex>S</tex>, ни одна работа <tex>i \leqslant i_t</tex> не будет удалена из этого множества. Так как <tex>i_t < l</tex>, то по определению <tex>l</tex> все работы, которые на момент добавления <tex>i_t</tex> находятся в <tex>S</tex>, так же должны принадлежать <tex>S^*</tex>. Покажем, что это приведет нас к противоречию. |
− | #:Пусть <tex>S_t</tex> {{---}} множество <tex>S</tex> после удаления <tex>k_{i_t}</tex> и добавления <tex>i_t</tex>. Рассмотрим два случая: | + | #:Пусть <tex>S_t</tex> {{---}} множество <tex>S</tex> после удаления <tex>k_{i_t}</tex> и добавления <tex>i_t</tex>. Рассмотрим два случая: |
#::<tex>(a)</tex> Если <tex>k^* = k_{i_t} > k</tex>, то есть <tex>d_{k^*} \geqslant d_k</tex>, то мы можем заменить <tex>k</tex> на <tex>k^*</tex> в <tex>S^*</tex>, сохранив условие, что <tex>S^*</tex> не содержит опаздывающих работ. Следовательно, множество <tex>S_t \cup \{k^*\}</tex> не содержит работ со штрафами, что противоречит построению <tex>S</tex>. | #::<tex>(a)</tex> Если <tex>k^* = k_{i_t} > k</tex>, то есть <tex>d_{k^*} \geqslant d_k</tex>, то мы можем заменить <tex>k</tex> на <tex>k^*</tex> в <tex>S^*</tex>, сохранив условие, что <tex>S^*</tex> не содержит опаздывающих работ. Следовательно, множество <tex>S_t \cup \{k^*\}</tex> не содержит работ со штрафами, что противоречит построению <tex>S</tex>. | ||
#::<tex>(b)</tex> Пусть <tex>k^* < k</tex>. Тогда все работы из <tex>S_t \cup \{k\}</tex> могут быть выполнены в срок, так как <tex>S_t</tex> и <tex>k</tex> принадлежат <tex>S^*</tex>. Более того, все работы из множества <tex>\{j \in S_t \mid j < k\}</tex> могут быть выполнены без опозданий. Таким образом, мы снова приходим к тому, что множество <tex>S_t \cup \{k^*\}</tex> не содержит работ со штрафами, что является противоречием. | #::<tex>(b)</tex> Пусть <tex>k^* < k</tex>. Тогда все работы из <tex>S_t \cup \{k\}</tex> могут быть выполнены в срок, так как <tex>S_t</tex> и <tex>k</tex> принадлежат <tex>S^*</tex>. Более того, все работы из множества <tex>\{j \in S_t \mid j < k\}</tex> могут быть выполнены без опозданий. Таким образом, мы снова приходим к тому, что множество <tex>S_t \cup \{k^*\}</tex> не содержит работ со штрафами, что является противоречием. |
Текущая версия на 19:21, 4 сентября 2022
Задача: |
Дано | одинаковых станков, на которых нужно выполнить работ. Любая работа на любом станке выполняется единицу времени. Для каждой работы есть время окончания — ожидается, что до этого времени она будет закончена, и штраф , который нужно будет выплатить в случае, если работа была закончена после . Необходимо минимизировать суммарный штраф, который придется выплатить.
Содержание
Описание алгоритма
Идея
Оптимальное расписание для этой задачи будем задавать множеством работ
, которые будут выполнены в срок. Работы, которые не войдут в , то есть завершатся с опозданием, могут быть выполнены в конце в любом порядке. Чтобы построить множество , будем добавлять работы в порядке неуменьшения их времен окончания, и как только некоторая работа опаздывает, удалим из работу с минимальным значением и поставим на ее место.Псевдокод
Пусть есть работы
с временами окончания . Будем называть простоем временной интервал, в который на машине ничего не обрабатывается. Для определения работ, не укладывающихся в срок, заведем счетчик времени , который будем модифицировать так, как показано ниже. Тогда работа опаздывает, если , где . Следующий алгоритм вычислит оптимальное множество .for to if опаздывает, и все более ранние простои заполнены найти if заменить на в else добавить в и поставить на место самого раннего простоя
Таким образом, работы, не попавшие в
, будут иметь минимальное значение .Асимптотика
Данный алгоритм может быть реализован за время приоритетной очереди и для множества использовать любую структуру данных, у которой операции поиска и добавления элемента не хуже, чем .
, например, если хранить значения , которые принадлежат , вДоказательство корректности
Теорема: |
Вышеописанный алгоритм корректен и строит оптимальное множество работ . |
Доказательство: |
Пусть
Покажем, что в работа может быть заменена работой без увеличения значения целевой функции. Рассмотрим два случая:
|
См. также
Источники информации
- Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 119-120 ISBN 978-3-540-69515-8