QpmtnSumCi — различия между версиями
Eadm (обсуждение | вклад) |
(лемма) |
||
Строка 3: | Строка 3: | ||
|definition= | |definition= | ||
Дано <tex>m</tex> станков с разной скоростью выполнения работ <tex>v_j</tex> и <tex>n</tex> работ с заданным временем выполнения <tex>p_i</tex>. Работы можно прерывать и продолжать их выполнение на другом станке. Необходимо построить такое расписание, чтобы суммарное время окончания всех работ было минимальным. | Дано <tex>m</tex> станков с разной скоростью выполнения работ <tex>v_j</tex> и <tex>n</tex> работ с заданным временем выполнения <tex>p_i</tex>. Работы можно прерывать и продолжать их выполнение на другом станке. Необходимо построить такое расписание, чтобы суммарное время окончания всех работ было минимальным. | ||
+ | }} | ||
+ | == Описание алгоритма == | ||
+ | [[Файл:QpmtnSumCi example.png|320px|thumb|right|Пример работы алгоритма]] | ||
+ | === Идея === | ||
+ | Для решения применим правило '''SRPT-FM''' (Shortest Remaining Processing Time on Fastest Machine), которое предлагает класть работу с наименьшим оставшемся временем обработки на самый быстрый доступный станок. Отсортируем работы по времени обработки в невозрастающем порядке так, что <tex>p_1 \ge p_2 \ge ... \ge p_n</tex>. Отсортируем станки по скорости обработки в невозрастающем порядке, так чтобы <tex>v_1 \ge v_2 \ge ... \ge v_m</tex>. Далее назначаем <tex>n</tex>-ю работу на станок <tex>M_1</tex> (1-й по скорости станок) на время <tex>t_1 = \cfrac{p_n}{v_1}</tex>, то есть пока она полностью не выполнится. Теперь назначим <tex>n-1</tex> работу сначала станок <tex>M_2</tex> на время <tex>t_1</tex>, а затем на время от <tex>t_1</tex> до <tex>t_2 \ge t_1</tex> на станок <tex>M_1</tex>, пока она не завершится. С <tex>n-2</tex> работой поступаем аналогично, сначала она <tex>t_1</tex> времени выполняется на станке <tex>M_3</tex>, затем <tex>t_2 - t_1</tex> времени на станке <tex>M_2</tex>, и, начиная с <tex>t_2</tex> до <tex>t_3 \ge t_2</tex>, на станке <tex>M_1</tex>. Также поступаем со всеми оставшимися работами. | ||
+ | |||
+ | === Псевдокод === | ||
+ | a = 0 | ||
+ | p[] // массив времен обработки работ отсортированный в невозрастающем порядке | ||
+ | v[] // массив скоростей обработки станков отсортированный в невозрастающем порядке | ||
+ | '''while''' p[1] > 0 | ||
+ | Находим наибольший i такой, что p[i] > 0 | ||
+ | t = p[i] / v[1] | ||
+ | '''for''' j = i '''down to''' k = max(1, i - m + 1) | ||
+ | Назначаем работу j на станок <tex>M_{1+i-j}</tex> на время от a до a + t | ||
+ | p[j] = p[j] - t * v[1 + i - j] | ||
+ | a = a + t | ||
+ | |||
+ | Сложность алгоритма составляет <tex> \mathcal{O}(n\log{n} + mn)</tex>. | ||
+ | |||
+ | == Доказательство корректности алгоритма == | ||
+ | {{Лемма | ||
+ | |statement= | ||
+ | Существует оптимальное расписание, в котором <tex>C_j \le C_k</tex>, когда <tex>p_j \le p_k</tex>, для всех <tex>j</tex> и <tex>k</tex> | ||
+ | |proof= | ||
+ | Рассмотрим расписание <tex>S</tex>, где для некоторых <tex>j</tex> и <tex>k</tex> верно, что <tex>C_j > C_k</tex>, но <tex>p_j \le p_k</tex>. С помощью обмена частей обработки, полученной работами <tex>j</tex> и <tex>k</tex>, мы можем изменить расписание <tex>S</tex>, получив новое оптимальное расписание <tex>S'</tex>, где обработка работ <tex>j</tex> и <tex>k</tex> завершается во времена <tex>C'_j \le C_k</tex> и <tex>C'_k = C_j</tex> соответственно, при этом время завершения обработки остальных работ остается прежним. Тот факт, что в расписании <tex>S'</tex> работа <tex>j</tex> заканчивается раньше <tex>k</tex>, при этом не нарушая оптимальности расписания, свидетельствует о существовании расписания, описанного в условии леммы. | ||
+ | |||
+ | Для построения расписания <tex>S'</tex> из расписания <tex>S</tex> введем следующие обозначения: | ||
+ | * <tex>p^1_j</tex>, <tex>p^1_k</tex> {{---}} количество обработки, полученной одновременно <tex>j</tex> и <tex>k</tex>, когда работа <tex>j</tex> была на более быстром станке или обе работы были на одинаковых станках. | ||
+ | * <tex>p^2_j</tex>, <tex>p^2_k</tex> {{---}} количество обработки, полученной одновременно <tex>j</tex> и <tex>k</tex>, когда работа <tex>k</tex> была на более быстром станке. | ||
+ | * <tex>p^3_j</tex>, <tex>p^3_k</tex> {{---}} количество обработки, полученной <tex>j</tex> и <tex>k</tex> до момента <tex>C_k</tex> на непересекающихся участках времени. | ||
+ | * <tex>p^+_j</tex> {{---}} количество обработки, полученной <tex>j</tex> после момента <tex>C_k</tex>. | ||
+ | |||
+ | Далее существуют два случая: | ||
+ | * Если <tex>p^+_j \le p^3_k</tex>, то расписание <tex>S'</tex> получается обменом обработки, полученной <tex>j</tex> после момента <tex>C_k</tex> с частью обработки, полученной <tex>k</tex> не одновременно с <tex>j</tex>. | ||
+ | * Если <tex>p^+_j > p^3_k</tex>, то для начала обмениваем всю обработку <tex>p^3_k</tex> с частью <tex>p^+_j</tex>, чтобы получить новое расписании, где <tex>C'_k = C_j</tex> и <tex>\tilde{p}^+_j = p^+_j - p^3_k</tex> обработки <tex>j</tex> после момента <tex>C_k</tex>. Пусть <tex>p^2_j</tex> и <tex>p^2_k</tex> представлены числом <tex>T</tex> непересекающихся временных интервалов длинной <tex>t_i</tex> с <tex>v^i_j</tex>, <tex>v^i_k</tex> {{---}} скоростями станков, обрабатывающих <tex>j</tex> и <tex>k</tex> в интервал <tex>i</tex> и <tex>p^{2,i}_j = v^i_j \cdot t_i</tex>, <tex>p^{2,i}_k = v^i_k \cdot t_i</tex> {{---}} количество обработки, полученной соответвующей задачей за этот интервал. Так как <tex>p^1_j \ge p^1_k</tex> и <tex>p_j \le p_k</tex>, то <tex>p^2_j + \tilde{p}^+_j \le p^2_k</tex>. Следовательно существует такой <tex>\tilde{p}^{+,i}_j</tex>, что верно:<br><tex>\sum\limits_{i=1}^{T}{\tilde{p}^{+,i}_j} = \tilde{p}^+_j</tex>, <tex>p^{2,i}_j + \tilde{p}^{+,i}_j \le p^{2,i}_k</tex>, <tex>i = 1...T</tex><br>Для каждого <tex>i = 1...T</tex> пусть <tex>t^i_j = \cfrac{\tilde{p}^{+,i}_j}{v^i_k - v^i_j}</tex>, <tex>t^i_k = t^i_j \cdot \cfrac{v^i_j}{v^i_k}</tex>. Чтобы получить расписание <tex>S'</tex> для каждого из <tex>T</tex> интервалов нужно обменять:<br> 1) обработку, полученную в начале интервала работой <tex>k</tex> на более быстром станке, с обработкой <tex>j</tex>, полученной на медленном станке, на интервалы <tex>t^i_k</tex> и <tex>t^i_j</tex> соответственно<br>2) обработку <tex>\tilde{p}^{+,i}_j</tex>, полученной <tex>j</tex> после момента <tex>C_k</tex>, с таким же количеством обработки, полученной работой <tex>k</tex> на более быстром станке в этот интервал сразу после момента <tex>t^i_k</tex>. | ||
+ | }} | ||
+ | |||
+ | {{Теорема | ||
+ | |statement= | ||
+ | Расписание, построенное по принципу '''SRPT-FM''', оптимальное для задачи <tex> Q \mid pmtn \mid \sum C_i </tex> | ||
+ | |proof= | ||
+ | В разработке | ||
}} | }} |
Версия 01:07, 30 мая 2016
Задача: |
Дано | станков с разной скоростью выполнения работ и работ с заданным временем выполнения . Работы можно прерывать и продолжать их выполнение на другом станке. Необходимо построить такое расписание, чтобы суммарное время окончания всех работ было минимальным.
Описание алгоритма
Идея
Для решения применим правило SRPT-FM (Shortest Remaining Processing Time on Fastest Machine), которое предлагает класть работу с наименьшим оставшемся временем обработки на самый быстрый доступный станок. Отсортируем работы по времени обработки в невозрастающем порядке так, что
. Отсортируем станки по скорости обработки в невозрастающем порядке, так чтобы . Далее назначаем -ю работу на станок (1-й по скорости станок) на время , то есть пока она полностью не выполнится. Теперь назначим работу сначала станок на время , а затем на время от до на станок , пока она не завершится. С работой поступаем аналогично, сначала она времени выполняется на станке , затем времени на станке , и, начиная с до , на станке . Также поступаем со всеми оставшимися работами.Псевдокод
a = 0
p[] // массив времен обработки работ отсортированный в невозрастающем порядке
v[] // массив скоростей обработки станков отсортированный в невозрастающем порядке
while p[1] > 0
Находим наибольший i такой, что p[i] > 0
t = p[i] / v[1]
for j = i down to k = max(1, i - m + 1)
Назначаем работу j на станок
на время от a до a + t
p[j] = p[j] - t * v[1 + i - j]
a = a + t
Сложность алгоритма составляет
.Доказательство корректности алгоритма
Лемма: |
Существует оптимальное расписание, в котором , когда , для всех и |
Доказательство: |
Рассмотрим расписание , где для некоторых и верно, что , но . С помощью обмена частей обработки, полученной работами и , мы можем изменить расписание , получив новое оптимальное расписание , где обработка работ и завершается во времена и соответственно, при этом время завершения обработки остальных работ остается прежним. Тот факт, что в расписании работа заканчивается раньше , при этом не нарушая оптимальности расписания, свидетельствует о существовании расписания, описанного в условии леммы.Для построения расписания из расписания введем следующие обозначения:
Далее существуют два случая:
|
Теорема: |
Расписание, построенное по принципу SRPT-FM, оптимальное для задачи |
Доказательство: |
В разработке |