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

Материал из Викиконспекты
Перейти к: навигация, поиск
(Алгоритм)
м (rollbackEdits.php mass rollback)
 
(не показано 7 промежуточных версий 3 участников)
Строка 7: Строка 7:
  
 
==Алгоритм==
 
==Алгоритм==
Чтобы получить оптимальное расписание, будем строить максимальное множество <tex>S</tex> тех работ, которые успеют выполниться. Само расписание тогда будет состоять из всех работ из <tex>S</tex>, упорядоченных по неубыванию дедлайнов.
 
Будем добавлять в <tex>S</tex> работы в порядке неубывания значений <tex>d_j</tex>, если успеваем их выполнить.
 
  
'''function''' <tex>\mathrm{schedule}</tex>(d: '''int[]'''): '''int[]'''  
+
===Описание алгоритма===
   S = <tex>\varnothing</tex>
+
Чтобы получить оптимальное расписание, будем строить максимальное множество <tex>S</tex> тех работ, которые успеют выполниться. Само расписание тогда будет состоять из всех работ из <tex>S</tex>, упорядоченных по неубыванию дедлайнов. Во время сортировки стоит учитывать, что дедлайны могут значительно превосходить количество задач. В таком случае необходимо предварительно пересчитать дедлайны по формуле <tex>d_i = \min\{d_i, n\}</tex> (в оптимальном расписании мы выполняем все работы до времени <tex>time=n</tex>). Для упорядочивания дедлайнов будем использовать  [[Карманная сортировка|карманную сортировку]].
   time = 0
+
 
 +
===Псевдокод===
 +
'''function''' schedule(d: '''int[n]'''): '''list<int>'''
 +
   '''list<int>''' S = <tex>\varnothing</tex>
 +
   '''int''' time = 0
 
   '''for''' i = 1 '''to''' n '''do'''
 
   '''for''' i = 1 '''to''' n '''do'''
     d[i] = min{d[i], n}
+
     d[i] = min(d[i], n)
   Сортиуем d подсчетом
+
   Сортиуем d
 
   '''for''' i = 1 '''to''' n '''do'''
 
   '''for''' i = 1 '''to''' n '''do'''
 
     '''if''' time < d[i]
 
     '''if''' time < d[i]
 
       S = S <tex>\cup</tex> {i}
 
       S = S <tex>\cup</tex> {i}
       time <code>+=</code> 1
+
       time += 1
'''return''' S
+
  '''return''' S
 
+
 
Cортировку работ по неубыванию дедлайнов осуществляем с помощью сортировки подсчетом за <tex>O(n)</tex>, а значит и весь алгоритм будет работать за <tex>O(n)</tex>.  
+
Во избежание лишнего копирования массивов, мы можем делать проход по массиву блоков (bucket'ов) и для каждого блока проходить по спискам работ внутри него. Начальное значение <tex> time = 0</tex>. После рассмотрения очередной работы мы будем добавлять ее в расписание и  увеличивать <tex> time</tex> на <tex>1</tex>. Тогда, если значение <tex> time</tex> становится равным номеру блока, то мы переходим к следующему блоку, а нерассмотренные задачи помечаем как просроченные и выполняем в конце. Работы с <tex>d_i = 0</tex> заранее отметим как просроченные.
Во время сортировки стоит учитывать, что дедлайны могут значительно превосходить количество задач. В таком случае необходимо предварительно пересчитать дедлайны по формуле <tex>d_i = \min\{d_i, n\}</tex> (в оптимальном расписании мы не выполняем работы позже времени <tex>t=n</tex>).
+
 
 +
===Время работы===
 +
Cортировку работ по неубыванию дедлайнов осуществляем с помощью карманной сортировки за <tex>O(n)</tex>, а значит и весь алгоритм будет работать за <tex>O(n)</tex>.  
 +
 
 +
===Корректность и оптимальность===
 +
В результате выполнения данного алгоритма будет получено корректное расписание, в котором каждая работа встречается не более одного раза. Вначале расписания будут стоять все работы, которые мы успеваем выполнить до дедлайна. Остальные работы дописываются в конец в произвольном порядке.  
  
В результате выполнения данного алгоритма будет получено корректное расписание, в котором каждая работа встречается не более одного раза. Оптимальность полученного расписания доказывается аналогично [[1sumwu|<tex>1 \mid  \mid \sum w_{i}U_{i}</tex>]].
+
Оптимальность полученного расписания доказывается аналогично [[1sumwu|<tex>1 \mid  \mid \sum w_{i}U_{i}</tex>]].
  
 
== См. также ==
 
== См. также ==

Текущая версия на 19:15, 4 сентября 2022

[math]1 \mid p_i=1\mid \sum U_i[/math]


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


Алгоритм

Описание алгоритма

Чтобы получить оптимальное расписание, будем строить максимальное множество [math]S[/math] тех работ, которые успеют выполниться. Само расписание тогда будет состоять из всех работ из [math]S[/math], упорядоченных по неубыванию дедлайнов. Во время сортировки стоит учитывать, что дедлайны могут значительно превосходить количество задач. В таком случае необходимо предварительно пересчитать дедлайны по формуле [math]d_i = \min\{d_i, n\}[/math] (в оптимальном расписании мы выполняем все работы до времени [math]time=n[/math]). Для упорядочивания дедлайнов будем использовать карманную сортировку.

Псевдокод

function schedule(d: int[n]): list<int>
  list<int> S = [math]\varnothing[/math]
  int time = 0
  for i = 1 to n do
    d[i] = min(d[i], n)
  Сортиуем d
  for i = 1 to n do
    if time < d[i]
      S = S [math]\cup[/math] {i}
      time += 1
  return S

Во избежание лишнего копирования массивов, мы можем делать проход по массиву блоков (bucket'ов) и для каждого блока проходить по спискам работ внутри него. Начальное значение [math] time = 0[/math]. После рассмотрения очередной работы мы будем добавлять ее в расписание и увеличивать [math] time[/math] на [math]1[/math]. Тогда, если значение [math] time[/math] становится равным номеру блока, то мы переходим к следующему блоку, а нерассмотренные задачи помечаем как просроченные и выполняем в конце. Работы с [math]d_i = 0[/math] заранее отметим как просроченные.

Время работы

Cортировку работ по неубыванию дедлайнов осуществляем с помощью карманной сортировки за [math]O(n)[/math], а значит и весь алгоритм будет работать за [math]O(n)[/math].

Корректность и оптимальность

В результате выполнения данного алгоритма будет получено корректное расписание, в котором каждая работа встречается не более одного раза. Вначале расписания будут стоять все работы, которые мы успеваем выполнить до дедлайна. Остальные работы дописываются в конец в произвольном порядке.

Оптимальность полученного расписания доказывается аналогично [math]1 \mid \mid \sum w_{i}U_{i}[/math].

См. также

Источники информации

  • Peter Brucker. «Scheduling Algorithms» — «Springer», 2006 г. — 86 стр. — ISBN 978-3-540-69515-8