R2Cmax — различия между версиями
Novik (обсуждение | вклад) |
Novik (обсуждение | вклад) |
||
| Строка 1: | Строка 1: | ||
| − | |||
| − | |||
| − | |||
<tex dpi=200>R2 \mid\mid C_{max} </tex> | <tex dpi=200>R2 \mid\mid C_{max} </tex> | ||
| Строка 8: | Строка 5: | ||
и втором станке различное. Нужно минимизировать время завершения всех работ.}} | и втором станке различное. Нужно минимизировать время завершения всех работ.}} | ||
| − | + | Задача <tex>R2 \mid \mid C_{max}</tex> является <tex>\mathrm{NP}</tex>-полной задачей. Доказательство смотри в книге, указанной в источниках информации. | |
| − | Задача <tex>R2 \mid \mid C_{max}</tex> является <tex>\mathrm{NP}</tex>-полной задачей. | ||
==Неэффективное решение== | ==Неэффективное решение== | ||
| − | Переберём все битовые | + | Переберём все битовые маски длины <tex>n</tex>. Для каждой маски вычислим завершение последней работы. Работы будем выполнять следующим образом, если на <tex>i</tex> -й позиции стоит <tex>0</tex>, то <tex>i</tex> -ая работа будет выполняться на первом станке, иначе на втором. Среди всех масок выберем ту, у которой <tex>C_{max}</tex> минимальный. |
Время работы алгоритма <tex>O(n \cdot 2^n)</tex> | Время работы алгоритма <tex>O(n \cdot 2^n)</tex> | ||
==Эффективное решение== | ==Эффективное решение== | ||
| − | Применим для решения данной задачи динамическое программирование. | + | Применим для решения данной задачи [[Динамическое программирование|динамическое программирование]]. |
| − | Будем считать <tex>dp[i][j]</tex>, в котором будем хранить минимально время выполнения работ на втором станке, где <tex>i</tex> означает, что мы рассмотрели <tex>i</tex> работ, а <tex>j</tex> с каким временем выполнения работ на первом станке. Тогда <tex>j</tex> не превосходит суммы выполнения работ на первом станке. | + | Будем считать массив <tex>dp[i][j]</tex>, в котором будем хранить минимально время выполнения работ на втором станке, где <tex>i</tex> означает, что мы рассмотрели <tex>i</tex> работ, а <tex>j</tex> с каким временем выполнения работ на первом станке. Тогда <tex>j</tex> не превосходит суммы выполнения работ на первом станке. |
Изначальное значение <tex>dp[0][0] = 0</tex>, а всё остальную таблицу проинициализируем бесконечностью. | Изначальное значение <tex>dp[0][0] = 0</tex>, а всё остальную таблицу проинициализируем бесконечностью. | ||
| Строка 27: | Строка 23: | ||
Тогда ответом на задачу будет минимум среди всех максимумов из <tex>j</tex> и <tex>dp[n][j]</tex>. | Тогда ответом на задачу будет минимум среди всех максимумов из <tex>j</tex> и <tex>dp[n][j]</tex>. | ||
| − | Так же можно заметить, что во время каждой итерации алгоритма используется только два столбца массива <tex> dp </tex>. Это позволяет уменьшить использование памяти до <tex dpi=130> \sum{ | + | Так же можно заметить, что во время каждой итерации алгоритма используется только два столбца массива <tex> dp </tex>. Это позволяет уменьшить использование памяти до <tex dpi=130> O(\sum\limits_{i = 1}^{n} p_1[i])</tex>. |
| + | |||
| + | ==Доказательство корректности алгоритма== | ||
| + | |||
| + | {{Теорема | ||
| + | |statement= | ||
| + | Расписание, построенное данным алгоритмом, является корректным и оптимальным. | ||
| + | |proof= | ||
| + | Корректность расписания, составленного алгоритмом очевидна. Надо доказать его оптимальность. | ||
| − | |||
Пусть расписание, составленное этим алгоритмом <tex>S</tex> не оптимальное. Пусть в конце работы алгоритма минимум достигается в <tex>\max(time, d[n][time])</tex>. Рассмотрим оптимальное решение <tex>O</tex>. | Пусть расписание, составленное этим алгоритмом <tex>S</tex> не оптимальное. Пусть в конце работы алгоритма минимум достигается в <tex>\max(time, d[n][time])</tex>. Рассмотрим оптимальное решение <tex>O</tex>. | ||
| Строка 37: | Строка 40: | ||
В итоге если превратить решение <tex>S</tex> в решение <tex>S'</tex> эквивалентное <tex>O</tex>, то ответ <tex>S</tex> не будет превосходить ответ <tex>S'</tex>. Тогда расписание <tex>S</tex> оптимальное. | В итоге если превратить решение <tex>S</tex> в решение <tex>S'</tex> эквивалентное <tex>O</tex>, то ответ <tex>S</tex> не будет превосходить ответ <tex>S'</tex>. Тогда расписание <tex>S</tex> оптимальное. | ||
| + | }} | ||
==Псевдокод== | ==Псевдокод== | ||
| − | + | <font color=green>//Функция принимает количество работ n, список времён выполнения работ на первом станке p1 и времён выполнения на втором станке p2.<br>//Функция возвращает минимальное время выполнения всех работ на двух станках.</font> | |
| − | '''for''' | + | '''function''' getCmax(n, p1, p2) |
| − | + | maxTime = 0 | |
| − | + | '''for''' i = 0 .. n - 1 | |
| − | + | maxTime += p1[i] | |
| − | + | dp[][] = INF | |
| − | + | dp[0][0] = 0 | |
| − | + | '''for''' i = 0 .. n - 1 | |
| − | + | '''for''' j = 0 .. maxTime | |
| − | + | '''if''' dp[i + 1][j + p1[i]] > dp[i][j]: | |
| − | + | dp[i + 1][j + p1[i]] = dp[i][j] | |
| − | + | '''if''' dp[i + 1][j] > dp[i][j] + p2[i]: | |
| − | + | dp[i + 1][j] = dp[i][j] + p2[i] | |
| − | + | answer = INF | |
| − | + | for j = 0 .. maxTime | |
| + | answer = '''min'''(answer, '''max'''(j, dp[n][j])) | ||
| + | '''return''' answer | ||
==Время работы== | ==Время работы== | ||
Время работы <tex>O(n \cdot maxTime)</tex> {{---}} псевдополиномиальный алгоритм. Кроме того, если время выполнения работ, будет вещественные числа, то придется приводить их до целых, либо считать приблежённое значения. | Время работы <tex>O(n \cdot maxTime)</tex> {{---}} псевдополиномиальный алгоритм. Кроме того, если время выполнения работ, будет вещественные числа, то придется приводить их до целых, либо считать приблежённое значения. | ||
| − | == | + | ==Источники информации== |
| − | J.K. Lenstra, A.H.G. Rinnooy Kan, and P. Brucker. Complexity | + | * J.K. Lenstra, A.H.G. Rinnooy Kan, and P. Brucker. Complexity of machine scheduling problems. Annals of Discrete Mathematics, 1:343–362, 1977. |
| − | of machine scheduling problems. Annals of Discrete Mathematics, | + | |
| − | 1:343–362, 1977. | + | ==См. также== |
| + | * [[F2Cmax|<tex>F2\mid\mid C_{max}</tex>]] | ||
| + | * [[O2Cmax|<tex>O2\mid\mid C_{max}</tex>]] | ||
[[Категория: Алгоритмы и структуры данных]] | [[Категория: Алгоритмы и структуры данных]] | ||
[[Категория: Теория расписаний]] | [[Категория: Теория расписаний]] | ||
Версия 15:02, 22 мая 2016
| Задача: |
| Дано два разных неоднородных станка, которые работают параллельно. Есть работ, время выполнения которых на первом и втором станке различное. Нужно минимизировать время завершения всех работ. |
Задача является -полной задачей. Доказательство смотри в книге, указанной в источниках информации.
Содержание
Неэффективное решение
Переберём все битовые маски длины . Для каждой маски вычислим завершение последней работы. Работы будем выполнять следующим образом, если на -й позиции стоит , то -ая работа будет выполняться на первом станке, иначе на втором. Среди всех масок выберем ту, у которой минимальный.
Время работы алгоритма
Эффективное решение
Применим для решения данной задачи динамическое программирование.
Будем считать массив , в котором будем хранить минимально время выполнения работ на втором станке, где означает, что мы рассмотрели работ, а с каким временем выполнения работ на первом станке. Тогда не превосходит суммы выполнения работ на первом станке.
Изначальное значение , а всё остальную таблицу проинициализируем бесконечностью.
Допустим мы посчитали динамику для работ. Теперь надо пересчитать её для -ой работы. Переберём время выполнения работ на первом станке и посчитаем какое минимально время выполнения мы можем получить при на втором станке при фиксированном первом времени. Так как -ю работу мы можем выполнить либо на первом станке, либо на втором, то надо прорелаксировать значением , что соответсвует выполнению работы на первом станке. А релаксируем значением (выполнение на втором станке).
Тогда ответом на задачу будет минимум среди всех максимумов из и .
Так же можно заметить, что во время каждой итерации алгоритма используется только два столбца массива . Это позволяет уменьшить использование памяти до .
Доказательство корректности алгоритма
| Теорема: |
Расписание, построенное данным алгоритмом, является корректным и оптимальным. |
| Доказательство: |
|
Корректность расписания, составленного алгоритмом очевидна. Надо доказать его оптимальность. Пусть расписание, составленное этим алгоритмом не оптимальное. Пусть в конце работы алгоритма минимум достигается в . Рассмотрим оптимальное решение . Рассмотрим произвольную работу, выполненную на первом станке в оптимальном расписании, но на втором в расписании, составленном алгоритмом. Пусть у этой работы номер . Если её выполнить на первом станке, то время окончания всех работ будет . Однако Рассмотрим произвольную работу, выполненную в оптимальном расписании на втором станке, но на первом в расписании, составленном алгоритмом. Пусть номер этой работы . Если выполнять эту работу на втором станке, то время выполнения всех работ будет . Но . В итоге если превратить решение в решение эквивалентное , то ответ не будет превосходить ответ . Тогда расписание оптимальное. |
Псевдокод
//Функция принимает количество работ n, список времён выполнения работ на первом станке p1 и времён выполнения на втором станке p2.
//Функция возвращает минимальное время выполнения всех работ на двух станках. function getCmax(n, p1, p2) maxTime = 0 for i = 0 .. n - 1 maxTime += p1[i] dp[][] = INF dp[0][0] = 0 for i = 0 .. n - 1 for j = 0 .. maxTime if dp[i + 1][j + p1[i]] > dp[i][j]: dp[i + 1][j + p1[i]] = dp[i][j] if dp[i + 1][j] > dp[i][j] + p2[i]: dp[i + 1][j] = dp[i][j] + p2[i] answer = INF for j = 0 .. maxTime answer = min(answer, max(j, dp[n][j])) return answer
Время работы
Время работы — псевдополиномиальный алгоритм. Кроме того, если время выполнения работ, будет вещественные числа, то придется приводить их до целых, либо считать приблежённое значения.
Источники информации
- J.K. Lenstra, A.H.G. Rinnooy Kan, and P. Brucker. Complexity of machine scheduling problems. Annals of Discrete Mathematics, 1:343–362, 1977.