1precpmtnrifmax — различия между версиями
Sementry (обсуждение | вклад) (→Blocks: +алгоритм) |
Sementry (обсуждение | вклад) (→Blocks: +доказательство) |
||
Строка 17: | Строка 17: | ||
=== Blocks === | === Blocks === | ||
Здесь и далее считается, что работы отсортированы в порядке неубывания модифицированных <tex> r_i </tex>. | Здесь и далее считается, что работы отсортированы в порядке неубывания модифицированных <tex> r_i </tex>. | ||
+ | |||
+ | Станок, выполняющий работы, выполняет работу в некоторые интервалы времени и простаивает в остальное время. Следующий алгоритм разбивает множество работ на блоки, внутри которых станок работает без простоя. | ||
Blocks(<tex> \{ 1 \ldots n \} </tex>) | Blocks(<tex> \{ 1 \ldots n \} </tex>) | ||
Строка 26: | Строка 28: | ||
6 <tex> j \leftarrow j + 1 </tex> | 6 <tex> j \leftarrow j + 1 </tex> | ||
7 <tex> B_j \leftarrow B_j \cup i </tex> | 7 <tex> B_j \leftarrow B_j \cup i </tex> | ||
− | 8 <tex> t \leftarrow </tex> | + | 8 <tex> t \leftarrow t + p_i </tex> |
+ | 9 return <tex> {B_1, \ldots, B_j} </tex> | ||
+ | |||
+ | Определим время начала блока <tex> B_j </tex> как <tex>s_j = \min\limits_{i \in B_j} r_i </tex>, а время конца — как <tex> e_j = s_j + \sum\limits_{i \in B_j} p_i </tex>. | ||
+ | |||
+ | {{Лемма | ||
+ | |statement= | ||
+ | Существует оптимальное расписание, такое, что все во все временные интервалы <tex> [s_j; e_j] </tex>, соответствующие блокам <tex> B_j </tex>, построенным алгоритмом Blocks, станок работает без простоя. | ||
+ | |proof= | ||
+ | Возьмем произвольное оптимальное расписание <tex> S </tex>, в нем деление на блоки может также быть произвольным. Найдем первый такой временной интервал <tex> [s_j; e_j] </tex>, что в <tex> S </tex> есть период простоя внутри <tex> [s_j; e_j] </tex> (если таких периодов несколько, будем рассматривать первый из них). Обозначим его за <tex> [s; e] </tex>. | ||
+ | |||
+ | Возьмем некоторую работу <tex> i </tex>, такую, что она начинается позже, чем в момент времени <tex> s </tex>, не имеет в графе зависимостей предков, завершаемых позже, чем в момент <tex> s </tex> и <tex> r_i \le s </tex>. Такая работа обязательно существует, иначе для множества работ, выполняемых позже, чем в момент <tex> s </tex>, было бы <tex> r = \min\limits{k \in T} r_k > s </tex>, и внутри блока <tex> B_j </tex> был бы простой <tex> [s_j; r] </tex>, что невозможно по построению алгоритма Blocks. Очевидно, мы можем начать выполнять ее в момент времени <tex> s </tex> и полностью, либо частично заполнить простой <tex> [s; e] </tex>; так как <tex> f_i </tex> — неубывающая функция, то ответ останется оптимальным. Повторяя этот процесс, мы за конечное число шагов придем к оптимальному расписанию с требуемым свойством. | ||
+ | }} | ||
=== Decompose === | === Decompose === |
Версия 22:12, 3 июня 2012
Содержание
Постановка задачи
Задача , но здесь у работ также есть времена появления, раньше которых их делать запрещено, и их можно прерывать.
является обобщениемАлгоритм
Работу будем обозначать просто ее номером (
), при этом, номера работ могут меняться в зависимости от того, по какому параметру они отсортированы. Время появления работы — , время, требуемое для ее выполнения — . Множество ребер графа обозначается как .Modify
Для начала, модифицируем времена появления работ. Если работа
зависит от , то, очевидно, она не может быть начата раньше, чем закончится выполнение </tex> i </tex>, поэтому нужно заменить на . Алгоритм, делающий это, представлен ниже (работы рассматриваются в порядке топологической сортировки):Modify() 1 for i2 for j: ij 3
После выполнения этого алгоритма для любых двух работ
, таких, что зависит от , выполняется , поэтому, при рассмотрении работ в порядке неубывания времен их появления, они также будут топологически отсортированы.Blocks
Здесь и далее считается, что работы отсортированы в порядке неубывания модифицированных
.Станок, выполняющий работы, выполняет работу в некоторые интервалы времени и простаивает в остальное время. Следующий алгоритм разбивает множество работ на блоки, внутри которых станок работает без простоя.
Blocks() 1 2 3 for 4 if 5 6 7 8 9 return
Определим время начала блока
как , а время конца — как .Лемма: |
Существует оптимальное расписание, такое, что все во все временные интервалы , соответствующие блокам , построенным алгоритмом Blocks, станок работает без простоя. |
Доказательство: |
Возьмем произвольное оптимальное расписание Возьмем некоторую работу , в нем деление на блоки может также быть произвольным. Найдем первый такой временной интервал , что в есть период простоя внутри (если таких периодов несколько, будем рассматривать первый из них). Обозначим его за . , такую, что она начинается позже, чем в момент времени , не имеет в графе зависимостей предков, завершаемых позже, чем в момент и . Такая работа обязательно существует, иначе для множества работ, выполняемых позже, чем в момент , было бы , и внутри блока был бы простой , что невозможно по построению алгоритма Blocks. Очевидно, мы можем начать выполнять ее в момент времени и полностью, либо частично заполнить простой ; так как — неубывающая функция, то ответ останется оптимальным. Повторяя этот процесс, мы за конечное число шагов придем к оптимальному расписанию с требуемым свойством. |
Decompose
Идея следующая: допустим, у нас есть блок работ, который можно выполнить без прерываний. Найдем работу
, которую выгодно выполнить последней. Разобъем оставшееся множество работ на блоки, решим задачу для этих блоков рекурсивно и вставим в промежутки между этими блоками, до них и после них, начиная с .Общий алгоритм
Выполним Modify(), после чего разобъем все множество работ на блоки и для каждого блока запустим Decompose():
MakeSchedule() 1 Modify() 2 BBlocks( ) 3 ans 4 for ( ): 5 ans = max(ans, Decompose( )) 6 return ans
Время работы
Теорема: |
Время работы алгоритма MakeSchedule() — операций. |
Доказательство: |
Обозначим за время, необходимое для выполнения алгоритма MakeSchedule() на n работах. Очевидно, для корректно определенной функции P в силу структуры алгоритма должно выполняться неравенство:
Здесь - размер блока с номером , построенного алгоритмом Blocks(). Заметим, что .Если , то имеем:
Так как , то можно переписать неравенство в следующем виде:
Чтобы получить максимальную нижнюю оценку на , оценим снизу :Так как Значит, при требуемое неравенство будет выполняться. |