1ripi1sumwc — различия между версиями
| Строка 64: | Строка 64: | ||
===Псевдокод=== | ===Псевдокод=== | ||
| + | |||
| + | ====Алгоритм 1==== | ||
<tex> S \leftarrow \{1 \ldots n\}</tex> | <tex> S \leftarrow \{1 \ldots n\}</tex> | ||
<tex> \mathtt{time} \leftarrow 0</tex> | <tex> \mathtt{time} \leftarrow 0</tex> | ||
| Строка 75: | Строка 77: | ||
<tex> \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{j}</tex> | <tex> \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{j}</tex> | ||
<tex> \mathtt{time++}</tex> | <tex> \mathtt{time++}</tex> | ||
| + | |||
| + | ====Алгоритм 2==== | ||
| + | Этот алгоритм реализован с помощью [[Двоичная_куча|двоичной кучи]] <tex>\mathtt{Heap}</tex> в которой операции вставки и извлечения выполняются за <tex>O(\log n)</tex>, а операция поиска максимального элемента за <tex>O(1)</tex> | ||
| + | <tex> S \leftarrow \{1 \ldots n\}</tex> | ||
| + | <tex> \mathtt{time} \leftarrow 0</tex> | ||
| + | <tex> \mathtt{answer} \leftarrow 0</tex> | ||
| + | '''for''' <tex>i \leftarrow 1 </tex> '''to''' <tex>n</tex> '''do''' | ||
| + | Heap.insert(<tex>w_i</tex>) | ||
| + | '''while''' <tex> S \neq \varnothing </tex> | ||
| + | <tex> j \leftarrow null </tex> | ||
| + | '''if''' <tex> i \in S</tex> '''and''' <tex> r_{i} \leqslant \mathtt{time}</tex> '''and''' <tex>w_i \geqslant </tex> Heap.Max() | ||
| + | <tex> j \leftarrow i </tex> | ||
| + | '''if''' <tex>j \neq null </tex> | ||
| + | <tex> S \leftarrow S \setminus j</tex> | ||
| + | Heap.extractMax() | ||
| + | <tex> \mathtt{Answer} \leftarrow \mathtt{Answer} + \mathtt{time} \cdot w_{j}</tex> | ||
| + | <tex> \mathtt{time++}</tex> | ||
| + | |||
| + | В начале алгоритма мы добавляем все элементы <tex>w_i</tex> в двоичную кучу тратя на это <tex>O(n \log n)</tex> времени. Затем мы тратим <tex>O(n \log n)</tex> на получение ответа. Тогда суммарное время работы алгоритма составит <tex>O(n \log n + n \log n)</tex> что равно <tex>O(n \log n)</tex> времени. | ||
===Сложность алгоритма=== | ===Сложность алгоритма=== | ||
Версия 16:52, 3 июня 2015
| Задача: |
| Дано работ и один станок. Для каждой работы известно её время появления и вес . Время выполнения всех работ равно . Требуется выполнить все работы, чтобы значение было минимальным, где — время окончания работы. |
Содержание
Более простые варианты исходной задачи
Перед решением основной задачи рассмотрим более простые.
Вариант 1
Этот случай простейший. Ответом будет , так как мы раз сложим время окончания выполнения одной работы. Воспользовавшись формулой суммы первых членов арифметической прогрессии алгоритм будет работает за .
Вариант 2
Для верного выполнения просто выставим работы по порядку невозрастания весов, тогда ответом будет , так как мы раз сложим время окончания выполнения одной работы (которое в нашем случае ) домноженное на вес этой работы. Вес работ отсортировали за . Алгоритм работает за
Вариант 3
— монотонная функция времени окончания работы для работ .
Нам нужно распределить работ в разное время. Если мы назначим время для работы то цена будет . Функция монотонно неубывающая, тогда работы в расписании надо располагать как можно раньше для получения верного решения. временных интервалов для работ могут быть получены с помощью следующего алгоритма, где предполагается что работы отсортированы так:
Псевдокод
for to do max
Этот алгоритм работает за
Основная задача
Описание алгоритма
Пусть — текущий момент времени.
Для каждого очередного значения , которое изменяется от до времени окончания последней работы, будем:
- Выбирать работу из множества невыполненных работ, у которой , а значение максимально.
- Если мы смогли найти работу , то выполняем её в момент времени и удаляем из множества невыполненных работ.
- Увеличиваем на один.
Доказательство корректности алгоритма
| Теорема: |
Расписание, построенное данным алгоритмом, является корректным и оптимальным. |
| Доказательство: |
|
Доказательство будем вести от противного. Первая скобка отрицательная: . Вторая скобка тоже отрицательная из того, что в работа с весом выполняется раньше, значит её вес должен быть больше . |
Псевдокод
Алгоритм 1
while if and and if
Алгоритм 2
Этот алгоритм реализован с помощью двоичной кучи в которой операции вставки и извлечения выполняются за , а операция поиска максимального элемента за
for to do Heap.insert() while if and and Heap.Max() if Heap.extractMax()
В начале алгоритма мы добавляем все элементы в двоичную кучу тратя на это времени. Затем мы тратим на получение ответа. Тогда суммарное время работы алгоритма составит что равно времени.
Сложность алгоритма
Множество станет пустым не позже, чем через шагов цикла. Определить максимум в множестве можно за время , используя , например, очередь с приоритетами. Значит общее время работы алгоритма
См. также
Источники информации
- P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 19-20
- P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 38-39
- P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 84-85
- Лазарев А.А., Мусатова Е.Г., Кварацхелия А.Г., Гафаров Е.Р. Пособие по теории расписаний.