3622
правки
Изменения
→Псевдокод
== Задача Джонсона о двух станках <tex>F_2 \mid \mid C_{max}</tex> ==
Это единственная из flow shop задач с произвольными временами выполнения работ, которая решается за полиномиальное время.
Приведём здесь решение задачи без доказательства, его можно посмотреть <ref> Доказательство описано в книге [1http://books.google.ru/books?id=FrUytMqlCv8C&printsec=frontcover&dq=scheduling+algorithms&hl=ru&sa=X&ei=0MPMT4HqKYSk4gSBm6gp&sqi=2&ved=0CDEQ6AEwAA#v=onepage&q=scheduling%20algorithms&f=false Scheduling Algorithms, Peter Brucker]на страницах 174 {{---}} 178.</ref>.
Оптимальное расписание для первой и второй машины будет совпадать. Таким образом, нам требуется найти перестановку входных работпорядок, в котором будут выполняться работы на каждой машине.
===Алгоритм такой===Обозначим за <tex>p_1</tex> время выполнения работы на первом станке, за <tex>p_2</tex> время выполнения работы на втором станке. Будем использовать следующий алгоритм: возьмём два пустых списка. Будем и будем рассматривать работы в порядке возрастания <tex>\min(p_1, p_2)</tex>, то есть , минимума из времён выполнения данной работы на первой и второй машине. Если у работы <tex>p_1 <= \leqslant p_2</tex>, то добавим её в конец первого списка. В противном случае , добавим её в начало второго списка. Итоговое расписание — это конкатенация первого и второго списков.
===Псевдокод===Для представления работы в памяти будем использовать следующую структуру: J - множество работ Head <tex> \leftarrow \emptyset </tex> Tail <tex> \leftarrow \emptyset </tex> '''whilestruct''' J <tex> \ne \emptyset </tex> Job: '''doint''' I <tex> \leftarrow </tex> работа с минимальным значением <tex>min(p_1, p_2)</tex> '''if''' <texfont color = green>p_1 <= p_2</tex> Head <tex> \leftarrow </tex> Head <tex>\circВремя выполнения на первом станке</texfont> I '''elseint''' Tail <tex> \leftarrow p_2</tex> I <tex>\circ</tex> Tail J <texfont color = green> \leftarrow </tex> J <tex> \backslash </tex> I Result <tex> \leftarrow </tex> Head <tex>\circВремя выполнения на втором станке</texfont> Tail
<font color = green>// Функция принимает список работ J и возвращает список с расписанием работ.</font>
'''function''' scheduling(<tex>J</tex>: '''List<Job>'''): '''List<int>'''
<tex> \mathtt{List1} = \varnothing </tex>
<tex>\mathtt{List2} = \varnothing </tex>
'''while''' <tex>J \ne \varnothing </tex>
<tex>I</tex> = работа с минимальным значением <tex>\min(p_1, \ \ p_2)</tex>
'''if''' <tex>p_1 \leqslant p_2</tex>
<tex> \mathtt{List1} = \mathtt{List1} \cup I </tex>
'''else'''
<tex>\mathtt{List2} = I \cup \mathtt{List2} </tex>
<tex>J = J \setminus I </tex>
'''return''' <tex>\mathtt{List1} \cup \mathtt{List2} </tex>
== Задача Джонсона о двух станках с прерываниями <tex>F_2 \mid pmtn \mid C_{max}</tex> ==
{{Теорема
|statement= Оптимальное решение этой задачи совпадает с решением задачи <tex>F_2 \mid \mid C_{max}</tex>, приведённой выше.
|proof = Пусть у нас есть оптимальное расписание для задачи <tex>F_2 \mid pmtn \mid C_{max}</tex>. Покажем, что его за конечное число шагов можно преобразовать к расписанию без прерываний, не изменив при это значение <tex>C_{max}</tex> .
Рассмотрим первую машину. Допустим, что некоторая работа <tex> J </tex> выполняется в <tex> 2 </tex> или более разных промежутка времени. Тогда передвинем более ранний промежуток вправо по оси времени так, чтоб он заканчивался в тот момент, когда начинается второй промежуток, при этом работы, которые были между этими двумя промежутками, сдвинем влево на длину первого промежутка. Расписание при этом осталось корректным, так как работы на машинах по-прежнему не пересекаются, и каждая работа на второй машине делается после того, как она сделана на первой: работа <tex> J </tex> может начать выполняться на второй машине только после того, как она целиком выполнится на первой, то есть уже после конца второго промежутка; а время окончания выполнения остальных работ на первой машине неувеличилось.
Важно, что подобная операция не увеличивает <tex> C_{max} </tex>.
Будем повторять эту операцию до тех пор, пока на первой машине все работы не станут выполняться без прерываний. Так как количество прерываний конечно, а такая операция уменьшает их количество на один, этот процесс конечен.
Теперь избавимся от прерываний на второй машине. Точно так же рассмотрим работу, разбитую на два или более промежутка. Передвинем более поздний промежуток к концу более раннего, а работы между ними сдвинем вправо. Доказательство корректности измененного расписания аналогично доказательству для первой машины. Будем повторять данную операцию, пока на второй машине присутствуют прерывания.
Таким образом, мы получили корректное расписание без прерываний, не изменив при этом значение <tex>C_{max}</tex>.}}
== См. также ==
* [[Fpij1sumwu|<tex>F \mid p_{ij} = 1 \mid \sum w_i u_i</tex>]]
== Литература Примeчания==*<references/> [[1Категория: Дискретная математика и алгоритмы]][http[Категория://books.google.ru/books?id=FrUytMqlCv8C&printsec=frontcover&dq=scheduling+algorithms&hl=ru&sa=X&ei=0MPMT4HqKYSk4gSBm6gp&sqi=2&ved=0CDEQ6AEwAA#v=onepage&q=scheduling%20algorithms&f=false Scheduling Algorithms, Peter BruckerТеория расписаний]]