O2Cmax — различия между версиями
Zemskovk (обсуждение | вклад) м (→Источники информации) |
м (rollbackEdits.php mass rollback) |
||
(не показаны 2 промежуточные версии 2 участников) | |||
Строка 13: | Строка 13: | ||
# Рассмотрим два случая: | # Рассмотрим два случая: | ||
## <tex>a_{x} > b_{y}</tex>. Будем строить расписание с двух концов: | ## <tex>a_{x} > b_{y}</tex>. Будем строить расписание с двух концов: | ||
− | ##*Строим расписание слева: выполняем на первом станке все работы из <tex>I \setminus \{x\}</tex>, а на втором выполняем первой работу <tex>x</tex>, затем <tex>I \setminus \{x\}</tex>. | + | ##*Строим расписание слева: выполняем на первом станке все работы из <tex>I \setminus \{x\}</tex>, а на втором выполняем первой работу <tex>x</tex>, затем <tex>I \setminus \{x\}</tex> в том же порядке, что и на первом станке. |
##*Теперь, упираясь в правую границу, равную <tex> C_{max} </tex>, можно построить расписание справа: выполняем на первом станке все работы из <tex>J</tex>, затем <tex>x</tex>, а для второго выполняем работы из <tex>J</tex>.[[Файл:Picture2.gif|500px|center]] | ##*Теперь, упираясь в правую границу, равную <tex> C_{max} </tex>, можно построить расписание справа: выполняем на первом станке все работы из <tex>J</tex>, затем <tex>x</tex>, а для второго выполняем работы из <tex>J</tex>.[[Файл:Picture2.gif|500px|center]] | ||
## <tex>a_{x} \leqslant b_{y}</tex>. Сводится к первому, если поменять местами станки и соответствующие списки времён выполнения, при этом надо заново выполнить пункты 1,2 и 3. При выдаче ответа меняем станки обратно местами. | ## <tex>a_{x} \leqslant b_{y}</tex>. Сводится к первому, если поменять местами станки и соответствующие списки времён выполнения, при этом надо заново выполнить пункты 1,2 и 3. При выдаче ответа меняем станки обратно местами. | ||
Строка 24: | Строка 24: | ||
Чтобы доказать корректность, надо доказать, что на каждом станке в любой момент времени выполняется не более одной работы, и что каждая работа в каждый момент времени выполняется не более, чем на одном станке.<br/> | Чтобы доказать корректность, надо доказать, что на каждом станке в любой момент времени выполняется не более одной работы, и что каждая работа в каждый момент времени выполняется не более, чем на одном станке.<br/> | ||
Первое утверждение вытекает из того, что мы строили расписание, опираясь на <tex>C_{max}</tex>. Из построения <tex>C_{max} \geqslant \sum \limits_{i = 1}^{n}a_{i}, \sum \limits_{i = 1}^{n}b_{i}</tex>, следовательно на каждом станке в любой момент времени выполняется не более одной работы.<br/> | Первое утверждение вытекает из того, что мы строили расписание, опираясь на <tex>C_{max}</tex>. Из построения <tex>C_{max} \geqslant \sum \limits_{i = 1}^{n}a_{i}, \sum \limits_{i = 1}^{n}b_{i}</tex>, следовательно на каждом станке в любой момент времени выполняется не более одной работы.<br/> | ||
− | Докажем теперь второе утверждение. У нас имеется | + | Докажем теперь второе утверждение. У нас имеется три блока работ: <tex> I \setminus \{x\}, \{x\}, J</tex>. |
# Для блока <tex> \{x\}</tex> это следует из того, что <tex> C_{max} \geqslant a_{x}+b_{x}</tex>, а работа <tex> x </tex> выполняется с разных концов станков. Получили, что отрезки выполнения работы <tex> x </tex> на разных станках не пересекаются. | # Для блока <tex> \{x\}</tex> это следует из того, что <tex> C_{max} \geqslant a_{x}+b_{x}</tex>, а работа <tex> x </tex> выполняется с разных концов станков. Получили, что отрезки выполнения работы <tex> x </tex> на разных станках не пересекаются. | ||
# Покажем, что любая работа из <tex> I \setminus \{x\}</tex> начинает выполняться на втором станке позже, чем заканчивает выполняться на первом. Для этого рассмотрим сумму:<br><tex>\sum \limits_{i = 1}^k a_{i} \leqslant \sum \limits_{i = 1}^k b_{i} = \sum \limits_{i = 1}^{k - 1} b_{i} + b_{x}</tex>, где <tex>1 \dots k</tex> {{---}} это работы, выполняемые на первом станке во время данного блока.<br>Это неравенство следует из выбора <tex>I</tex> и из того, что <tex>b_{x} \geqslant a_{x} \geqslant a_{i}, \forall i \in I</tex>.<br>Получили, что каждая работа из этого блока начинает выполняться на втором станке позже, чем она заканчивается на первом.<br> | # Покажем, что любая работа из <tex> I \setminus \{x\}</tex> начинает выполняться на втором станке позже, чем заканчивает выполняться на первом. Для этого рассмотрим сумму:<br><tex>\sum \limits_{i = 1}^k a_{i} \leqslant \sum \limits_{i = 1}^k b_{i} = \sum \limits_{i = 1}^{k - 1} b_{i} + b_{x}</tex>, где <tex>1 \dots k</tex> {{---}} это работы, выполняемые на первом станке во время данного блока.<br>Это неравенство следует из выбора <tex>I</tex> и из того, что <tex>b_{x} \geqslant a_{x} \geqslant a_{i}, \forall i \in I</tex>.<br>Получили, что каждая работа из этого блока начинает выполняться на втором станке позже, чем она заканчивается на первом.<br> | ||
Строка 40: | Строка 40: | ||
<tex>I = \varnothing </tex> | <tex>I = \varnothing </tex> | ||
<tex>J = \varnothing </tex> | <tex>J = \varnothing </tex> | ||
− | |||
<tex>C_{max} = \max \{\sum \limits_{i = 1}^{n} a_i, \ \sum \limits_{i = 1}^{n} b_i, \ \max \limits_{i = 1}^{n}\{a_i + b_{i}\}\}</tex> | <tex>C_{max} = \max \{\sum \limits_{i = 1}^{n} a_i, \ \sum \limits_{i = 1}^{n} b_i, \ \max \limits_{i = 1}^{n}\{a_i + b_{i}\}\}</tex> | ||
'''for''' <tex>i = 1</tex> '''to''' <tex>n</tex> | '''for''' <tex>i = 1</tex> '''to''' <tex>n</tex> | ||
Строка 54: | Строка 53: | ||
От правой границы {{---}} <tex>C_{max}</tex> на первом станке расставляем расписание для <tex>\{x\}</tex>, затем для <tex>J</tex> | От правой границы {{---}} <tex>C_{max}</tex> на первом станке расставляем расписание для <tex>\{x\}</tex>, затем для <tex>J</tex> | ||
От правой границы {{---}} <tex>C_{max}</tex> на втором станке расставляем расписание для <tex>J</tex><br/> | От правой границы {{---}} <tex>C_{max}</tex> на втором станке расставляем расписание для <tex>J</tex><br/> | ||
− | ans = пара из расписания для первого станка и расписания для второго станка | + | '''pair<int[n], int[n]>''' ans = пара из расписания для первого станка и расписания для второго станка |
'''return''' ans | '''return''' ans | ||
'''else''' | '''else''' | ||
− | ans = scheduling(b, a) | + | '''pair<int[n], int[n]>''' ans = scheduling(b, a) |
Меняем местами расписания для станков в ans | Меняем местами расписания для станков в ans | ||
'''return''' ans | '''return''' ans |
Текущая версия на 19:13, 4 сентября 2022
Задача: |
Рассмотрим задачу:
|
Содержание
Описание алгоритма
Пусть
- Разобьём все работы на два множества: и .
- Найдем такие и , что и .
- Построим оптимальное значение целевой функции: .
- Рассмотрим два случая:
-
- Строим расписание слева: выполняем на первом станке все работы из , а на втором выполняем первой работу , затем в том же порядке, что и на первом станке.
- Теперь, упираясь в правую границу, равную , можно построить расписание справа: выполняем на первом станке все работы из , затем , а для второго выполняем работы из .
. Будем строить расписание с двух концов:
- . Сводится к первому, если поменять местами станки и соответствующие списки времён выполнения, при этом надо заново выполнить пункты 1,2 и 3. При выдаче ответа меняем станки обратно местами.
-
Доказательство корректности алгоритма
Теорема: |
Расписание, построенное данным алгоритмом, является корректным и оптимальным. |
Доказательство: |
Чтобы доказать корректность, надо доказать, что на каждом станке в любой момент времени выполняется не более одной работы, и что каждая работа в каждый момент времени выполняется не более, чем на одном станке.
Это неравенство следует из выбора и из того, что . Получили, что каждая работа из этого блока начинает выполняться на втором станке позже, чем она заканчивается на первом.Итого мы доказали корректность. |
Псевдокод
//Функция принимает список из времён выполнения на первом станке a и времён выполнения на втором станке b.
//Функция возвращает пару из расписания для первого станка и расписания для второго станка. function scheduling(a: int[n], b: int[n]): pair<int[n], int[n]> for to if else Найти , где Найти , где if Начиная с на первом станке расставляем расписание для Начиная с на втором станке расставляем расписание для , затем для
От правой границы — на первом станке расставляем расписание для , затем для От правой границы — на втором станке расставляем расписание для
pair<int[n], int[n]> ans = пара из расписания для первого станка и расписания для второго станка return ans else pair<int[n], int[n]> ans = scheduling(b, a) Меняем местами расписания для станков в ans return ans
Сложность алгоритма
Каждое из множеств в сумме содержит
элементов. Следовательно, чтобы найти максимум в каждом из множеств нам потребуется операций, чтобы составить расписание для каждой работы из множества нам потребуется так же операций. Получаем сложность алгоритма .См. также
Источники информации
- Peter Brucker «Scheduling Algorithms», fifth edition, Springer — с. 158—160 ISBN 978-3-540-69515-8