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

Материал из Викиконспекты
Перейти к: навигация, поиск
м
Строка 1: Строка 1:
== Постановка задачи ==
+
<tex dpi = 200>O2 \mid \mid C_{max}</tex>
Рассмотрим задачу:
+
{{Задача
<ol>
+
|definition=Рассмотрим задачу:
<li>Дано <tex>n</tex> работ и <tex>2</tex> станка.</li>
+
*Дано <tex>n</tex> работ и <tex>2</tex> станка.
<li>Для каждой работы известно её время выполнения на каждом станке.</li>
+
*Для каждой работы известно её время выполнения на каждом станке.
</ol>
+
Требуется минимизировать время окончания всех работ, если каждую работу необходимо выполнить на обоих станках.}}
Требуется минимизировать время окончания всех работ, если каждую работу необходимо выполнить на обоих станках.
 
  
 
== Описание алгоритма ==
 
== Описание алгоритма ==
 
Пусть <tex>a_{i}</tex> {{---}} время выполнения <tex>i</tex>-ой работы на первом станке, а <tex>b_{i}</tex> {{---}} на втором.<br/>
 
Пусть <tex>a_{i}</tex> {{---}} время выполнения <tex>i</tex>-ой работы на первом станке, а <tex>b_{i}</tex> {{---}} на втором.<br/>
<ol>
+
#Разобьём все работы на два множества: <tex>I = \{i \mid a_{i} \leqslant b_{i}; i = 1, \dots, n\}</tex> и <tex>J = \{i \mid a_{i} > b_{i}; i = 1, \dots, n\}</tex>.
<li>Разобьём все работы на два множества: <tex>I = \{i \mid a_{i} \le b_{i}; i = 1, \dots, n\}</tex> и <tex>J = \{i \mid a_{i} > b_{i}; i = 1, \dots, n\}</tex></li>
+
#Найдем такие <tex> x </tex> и <tex> y </tex>, что <tex>a_{x} = \max \{a_{i} \mid i \in I\}</tex> и <tex>b_{y} = \max \{b_{i} \mid i \in J\}</tex>.
<li>Найдем такие <tex> x </tex> и <tex> y </tex>, что <tex>a_{x} = \max \{a_{i} \mid i \in I\}</tex> и <tex>b_{y} = \max \{b_{i} \mid i \in J\}</tex> </li>
+
#Построим оптимальное значение целевой функции: <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>.
<li>Построим оптимальное значение целевой функции: <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>.</li>
+
# Рассмотрим два случая. Первый случай, когда <tex>a_{x} > b_{y}</tex> (он показан на рисунке ниже). Будем строить расписание с двух концов:
<li> Рассмотрим два случая. Первый случай, когда <tex>a_{x} > b_{y}</tex> (он показан на рисунке ниже). Будем строить расписание с двух концов:
+
#*Строим расписание слева: выполняем на первом станке все работы из <tex>I \setminus \{x\}</tex>, а на втором выполняем первой работу <tex>x</tex>, затем <tex>I \setminus \{x\}</tex>.
<ul>
+
#*Теперь, упираясь в правую границу, равную <tex> C_{max} </tex>, можно построить расписание справа: выполняем на первом станке все работы из <tex>J</tex>, затем <tex>x</tex>, а для второго выполняем работы из <tex>J</tex>.
<li>Строим расписание слева: выполняем на первом станке все работы из <tex>I \setminus \{x\}</tex>, а на втором выполняем первой работу <tex>x</tex>, затем <tex>I \setminus \{x\}</tex>.</li>
+
:Второй случай сводится к первому: все работы и станки меняются местами, и решается задача для первого случая.
<li>Теперь, упираясь в правую границу, равную <tex> C_{max} </tex>, можно построить расписание справа: выполняем на первом станке все работы из <tex>J</tex>, затем <tex>x</tex>, а для второго выполняем работы из <tex>J</tex></li>
+
 
</ul>
 
Второй случай сводится к первому: все работы и станки меняются местами, и решается задача для первого случая.
 
</li>
 
</ol>
 
 
[[Файл:Picture2.gif‎|500px|center]]
 
[[Файл:Picture2.gif‎|500px|center]]
  
Строка 29: Строка 24:
 
|proof=
 
|proof=
 
Чтобы доказать корректность, надо доказать, что на каждом станке в любой момент времени выполняется не более одной работы, и что каждая работа в каждый момент времени выполняется не более, чем на одном станке.<br/>
 
Чтобы доказать корректность, надо доказать, что на каждом станке в любой момент времени выполняется не более одной работы, и что каждая работа в каждый момент времени выполняется не более, чем на одном станке.<br/>
Первое утверждение вытекает из того, что мы строили расписание, опираясь на <tex>C_{max}</tex>. Из построения <tex>C_{max} \ge \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/>
 
Докажем теперь второе утверждение. У нас имеется 3 блока работ: <tex> I \setminus \{x\}, \{x\}, J</tex>.
 
Докажем теперь второе утверждение. У нас имеется 3 блока работ: <tex> I \setminus \{x\}, \{x\}, J</tex>.
<ol>
+
# Для блока <tex> \{x\}</tex> это следует из того, что <tex> C_{max} \geqslant a_{x}+b_{x}</tex>, а работа <tex> x </tex> выполняется с разных концов станков. Получили, что отрезки выполнения работы <tex> x </tex> на разных станках не пересекаются.
<li>Для блока <tex> \{x\}</tex> это следует из того, что <tex> C_{max} \ge a_{x}+b_{x}</tex>, а работа <tex> x </tex> выполняется с разных концов станков. Получили, что отрезки выполнения работы <tex> x </tex> на разных станках не пересекаются.</li>
+
# Покажем, что любая работа из <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>
<li>Покажем, что любая работа из <tex> I \setminus \{x\}</tex> начинает выполняться на втором станке позже, чем заканчивает выполняться на первом. Для этого рассмотрим сумму:
+
# Покажем, что любая работа из <tex>J</tex> начинает выполняться на втором станке позже, чем заканчивает выполняться на первом. Для этого рассмотрим сумму:<br><tex>\sum \limits_{i = 1}^k b_{i} \leqslant \sum \limits_{i = 1}^k a_{i} \leqslant \sum \limits_{i = 1}^{k - 1} a_{i} + a_{x}</tex>, где <tex>1 \dots k</tex> {{---}} это работы, выполняемые на втором станке во время данного блока.
<ul><tex>\sum \limits_{i = 1}^k a_{i} \le \sum \limits_{i = 1}^k b_{i} = \sum \limits_{i = 1}^{k - 1} b_{i} + b_{x}</tex></ul>,
+
Это неравенство следует из выбора <tex>J</tex> и из того, что <tex>a_{x} \geqslant a_{i}, \forall i \in I</tex>.
где <tex>1 \dots k</tex> {{---}} это работы, выполняемые на первом станке во время данного блока.<br/>
+
Получили, что каждая работа из этого блока начинает выполняться на втором станке позже, чем она заканчивается на первом.
Это неравенство следует из выбора <tex>I</tex> и из того, что <tex>b_{x} \ge a_{x} \ge a_{i}, \forall i \in I</tex>.<br/>
+
 
Получили, что каждая работа из этого блока начинает выполняться на втором станке позже, чем она заканчивается на первом.</li>
 
<li>Покажем, что любая работа из <tex>J</tex> начинает выполняться на втором станке позже, чем заканчивает выполняться на первом. Для этого рассмотрим сумму:
 
<ul><tex>\sum \limits_{i = 1}^k b_{i} \le \sum \limits_{i = 1}^k a_{i} \le \sum \limits_{i = 1}^{k - 1} a_{i} + a_{x}</tex></ul>,
 
где <tex>1 \dots k</tex> {{---}} это работы, выполняемые на втором станке во время данного блока.<br/>
 
Это неравенство следует из выбора <tex>J</tex> и из того, что <tex>a_{x} \ge a_{i}, \forall i \in I</tex>.<br/>
 
Получили, что каждая работа из этого блока начинает выполняться на втором станке позже, чем она заканчивается на первом.</li>
 
</ol>
 
 
Итого мы доказали корректность.<br/>
 
Итого мы доказали корректность.<br/>
 
Оптимальность вытекает из того, что <tex>C_{max}</tex> не может быть меньше <tex>\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}</tex> не может быть меньше <tex>\sum \limits_{i = 1}^{n} a_i, \sum \limits_{i = 1}^{n} b_i, \max \limits_{i = 1}^{n}\{a_i + b_{i}\}</tex>, а из построения оно равно максимуму из этих значений.
Строка 53: Строка 41:
 
   <tex>C_{max} \leftarrow \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} \leftarrow \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 \dots n</tex>
 
   for <tex>i = 1 \dots n</tex>
       if <tex>a_{i} \le b{i}</tex>
+
       if <tex>a_{i} \leqslant b{i}</tex>
 
         <tex> I \leftarrow I \cup \{i\} </tex>
 
         <tex> I \leftarrow I \cup \{i\} </tex>
 
       else
 
       else
Строка 73: Строка 61:
 
==Сложность алгоритма==
 
==Сложность алгоритма==
 
Каждое из множеств в сумме содержит <tex>n</tex> элементов. Следовательно, чтобы найти максимум в каждом из множеств нам потребуется <tex>O(n)</tex> операций, чтобы составить расписание для каждой работы из множества нам потребуется так же <tex>O(n)</tex> операций. Получаем сложность алгоритма <tex>O(n)</tex>.
 
Каждое из множеств в сумме содержит <tex>n</tex> элементов. Следовательно, чтобы найти максимум в каждом из множеств нам потребуется <tex>O(n)</tex> операций, чтобы составить расписание для каждой работы из множества нам потребуется так же <tex>O(n)</tex> операций. Получаем сложность алгоритма <tex>O(n)</tex>.
 +
 +
[[Категория: Дискретная математика и алгоритмы]]
 +
[[Категория: Теория расписаний]]

Версия 20:44, 15 мая 2016

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

Задача:
Рассмотрим задачу:
  • Дано [math]n[/math] работ и [math]2[/math] станка.
  • Для каждой работы известно её время выполнения на каждом станке.
Требуется минимизировать время окончания всех работ, если каждую работу необходимо выполнить на обоих станках.


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

Пусть [math]a_{i}[/math] — время выполнения [math]i[/math]-ой работы на первом станке, а [math]b_{i}[/math] — на втором.

  1. Разобьём все работы на два множества: [math]I = \{i \mid a_{i} \leqslant b_{i}; i = 1, \dots, n\}[/math] и [math]J = \{i \mid a_{i} \gt b_{i}; i = 1, \dots, n\}[/math].
  2. Найдем такие [math] x [/math] и [math] y [/math], что [math]a_{x} = \max \{a_{i} \mid i \in I\}[/math] и [math]b_{y} = \max \{b_{i} \mid i \in J\}[/math].
  3. Построим оптимальное значение целевой функции: [math]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}\}\}[/math].
  4. Рассмотрим два случая. Первый случай, когда [math]a_{x} \gt b_{y}[/math] (он показан на рисунке ниже). Будем строить расписание с двух концов:
    • Строим расписание слева: выполняем на первом станке все работы из [math]I \setminus \{x\}[/math], а на втором выполняем первой работу [math]x[/math], затем [math]I \setminus \{x\}[/math].
    • Теперь, упираясь в правую границу, равную [math] C_{max} [/math], можно построить расписание справа: выполняем на первом станке все работы из [math]J[/math], затем [math]x[/math], а для второго выполняем работы из [math]J[/math].
Второй случай сводится к первому: все работы и станки меняются местами, и решается задача для первого случая.
Picture2.gif

Доказательство корректности алгоритма

Теорема:
Расписание, построенное данным алгоритмом, является корректным и оптимальным.
Доказательство:
[math]\triangleright[/math]

Чтобы доказать корректность, надо доказать, что на каждом станке в любой момент времени выполняется не более одной работы, и что каждая работа в каждый момент времени выполняется не более, чем на одном станке.
Первое утверждение вытекает из того, что мы строили расписание, опираясь на [math]C_{max}[/math]. Из построения [math]C_{max} \geqslant \sum \limits_{i = 1}^{n}a_{i}, \sum \limits_{i = 1}^{n}b_{i}[/math], следовательно на каждом станке в любой момент времени выполняется не более одной работы.
Докажем теперь второе утверждение. У нас имеется 3 блока работ: [math] I \setminus \{x\}, \{x\}, J[/math].

  1. Для блока [math] \{x\}[/math] это следует из того, что [math] C_{max} \geqslant a_{x}+b_{x}[/math], а работа [math] x [/math] выполняется с разных концов станков. Получили, что отрезки выполнения работы [math] x [/math] на разных станках не пересекаются.
  2. Покажем, что любая работа из [math] I \setminus \{x\}[/math] начинает выполняться на втором станке позже, чем заканчивает выполняться на первом. Для этого рассмотрим сумму:
    [math]\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}[/math], где [math]1 \dots k[/math] — это работы, выполняемые на первом станке во время данного блока.
    Это неравенство следует из выбора [math]I[/math] и из того, что [math]b_{x} \geqslant a_{x} \geqslant a_{i}, \forall i \in I[/math].
    Получили, что каждая работа из этого блока начинает выполняться на втором станке позже, чем она заканчивается на первом.
  3. Покажем, что любая работа из [math]J[/math] начинает выполняться на втором станке позже, чем заканчивает выполняться на первом. Для этого рассмотрим сумму:
    [math]\sum \limits_{i = 1}^k b_{i} \leqslant \sum \limits_{i = 1}^k a_{i} \leqslant \sum \limits_{i = 1}^{k - 1} a_{i} + a_{x}[/math], где [math]1 \dots k[/math] — это работы, выполняемые на втором станке во время данного блока.

Это неравенство следует из выбора [math]J[/math] и из того, что [math]a_{x} \geqslant a_{i}, \forall i \in I[/math]. Получили, что каждая работа из этого блока начинает выполняться на втором станке позже, чем она заканчивается на первом.

Итого мы доказали корректность.

Оптимальность вытекает из того, что [math]C_{max}[/math] не может быть меньше [math]\sum \limits_{i = 1}^{n} a_i, \sum \limits_{i = 1}^{n} b_i, \max \limits_{i = 1}^{n}\{a_i + b_{i}\}[/math], а из построения оно равно максимуму из этих значений.
[math]\triangleleft[/math]

Псевдокод

  [math]I \leftarrow \varnothing [/math]
  [math]J \leftarrow \varnothing [/math]
  [math]C_{max} \leftarrow \max \{\sum \limits_{i = 1}^{n} a_i, \sum \limits_{i = 1}^{n} b_i, \max \limits_{i = 1}^{n}\{a_i + b_{i}\}\}[/math]
  for [math]i = 1 \dots n[/math]
     if [math]a_{i} \leqslant b{i}[/math]
        [math] I \leftarrow I \cup \{i\} [/math]
     else
        [math] J \leftarrow J \cup \{i\} [/math]
  Найти [math]x[/math], где [math]a_{x} = \max \limits_{i \in I} \{a_{i}\}[/math]
  Найти [math]y[/math], где [math]b_{y} = \max \limits_{i \in J} \{b_{i}\}[/math]
  if [math]a_{x} \lt  b_{y}[/math]
     Поменять местами первый и второй станок
     Пересчитать [math]I, J, x[/math]
     Запомнить, что поменяли
  
  Начиная с [math]0[/math] на первом станке расставляем расписание для [math]I \setminus \{x\}[/math]
  Начиная с [math]0[/math] на втором станке расставляем расписание для [math]\{x\}[/math], затем для [math]I \setminus \{x\}[/math]
От правой границы — [math]C_{max}[/math] на первом станке расставляем расписание для [math]\{x\}[/math], затем для [math]J[/math] От правой границы — [math]C_{max}[/math] на втором станке расставляем расписание для [math]J[/math]
if станки меняли местами поменять их обратно

Сложность алгоритма

Каждое из множеств в сумме содержит [math]n[/math] элементов. Следовательно, чтобы найти максимум в каждом из множеств нам потребуется [math]O(n)[/math] операций, чтобы составить расписание для каждой работы из множества нам потребуется так же [math]O(n)[/math] операций. Получаем сложность алгоритма [math]O(n)[/math].