R2Cmax — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
(Время работы)
Строка 2: Строка 2:
 
<includeonly>[[Категория: В разработке]]</includeonly>
 
<includeonly>[[Категория: В разработке]]</includeonly>
  
==Постановка задачи==
+
<tex dpi=200>R2 \mid\mid C_{max} </tex>
Дано два разных неоднородных станка, которые работают параллельно. Есть <tex>n</tex> работ, время выполнения которых на первом  
+
 
и втором станке различное. Нужно минимизировать время завершения всех работ.
+
{{Задача
 +
|definition=Дано два разных неоднородных станка, которые работают параллельно. Есть <tex>n</tex> работ, время выполнения которых на первом  
 +
и втором станке различное. Нужно минимизировать время завершения всех работ.}}
  
 
==Сложность задачи==
 
==Сложность задачи==
Строка 10: Строка 12:
  
 
==Неэффективное решение==
 
==Неэффективное решение==
Переберём все битовые последовательности из <tex>n</tex> элементов. Для каждой перестановки вычислим завершение последней работы. Работы будем выполнять следующим образом, если на <tex>i</tex>&nbsp;-й позиции стоит 0, то <tex>i</tex>&nbsp;-ая работа будет выполняться на первом станке, иначе на втором. Среди всех перестановок выберем ту перестановку, у которой <tex>C_{max}</tex> минимальный.
+
Переберём все битовые последовательности из <tex>n</tex> элементов. Для каждой перестановки вычислим завершение последней работы. Работы будем выполнять следующим образом, если на <tex>i</tex>&nbsp;-й позиции стоит <tex>0</tex>, то <tex>i</tex>&nbsp;-ая работа будет выполняться на первом станке, иначе на втором. Среди всех перестановок выберем ту перестановку, у которой <tex>C_{max}</tex> минимальный.
  
 
Время работы алгоритма <tex>O(n \cdot 2^n)</tex>
 
Время работы алгоритма <tex>O(n \cdot 2^n)</tex>
Строка 21: Строка 23:
 
Изначальное значение <tex>dp[0][0] = 0</tex>, а всё остальную таблицу проинициализируем бесконечностью.
 
Изначальное значение <tex>dp[0][0] = 0</tex>, а всё остальную таблицу проинициализируем бесконечностью.
  
Допустим мы посчитали динамику для <tex>i-1</tex> работ. Теперь надо пересчитать её для <tex>i</tex>-ой работы. Переберём время выполнения работ на первом станке и посчитаем какое минимально время выполнения мы можем получить при на втором станке при фиксированном первом времени. Так как <tex>i</tex>-ю работу мы можем выполнить либо на первом станке, либо на втором, то <tex>dp[i][j]=  \min(dp[i-1][j-p_1[i]], dp[i-1][j]+p_2[i])</tex>.
+
Допустим мы посчитали динамику для <tex>i</tex> работ. Теперь надо пересчитать её для <tex>(i + 1)</tex>-ой работы. Переберём время выполнения работ на первом станке и посчитаем какое минимально время выполнения мы можем получить при на втором станке при фиксированном первом времени. Так как <tex>(i + 1)</tex>-ю работу мы можем выполнить либо на первом станке, либо на втором, то <tex> dp[i + 1][j + p_1[i + 1]]</tex> надо прорелаксировать значением <tex>dp[i][j] </tex>, что соответсвует выполнению работы на первом станке. А <tex>dp[i + 1][j] </tex> релаксируем значением <tex> dp[i][j]+p_2[i + 1]</tex> (выполнение на втором станке).
  
 
Тогда ответом на задачу будет минимум среди всех максимумов из <tex>j</tex> и <tex>dp[n][j]</tex>.
 
Тогда ответом на задачу будет минимум среди всех максимумов из <tex>j</tex> и <tex>dp[n][j]</tex>.
 +
 +
Так же можно заметить, что во время каждой итерации алгоритма используется только два столбца массива <tex> dp </tex>. Это позволяет уменьшить использование памяти до <tex dpi=130> \sum{p_{1}[i]}</tex>.
  
 
==Псевдокод==
 
==Псевдокод==
   <tex>maxTime \leftarrow 0 </tex>
+
   <tex>maxTime = 0 </tex>
   for <tex>i = 1 \dots n</tex>
+
   '''for''' <tex>i = 0 \dots n - 1</tex>
 
       <tex>maxTime += p_1[i]</tex>
 
       <tex>maxTime += p_1[i]</tex>
   <tex>dp[][] \leftarrow INF</tex>
+
   <tex>dp[][] = INF</tex>
   <tex>dp[0][0] \leftarrow 0 </tex>
+
   <tex>dp[0][0] = 0 </tex>
   for <tex>i = 1 \dots n</tex>
+
   '''for''' <tex>i = 0 \dots n - 1 </tex>
       for <tex>j = 0 \dots maxTime </tex>
+
       '''for''' <tex>j = 0 \dots maxTime </tex>
         if <tex>(j - p_2[i] > 0) </tex> then
+
         '''if''' <tex> (dp[i + 1][j + p_{1}[i]] > dp[i][j]) </tex> '''then'''
             <tex>dp[i][j] \leftarrow \min (dp[i][j], dp[i-1][j - p_1[i]) </tex>
+
             <tex> dp[i + 1][j + p_{1}[i]] = dp[i][j] </tex>
         <tex>dp[i][j] \leftarrow \min (dp[i][j], dp[i-1][j] + p_2[i])</tex>
+
         '''if''' <tex>(dp[i + 1][j] > dp[i][j] + p_{2}[i]) </tex> '''then'''
   <tex>answer \leftarrow INF</tex>
+
            <tex> dp[i + 1][j] = dp[i][j] + p_{2}[i] </tex>
 +
   <tex>answer = INF</tex>
 
   for <tex> j = 0 \dots maxTime </tex>
 
   for <tex> j = 0 \dots maxTime </tex>
       <tex>answer \leftarrow \min (answer, \max(j, dp[n][j]))</tex>
+
       <tex>answer = \min (answer, \max(j, dp[n][j]))</tex>
  
 
==Время работы==
 
==Время работы==
Строка 47: Строка 52:
 
of machine scheduling problems. Annals of Discrete Mathematics,
 
of machine scheduling problems. Annals of Discrete Mathematics,
 
1:343–362, 1977.
 
1:343–362, 1977.
 +
 +
[[Категория: Алгоритмы и структуры данных]]
 +
[[Категория: Теория расписаний]]

Версия 04:03, 22 мая 2016

Эта статья находится в разработке!


[math]R2 \mid\mid C_{max} [/math]


Задача:
Дано два разных неоднородных станка, которые работают параллельно. Есть [math]n[/math] работ, время выполнения которых на первом и втором станке различное. Нужно минимизировать время завершения всех работ.


Сложность задачи

Задача [math]R2 \mid \mid C_{max}[/math] является [math]\mathrm{NP}[/math]-полной задачей.

Неэффективное решение

Переберём все битовые последовательности из [math]n[/math] элементов. Для каждой перестановки вычислим завершение последней работы. Работы будем выполнять следующим образом, если на [math]i[/math] -й позиции стоит [math]0[/math], то [math]i[/math] -ая работа будет выполняться на первом станке, иначе на втором. Среди всех перестановок выберем ту перестановку, у которой [math]C_{max}[/math] минимальный.

Время работы алгоритма [math]O(n \cdot 2^n)[/math]

Эффективное решение

Применим для решения данной задачи динамическое программирование.

Будем считать [math]dp[i][j][/math], в котором будем хранить минимально время выполнения работ на втором станке, где [math]i[/math] означает, что мы рассмотрели [math]i[/math] работ, а [math]j[/math] с каким временем выполнения работ на первом станке. Тогда [math]j[/math] не превосходит суммы выполнения работ на первом станке.

Изначальное значение [math]dp[0][0] = 0[/math], а всё остальную таблицу проинициализируем бесконечностью.

Допустим мы посчитали динамику для [math]i[/math] работ. Теперь надо пересчитать её для [math](i + 1)[/math]-ой работы. Переберём время выполнения работ на первом станке и посчитаем какое минимально время выполнения мы можем получить при на втором станке при фиксированном первом времени. Так как [math](i + 1)[/math]-ю работу мы можем выполнить либо на первом станке, либо на втором, то [math] dp[i + 1][j + p_1[i + 1]][/math] надо прорелаксировать значением [math]dp[i][j] [/math], что соответсвует выполнению работы на первом станке. А [math]dp[i + 1][j] [/math] релаксируем значением [math] dp[i][j]+p_2[i + 1][/math] (выполнение на втором станке).

Тогда ответом на задачу будет минимум среди всех максимумов из [math]j[/math] и [math]dp[n][j][/math].

Так же можно заметить, что во время каждой итерации алгоритма используется только два столбца массива [math] dp [/math]. Это позволяет уменьшить использование памяти до [math] \sum{p_{1}[i]}[/math].

Псевдокод

  [math]maxTime = 0 [/math]
  for [math]i = 0 \dots n - 1[/math]
     [math]maxTime += p_1[i][/math]
  [math]dp[][] = INF[/math]
  [math]dp[0][0] = 0 [/math]
  for [math]i = 0 \dots n - 1 [/math]
     for [math]j = 0 \dots maxTime [/math]
        if [math] (dp[i + 1][j + p_{1}[i]] \gt  dp[i][j]) [/math] then
           [math] dp[i + 1][j + p_{1}[i]] = dp[i][j] [/math]
        if [math](dp[i + 1][j] \gt  dp[i][j] + p_{2}[i]) [/math] then
           [math] dp[i + 1][j] = dp[i][j] + p_{2}[i] [/math]
  [math]answer = INF[/math]
  for [math] j = 0 \dots maxTime [/math]
     [math]answer = \min (answer, \max(j, dp[n][j]))[/math]

Время работы

Время работы [math]O(n \cdot maxTime)[/math] — псевдополиномиальный алгоритм. Кроме того, если время выполнения работ, будет вещественные числа, то придется приводить их до целых, либо считать приблежённое значения.

Литература

J.K. Lenstra, A.H.G. Rinnooy Kan, and P. Brucker. Complexity of machine scheduling problems. Annals of Discrete Mathematics, 1:343–362, 1977.