Ppi1riintegerLmax — различия между версиями
(алгоритм) |
(корректность) |
||
Строка 17: | Строка 17: | ||
'''heap''' M <font color=green>// куча, в которой будем хранить доступные на данный момент работы в порядке неубывания дедлайнов</font> | '''heap''' M <font color=green>// куча, в которой будем хранить доступные на данный момент работы в порядке неубывания дедлайнов</font> | ||
'''while''' j <= n | '''while''' j <= n | ||
− | '''int''' time = jobs[j].first | + | '''int''' time = jobs[j].first <font color=green>// время начала выполнения текущего блока работ</font> |
'''while''' jobs[j].first <= time <font color=green>// добавляем в кучу все невыполненные работы, доступные на данный момент</font> | '''while''' jobs[j].first <= time <font color=green>// добавляем в кучу все невыполненные работы, доступные на данный момент</font> | ||
M.push(j) | M.push(j) | ||
Строка 34: | Строка 34: | ||
M.push(j) | M.push(j) | ||
j++ | j++ | ||
+ | |||
+ | Внутренний цикл '''while''' распределяет работы блоками, в которых они выполняются без простоя станков. После окончания такого блока, время начала выполнения следующего будет равно текущему значению <tex>r_j</tex>. | ||
+ | === Асимптотика === | ||
+ | Сначала мы сортируем работы, что занимает <tex> \mathcal{O}(n\log{n})</tex>. Далее идёт цикл, в котором мы <tex>n</tex> раз кладём элемент в кучу и <tex>n</tex> раз извлекаем, что также занимает <tex> \mathcal{O}(n\log{n})</tex> времени. В итоге всё вместе составляет асимптотику алгоритма <tex> \mathcal{O}(n\log{n})</tex>. | ||
+ | |||
+ | == Доказательство корректности алгоритма == | ||
+ | {{Теорема | ||
+ | |statement= | ||
+ | Приведенный алгоритм строит оптимальное расписание для задачи <tex> P \mid p_i=1; r_i - integer \mid L_{max} </tex>. | ||
+ | |proof= | ||
+ | Пусть <tex>S</tex> {{---}} расписание построенное предложенным алгоритмом, а <tex>S^*</tex> оптимальное расписание со следующими свойствами: | ||
+ | * первые <tex>r-1</tex> работ из <tex>S</tex> в обоих расписаниях назначены на одно и тоже время и | ||
+ | * значение <tex>r-1</tex> {{---}} наибольшее. | ||
+ | Таким образом работа <tex>J_r</tex> в расписании <tex>S</tex> назначена на время <tex>t</tex>, а в расписании <tex>S^*</tex> на другой более поздний момент времени. Если в момент времени <tex>t</tex> в расписании <tex>S^*</tex> есть свободный станок, то работа <tex>J_r</tex> может быть назначена на этот станок и выполнена в момент <tex>t</tex>. Иначе существует работа <tex>J_k</tex> такая, что <tex>d_r \leqslant d_k</tex>, которая выполнится в расписании <tex>S^*</tex> в момент <tex>t</tex>, а в <tex>S</tex> в другое время. Тогда мы меняем местами работы <tex>J_k</tex> и <tex>J_r</tex> в расписании <tex>S^*</tex>, что не нарушает оптимальность <tex>S^*</tex>, но является противоречием максимальности значения <tex>r-1</tex>. | ||
+ | }} | ||
+ | |||
+ | == См. также == | ||
+ | * [[Pintreepi1Lmax|<tex>P \mid intree, p_{i} = 1 \mid L_{max}</tex>]] | ||
+ | * [[PpmtnriLmax|<tex>P \mid pmtn, r_i \mid L_{max}</tex>]] | ||
+ | |||
+ | == Источники информации == | ||
+ | * Peter Brucker «Scheduling Algorithms», fifth edition, Springer {{---}} с. 111-112 ISBN 978-3-540-69515-8 | ||
+ | |||
+ | [[Категория: Алгоритмы и структуры данных]] | ||
+ | [[Категория: Теория расписаний]] |
Версия 13:51, 4 июня 2016
Задача: |
Дано | однородных станков, работающих параллельно, и работ с временем выполнения , временем появления , заданным целым числом, и момент времени , к которому нужно выполнить работу. Необходимо построить такое расписание, чтобы значение максимального опоздания было минимальным.
Содержание
Описание алгоритма
Идея
Отсортируем все работы по времени появления в неубывающем порядке так, что
. Теперь будем выполнять доступные на данный момент работы в порядке неубывания дедлайнов . То есть, если в момент времени есть свободные станки и есть невыполненные работы такие, что , то назначаем работу с наименьшим дедлайном на свободный станок.Псевдокод
Алгоритм принимает на вход массив пар, где первый элемент является временем появления
работы, а второй её дедлайном , и возвращает расписание, представленное массивом, где на позиции стоит момент обработки работы .function scheduling(jobs: <int, int>[n]) -> int[n] sort(jobs) // сортируем работы в порядке неубывания времени появления int j = 1 // последняя невыполненная работа int[n] ans // массив, куда будет записано расписание heap M // куча, в которой будем хранить доступные на данный момент работы в порядке неубывания дедлайнов while j <= n int time = jobs[j].first // время начала выполнения текущего блока работ while jobs[j].first <= time // добавляем в кучу все невыполненные работы, доступные на данный момент M.push(j) j++ int k = 0 // количество занятых станков в данный момент времени while M.notEmpty() i = M.pop() // получаем доступную работу с наименьшим дедлайном ans[i] = t // назначаем работу i на время t if k + 1 < m // если в момент t есть свободный станок, то назначаем работу i на него k++ else // иначе увеличиваем время и обновляем список доступных работ t++ k = 0 while jobs[j].first <= time M.push(j) j++
Внутренний цикл while распределяет работы блоками, в которых они выполняются без простоя станков. После окончания такого блока, время начала выполнения следующего будет равно текущему значению
.Асимптотика
Сначала мы сортируем работы, что занимает
. Далее идёт цикл, в котором мы раз кладём элемент в кучу и раз извлекаем, что также занимает времени. В итоге всё вместе составляет асимптотику алгоритма .Доказательство корректности алгоритма
Теорема: |
Приведенный алгоритм строит оптимальное расписание для задачи . |
Доказательство: |
Пусть — расписание построенное предложенным алгоритмом, а оптимальное расписание со следующими свойствами:
|
См. также
Источники информации
- Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 111-112 ISBN 978-3-540-69515-8