QpmtnSumCi — различия между версиями
Eadm (обсуждение | вклад) |
м (rollbackEdits.php mass rollback) |
||
(не показаны 4 промежуточные версии 2 участников) | |||
Строка 10: | Строка 10: | ||
=== Псевдокод === | === Псевдокод === | ||
− | '''function''' scheduling(p: '''int'''[n], v: '''int'''[n]) -> ''' | + | Алгоритм принимает на вход два массива {{---}} массив с объемами работ и массив скоростей обработки станков, и возвращает вектор четвёрок, где первый элемент является номером станка, второй {{---}} номером работы, а два оставшихся время начала и окончания обработки этой работы на этом станке. |
− | '''int''' | + | '''function''' scheduling(p: '''int'''[n], v: '''int'''[n]) -> '''vector<int, int, int, int>''' |
− | ''' | + | '''int''' time = 0 <font color=green>// текущее время на всех станках</font> |
+ | '''vector<int, int, int, int>''' ans <font color=green> // вектор, куда будет записан ответ</font> | ||
sort(p) <font color=green>// сортируем времена обработки работ в невозрастающем порядке</font> | sort(p) <font color=green>// сортируем времена обработки работ в невозрастающем порядке</font> | ||
sort(v) <font color=green>// сортируем скорости обработки станков в невозрастающем порядке</font> | sort(v) <font color=green>// сортируем скорости обработки станков в невозрастающем порядке</font> | ||
'''while''' p[1] > 0 | '''while''' p[1] > 0 | ||
Находим наибольший i такой, что p[i] > 0 | Находим наибольший i такой, что p[i] > 0 | ||
− | '''int''' | + | '''int''' dt = p[i] / v[1] <font color=green>// время обработки самой короткой доступной задачи на самом быстром станке</font> |
'''for''' j = i '''downto''' k = max(1, i - m + 1) | '''for''' j = i '''downto''' k = max(1, i - m + 1) | ||
− | ans | + | ans.push(1 + i - j, j, time, time + dt) <font color=green>// Назначаем на станок <tex>M_{1+i-j}</tex> работу j на время от time до time + dt</font> |
− | p[j] = p[j] - | + | p[j] = p[j] - dt * v[1 + i - j] <font color=green>// уменьшаем количество обработки, оставшейся для j-ой работы</font> |
− | + | time = time + dt <font color=green>// обновляем текущее время</font> | |
− | return ans | + | '''return''' ans |
=== Асимптотика === | === Асимптотика === | ||
− | Сначала мы сортируем работы и станки, что занимает <tex> \mathcal{O}(n\log{n})</tex> и <tex> \mathcal{O}(m\log{m})</tex>. Так как | + | Сначала мы сортируем работы и станки, что занимает <tex> \mathcal{O}(n\log{n})</tex> и <tex> \mathcal{O}(m\log{m})</tex>. Так как при <tex>m \geqslant n</tex>, <tex>m - n</tex> самых медленных станков можно не использовать, то в итоге сортировка займет <tex> \mathcal{O}(n\log{n})</tex>. |
Количество прерываний ограничено числом <tex>(m-1) \cdot n - (1 + 2 + \ldots + (m - 1)) = (m - 1) \cdot (n - \cfrac{m}{2})</tex>. | Количество прерываний ограничено числом <tex>(m-1) \cdot n - (1 + 2 + \ldots + (m - 1)) = (m - 1) \cdot (n - \cfrac{m}{2})</tex>. | ||
В итоге всё вместе составляет асимптотику алгоритма <tex> \mathcal{O}(n\log{n} + mn)</tex>. | В итоге всё вместе составляет асимптотику алгоритма <tex> \mathcal{O}(n\log{n} + mn)</tex>. |
Текущая версия на 19:26, 4 сентября 2022
Задача: |
Дано | станков с разной скоростью выполнения работ и работ с заданным временем выполнения . Работы можно прерывать и продолжать их выполнение на другом станке. Необходимо построить такое расписание, чтобы суммарное время окончания всех работ было минимальным.
Содержание
Описание алгоритма
Идея
Для решения применим правило SRPT-FM (Shortest Remaining Processing Time on Fastest Machine), которое предлагает класть работу с наименьшим оставшемся временем обработки на самый быстрый доступный станок. Отсортируем работы по времени обработки в невозрастающем порядке так, что
. Отсортируем станки по скорости обработки в невозрастающем порядке, так чтобы . Далее назначаем -ю работу на станок (1-й по скорости станок) на время , то есть пока она полностью не выполнится. Теперь назначим работу сначала станок на время , а затем на время от до на станок , пока она не завершится. С работой поступаем аналогично, сначала она времени выполняется на станке , затем времени на станке , и, начиная с до , на станке . Также поступаем со всеми оставшимися работами.Псевдокод
Алгоритм принимает на вход два массива — массив с объемами работ и массив скоростей обработки станков, и возвращает вектор четвёрок, где первый элемент является номером станка, второй — номером работы, а два оставшихся время начала и окончания обработки этой работы на этом станке.
function scheduling(p: int[n], v: int[n]) -> vector<int, int, int, int>
int time = 0 // текущее время на всех станках
vector<int, int, int, int> ans // вектор, куда будет записан ответ
sort(p) // сортируем времена обработки работ в невозрастающем порядке
sort(v) // сортируем скорости обработки станков в невозрастающем порядке
while p[1] > 0
Находим наибольший i такой, что p[i] > 0
int dt = p[i] / v[1] // время обработки самой короткой доступной задачи на самом быстром станке
for j = i downto k = max(1, i - m + 1)
ans.push(1 + i - j, j, time, time + dt) // Назначаем на станок
работу j на время от time до time + dt
p[j] = p[j] - dt * v[1 + i - j] // уменьшаем количество обработки, оставшейся для j-ой работы
time = time + dt // обновляем текущее время
return ans
Асимптотика
Сначала мы сортируем работы и станки, что занимает
и . Так как при , самых медленных станков можно не использовать, то в итоге сортировка займет . Количество прерываний ограничено числом . В итоге всё вместе составляет асимптотику алгоритма .Доказательство корректности алгоритма
Лемма: |
Существует оптимальное расписание, в котором , когда , для всех и . |
Доказательство: |
Рассмотрим расписание , где для некоторых и верно, что , но . С помощью обмена частей обработки, полученной работами и , мы можем изменить расписание , получив новое оптимальное расписание , где обработка работ и завершается во времена и соответственно, при этом время завершения обработки остальных работ остается прежним. Тот факт, что в расписании работа заканчивается раньше , при этом не нарушая оптимальности расписания, свидетельствует о существовании расписания, описанного в условии леммы.Для построения расписания из расписания введем следующие обозначения:
Далее существуют два случая:
|
Теорема: |
Расписание, построенное по принципу SRPT-FM, оптимальное для задачи . |
Доказательство: |
Без потери общности будем предполагать, что количество станков равно количеству работ . Если , то добавим станков с нулевой скоростью обработки, если , то удалим самых медленных станков.Пусть у нас есть расписание, построенное по правилу SRPT-FM, тогда . Следовательно, верны следующие равенства:Проведем математические преобразования и получим следующие равенства: Пусть оптимальное расписание, по предыдущей лемме верно, что . Самая короткая работа не может быть выполнена раньше, чем . Таким образом илиТак как работы и выполнены к моменту и соответственно, то максимальное количество обработки, полученной этими работами составляетИз чего следует, что Продолжая в том же духе можно показать, что В итоге получаем следующие неравенства Если существует такой набор положительных чисел , что умножение -го неравенства на и сложение всех неравенств будет давать неравенство , тогда теорема будет доказана. Можно показать, что должны удовлетворять следующим равенствам |
См. также
Источники информации
- Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 134-135 ISBN 978-3-540-69515-8
- Dimitrios G. Pandelis "Optimal preemptive scheduling on uniform machines with discounted flowtime objectives" — с. 631-632
- M.L. Pinedo "Parallel Machine Models (Deterministic)" — с.135-136