1sumwu — различия между версиями
Dominica (обсуждение | вклад) |
Dominica (обсуждение | вклад) (→Идея алгоритма) |
||
Строка 40: | Строка 40: | ||
В ситуации, когда времена выполнения работ <tex>p_i</tex> целочисленные, а значение <tex> \sum\limits_{i=1}^n p_i </tex> не очень большое, то для решения данной задачи можно применить [[Динамическое программирование|динамическое программирование]]. | В ситуации, когда времена выполнения работ <tex>p_i</tex> целочисленные, а значение <tex> \sum\limits_{i=1}^n p_i </tex> не очень большое, то для решения данной задачи можно применить [[Динамическое программирование|динамическое программирование]]. | ||
− | === | + | ===Описание алгоритма=== |
Обозначим <tex>T = \sum\limits_{i=1}^n p_i</tex>. | Обозначим <tex>T = \sum\limits_{i=1}^n p_i</tex>. | ||
Строка 59: | Строка 59: | ||
Ответом на задачу будет <tex>F_n(d_n)</tex>. | Ответом на задачу будет <tex>F_n(d_n)</tex>. | ||
+ | |||
===Псевдокод=== | ===Псевдокод=== | ||
Приведенный ниже алгоритм вычисляет <tex>F_j(t)</tex> для <tex>j = 0,\ldots, n </tex> и <tex>t = 0,\ldots, d_j </tex>. | Приведенный ниже алгоритм вычисляет <tex>F_j(t)</tex> для <tex>j = 0,\ldots, n </tex> и <tex>t = 0,\ldots, d_j </tex>. |
Версия 20:39, 4 июня 2016
Задача: |
Есть один станок и | работ. Для каждой работы заданы время выполнения дедлайн и стоимость выполнения этой работы . Необходимо минимизировать .
Содержание
Наивное решение
В общем случае, когда времена выполнения работ
могут быть сколь угодно большими или, например, дробными, данная задача может быть решена с помощью перебора.Будем перебирать все перестановки чисел от
до , обозначающих номера заданий. При получении очередной перестановки просто будем пытаться выполнять задания в указанном порядке. Если значение , полученное при данном расположении заданий, лучше, чем предыдущие результаты, то обновляем ответ.Данное решение будет работать за
.Перебор с битовыми масками
Далее широко будет использоваться следующий факт:
Лемма: |
Пусть все работы отсортированы в порядке неубывания дедлайнов .
Тогда существует оптимальное расписание вида , такое, что — номера работ, которые успеют выполниться вовремя, а — номера просроченных работ. |
Доказательство: |
Пусть у нас есть некоторое оптимальное раписание . Получим необходимое нам расписание путем переставления некоторых работ.
|
Наше решение будет построено на переборе всех битовых масок. При построении решения мы будем опираться на доказанную лемму.
Если бит, соответствующий заданию с номером
равен , то это задание должно быть записано в список заданий, которые, возможно, успеют выполниться. Далее мы сортируем задания из этого списка по времени неубывания дедлайнов, а те задания, что не попали в этот список, должны быть отправлены в конец расписания в любом порядке. Далее проверяем полученное возможное расписание на корректность, и, в случае успеха, обновляем ответ. Перебор всех масок может быть произведен за , и на пересчет ответа. Таким образом, это решение будет работать за .Псевдополиномиальное решение
В ситуации, когда времена выполнения работ динамическое программирование.
целочисленные, а значение не очень большое, то для решения данной задачи можно применитьОписание алгоритма
Обозначим
. Для всех и будем рассчитывать — значение целевой функции , при условии, что были рассмотрены первые работ и общее время выполнения тех из них, что будут закончены вовремя, не превышает времени .- Если и работа успевает выполниться вовремя в расписании, соответствующем , то , иначе .
- Если , то , поскольку все работы с номерами , законченные позже, чем , будут выполнены с опозданием.
Отсюда, получим соотношение:
В качестве начальных условий следует взять
при и при .Ответом на задачу будет
.Псевдокод
Приведенный ниже алгоритм вычисляет
для и .- За обозначим самое большое из времен выполнения заданий.
- Значения будем хранить в массиве .
- В массиве хранятся стоимости выполнения работ, в — дедлайны, а в — продолжительности выполнения.
functionint int int int int for int сортируем работы по неубыванию времен дедлайнов ; for to for to for to for to for to if else for to return
Для того, чтобы найти само расписание, по доказанной выше лемме, нам достаточно найти множество работ
, которые будут выполнены с опозданием. Это может быть сделано следующим способом:functionint int int int set<int> int set<int> for downto if else return
Время работы
Время работы приведенного выше алгоритма —
.См. также
Источники информации
- P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 26 - 28