1precpmtnrifmax — различия между версиями
Sementry (обсуждение | вклад) (pre-alpha-0.01 version) |
Sementry (обсуждение | вклад) (Добавил Modify и общий алгоритм.) |
||
| Строка 1: | Строка 1: | ||
| − | + | == Постановка задачи == | |
| + | Задача <tex> 1 \mid prec, pmtn, r_i \mid f_{max} </tex> является обобщением [[Правило Лаулера|<tex>1 \mid prec \mid f_{max}</tex>]], но здесь у работ также есть времена появления, раньше которых их делать запрещено, и их можно прерывать. | ||
== Алгоритм == | == Алгоритм == | ||
| + | Работу будем обозначать просто ее номером (<tex> i </tex>), при этом, номера работ могут меняться в зависимости от того, по какому параметру они отсортированы. Время появления работы — <tex> r_i </tex>, время, требуемое для ее выполнения — <tex> p_i </tex>. Множество ребер графа обозначается как <tex> E </tex>. | ||
| + | |||
| + | === Modify === | ||
| + | Для начала, модифицируем времена появления работ. Если работа <tex> j </tex> зависит от <tex> i </tex>, то, очевидно, она не может быть начата раньше, чем закончится выполнение </tex> i </tex>, поэтому нужно заменить <tex> r_j </tex> на <tex> \max(r_j, r_i + p_i) </tex>. Алгоритм, делающий это, представлен ниже (работы рассматриваются в порядке топологической сортировки): | ||
| + | |||
| + | Modify() | ||
| + | 1 '''for''' i <tex> \in \{ 1 \ldots n \} </tex> | ||
| + | 2 '''for''' j: ij <tex> \in E </tex> | ||
| + | 3 <tex> r_j \leftarrow \max(r_j, r_i + p_i) </tex> | ||
| + | |||
| + | После выполнения этого алгоритма для любых двух работ <tex> i, j </tex>, таких, что <tex> j </tex> зависит от <tex> i </tex>, выполняется <tex> r_j > r_i </tex>, поэтому, при рассмотрении работ в порядке неубывания времен их появления, они также будут топологически отсортированы. | ||
| + | |||
| + | === Blocks === | ||
| + | Здесь и далее считается, что работы отсортированы в порядке неубывания модифицированных <tex> r_i </tex>. | ||
| + | |||
| + | === Decompose === | ||
Идея следующая: допустим, у нас есть блок работ, который можно выполнить без прерываний. Найдем работу <tex>i</tex>, которую выгодно выполнить последней. Разобъем оставшееся множество работ на блоки, решим задачу для этих блоков рекурсивно и вставим <tex> i </tex> в промежутки между этими блоками, до них и после них, начиная с <tex> r_i </tex>. | Идея следующая: допустим, у нас есть блок работ, который можно выполнить без прерываний. Найдем работу <tex>i</tex>, которую выгодно выполнить последней. Разобъем оставшееся множество работ на блоки, решим задачу для этих блоков рекурсивно и вставим <tex> i </tex> в промежутки между этими блоками, до них и после них, начиная с <tex> r_i </tex>. | ||
| + | |||
| + | === Общий алгоритм === | ||
| + | |||
| + | Выполним Modify(), после чего разобъем все множество работ на блоки и для каждого блока запустим '''Decompose'''(): | ||
| + | |||
| + | <tex> 1 \mid prec, pmtn, r_i \mid f_{max} </tex>() | ||
| + | 1 Modify() | ||
| + | 2 B = '''Blocks(<tex> \{1 \ldots n \} </tex>) | ||
| + | 3 ans = - <tex> \infty </tex> | ||
| + | 4 for (<tex> B_i \in </tex> B): | ||
| + | 5 ans = <tex> \max </tex> (ans, '''Decompose'''(<tex> B_i </tex>)) | ||
| + | 6 return ans | ||
| + | |||
| + | == Время работы == | ||
| + | Лемма: время работы алгоритма <tex> 1 \mid prec, pmtn, r_i \mid f_{max} </tex> — <tex> O(n^2) </tex> операций. | ||
Версия 18:10, 3 июня 2012
Содержание
Постановка задачи
Задача является обобщением , но здесь у работ также есть времена появления, раньше которых их делать запрещено, и их можно прерывать.
Алгоритм
Работу будем обозначать просто ее номером (), при этом, номера работ могут меняться в зависимости от того, по какому параметру они отсортированы. Время появления работы — , время, требуемое для ее выполнения — . Множество ребер графа обозначается как .
Modify
Для начала, модифицируем времена появления работ. Если работа зависит от , то, очевидно, она не может быть начата раньше, чем закончится выполнение </tex> i </tex>, поэтому нужно заменить на . Алгоритм, делающий это, представлен ниже (работы рассматриваются в порядке топологической сортировки):
Modify() 1 for i 2 for j: ij 3
После выполнения этого алгоритма для любых двух работ , таких, что зависит от , выполняется , поэтому, при рассмотрении работ в порядке неубывания времен их появления, они также будут топологически отсортированы.
Blocks
Здесь и далее считается, что работы отсортированы в порядке неубывания модифицированных .
Decompose
Идея следующая: допустим, у нас есть блок работ, который можно выполнить без прерываний. Найдем работу , которую выгодно выполнить последней. Разобъем оставшееся множество работ на блоки, решим задачу для этих блоков рекурсивно и вставим в промежутки между этими блоками, до них и после них, начиная с .
Общий алгоритм
Выполним Modify(), после чего разобъем все множество работ на блоки и для каждого блока запустим Decompose():
() 1 Modify() 2 B = Blocks() 3 ans = - 4 for ( B): 5 ans = (ans, Decompose()) 6 return ans
Время работы
Лемма: время работы алгоритма — операций.