Изменения

Перейти к: навигация, поиск

QpmtnSumCi

8193 байта добавлено, 01:07, 30 мая 2016
лемма
|definition=
Дано <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=
В разработке
}}
Анонимный участник

Навигация