<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=%D0%90%D0%BD%D0%BD%D0%B0</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=%D0%90%D0%BD%D0%BD%D0%B0"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/%D0%90%D0%BD%D0%BD%D0%B0"/>
		<updated>2026-06-11T17:35:10Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D0%B5%D0%BE%D1%80%D0%B8%D1%8F_%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D1%85_%D1%8F%D0%B7%D1%8B%D0%BA%D0%BE%D0%B2&amp;diff=58812</id>
		<title>Теория формальных языков</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D0%B5%D0%BE%D1%80%D0%B8%D1%8F_%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D1%85_%D1%8F%D0%B7%D1%8B%D0%BA%D0%BE%D0%B2&amp;diff=58812"/>
				<updated>2017-01-05T14:43:40Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: /* Примеры неразрешимых задач */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория: Теория формальных языков]]&lt;br /&gt;
Символом &amp;lt;tex&amp;gt; \star &amp;lt;/tex&amp;gt; помечены дополнительные темы (возможно, сложные), которые не были подробно рассмотрены (или вообще рассмотрены) в рамках курса.&lt;br /&gt;
== Автоматы и регулярные языки ==&lt;br /&gt;
=== Регулярные языки и ДКА ===&lt;br /&gt;
*[[Основные определения: алфавит, слово, язык, конкатенация, свободный моноид слов; операции над языками]]&lt;br /&gt;
*[[Регулярные языки: два определения и их эквивалентность | Регулярные языки: два определения и их эквивалентность, регулярные выражения]]&lt;br /&gt;
*[[Детерминированные конечные автоматы]]&lt;br /&gt;
*[[Прямое произведение ДКА]]&lt;br /&gt;
*[[Простой сопоставитель регулярных выражений]] &amp;lt;tex&amp;gt; \star &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== НКА ===&lt;br /&gt;
*[[Недетерминированные конечные автоматы]]&lt;br /&gt;
*[[Построение по НКА эквивалентного ДКА, алгоритм Томпсона]]&lt;br /&gt;
*[[Автоматы с eps-переходами. Eps-замыкание]]&lt;br /&gt;
*[[Теорема Клини (совпадение классов автоматных и регулярных языков)]]&lt;br /&gt;
*[[Альтернативное доказательство теоремы Клини (через систему уравнений в регулярных выражениях)]]&lt;br /&gt;
=== Минимизация ДКА ===&lt;br /&gt;
*[[Эквивалентность состояний ДКА]]&lt;br /&gt;
*[[Минимизация ДКА, алгоритм за O(n^2) с построением пар различимых состояний]]&lt;br /&gt;
*[[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))]]&lt;br /&gt;
*[[Алгоритм Бржозовского]]&amp;lt;tex&amp;gt; ^\star &amp;lt;/tex&amp;gt;&lt;br /&gt;
=== Свойства конечных автоматов ===&lt;br /&gt;
*[[Доказательство нерегулярности языков: лемма о разрастании]]&lt;br /&gt;
*[[Интерпретация булевых формул с кванторами как игр для двух игроков]]&lt;br /&gt;
*[[Решение уравнений в регулярных выражениях]]&lt;br /&gt;
*[[Замкнутость регулярных языков относительно различных операций]]&lt;br /&gt;
*[[Анализ свойств регулярных языков (пустота, совпадение, включение, конечность, подсчет числа слов)]]&lt;br /&gt;
*[[Контексты и синтаксические моноиды]]&lt;br /&gt;
=== Другие автоматы ===&lt;br /&gt;
*[[Локальные автоматы]]&amp;lt;tex&amp;gt; ^\star &amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Двусторонний детерминированный конечный автомат]]&amp;lt;tex&amp;gt; ^\star &amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Квантовые конечные автоматы]]&amp;lt;tex&amp;gt; ^\star &amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Автоматы Мура и Мили]]&amp;lt;tex&amp;gt; ^\star &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Контекстно-свободные грамматики ==&lt;br /&gt;
=== Базовые понятия о грамматиках ===&lt;br /&gt;
*[[Формальные грамматики]]&lt;br /&gt;
*[[Иерархия Хомского формальных грамматик]]&lt;br /&gt;
*[[Неукорачивающие и контекстно-зависимые грамматики, эквивалентность]]&lt;br /&gt;
*[[Правоконтекстные грамматики, эквивалентность автоматам]]&lt;br /&gt;
*[[Контекстно-свободные грамматики, вывод, лево- и правосторонний вывод, дерево разбора]]&lt;br /&gt;
*[[Замкнутость КС-языков относительно различных операций]]&lt;br /&gt;
*[[Регулярная аппроксимация КС-языков]]&amp;lt;tex&amp;gt; ^\star &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Нормальные формы КС-грамматик ===&lt;br /&gt;
*[[Удаление бесполезных символов из грамматики]]&lt;br /&gt;
*[[Удаление длинных правил из грамматики]]&lt;br /&gt;
*[[Удаление eps-правил из грамматики]]&lt;br /&gt;
*[[Удаление цепных правил из грамматики]]&lt;br /&gt;
*[[Нормальная форма Хомского]]&lt;br /&gt;
*[[Устранение левой рекурсии]]&lt;br /&gt;
*[[Приведение грамматики к ослабленной нормальной форме Грейбах]]&lt;br /&gt;
*[[Нормальная форма Куроды]]&amp;lt;tex&amp;gt; ^\star &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Алгоритмы разбора ===&lt;br /&gt;
*[[Алгоритм Кока-Янгера-Касами разбора грамматики в НФХ]]&lt;br /&gt;
*[[Алгоритм Кока-Янгера-Касами, модификация для произвольной грамматики]]&lt;br /&gt;
*[[Алгоритм Эрли]]&lt;br /&gt;
*[[Алгоритм Эрли, доказательство оценки O(n^2) для однозначной грамматики]]&lt;br /&gt;
&lt;br /&gt;
=== Опровержение контекстно-свободности языка ===&lt;br /&gt;
*[[Лемма о разрастании для КС-грамматик]]&lt;br /&gt;
*[[Лемма Огдена]]&lt;br /&gt;
*[[Существенно неоднозначные языки]]&lt;br /&gt;
*[[Теорема Парика]]&amp;lt;tex&amp;gt; ^\star &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== МП-автоматы ===&lt;br /&gt;
*[[Автоматы с магазинной памятью]]&lt;br /&gt;
*[[МП-автоматы, допуск по пустому стеку и по допускающему состоянию, эквивалентность]]&lt;br /&gt;
*[[Совпадение множества языков МП-автоматов и контекстно-свободных языков]]&lt;br /&gt;
*[[Детерминированные автоматы с магазинной памятью]]&lt;br /&gt;
*[[Детерминированные автоматы с магазинной памятью, допуск по пустому стеку]]&lt;br /&gt;
*[[Нормальная форма ДМП-автомата]]&lt;br /&gt;
*[[Несовпадение класса языков, распознаваемых ДМП автоматами и произвольными МП автоматами]]&lt;br /&gt;
*[[ДМП-автоматы и неоднозначность]]&lt;br /&gt;
&lt;br /&gt;
== Теория вычислимости ==&lt;br /&gt;
=== Разрешимые и перечислимые языки ===&lt;br /&gt;
*[[Разрешимые (рекурсивные) языки]]&lt;br /&gt;
*[[Перечислимые языки]]&lt;br /&gt;
*[[Замкнутость разрешимых и перечислимых языков относительно теоретико-множественных и алгебраических операций]]&lt;br /&gt;
*[[Вычислимые функции]]&lt;br /&gt;
*[[Вычислимые числа]]&lt;br /&gt;
*[[Универсальная функция|Универсальная функция и главные нумерации]] &lt;br /&gt;
*[[Свойства перечислимых языков. Теорема Успенского-Райса]]&lt;br /&gt;
*[[Неотделимые множества]]&lt;br /&gt;
*[[Иммунные и простые множества]]&lt;br /&gt;
*[[Теорема о рекурсии]]&lt;br /&gt;
*[[Квайны]]&amp;lt;tex&amp;gt; ^\star &amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Busy beaver]]&lt;br /&gt;
*[[Колмогоровская сложность]]&amp;lt;tex&amp;gt; ^\star &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительные формализмы ===&lt;br /&gt;
*[[Машина Тьюринга]]&lt;br /&gt;
*[[Лямбда-исчисление]]&amp;lt;tex&amp;gt; ^\star &amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Рекурсивные функции, представимость в формальной арифметике | Примитивно рекурсивные функции]]&amp;lt;tex&amp;gt; ^\star &amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Частично рекурсивные функции]]&amp;lt;tex&amp;gt; ^\star &amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Стековые машины, эквивалентность двухстековой машины МТ]]&lt;br /&gt;
*[[Счетчиковые машины, эквивалентность двухсчетчиковой машины МТ]]&lt;br /&gt;
*[[Линейный клеточный автомат, эквивалентность МТ]]&lt;br /&gt;
*[[Возможность порождения формальной грамматикой произвольного перечислимого языка]]&lt;br /&gt;
*[[Линейный ограниченный автомат]]&lt;br /&gt;
*[[Сверхтьюринговые вычисления (гипервычисления)]]&amp;lt;tex&amp;gt; ^\star &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Примеры неразрешимых задач ===&lt;br /&gt;
*[[m-сводимость]]&lt;br /&gt;
*[[Примеры неразрешимых задач: проблема соответствий Поста |Проблема соответствий Поста]]&lt;br /&gt;
*[[Примеры неразрешимых задач: однозначность грамматики|Однозначность КС-грамматики]]&lt;br /&gt;
*[[Неразрешимость задачи об эквивалентности КС-грамматик|Эквивалентность КС-грамматик]]&lt;br /&gt;
*[[Неразрешимость задачи о проверке на пустоту пересечения двух КС-грамматик|Пустота пересечения КС-грамматик]]&lt;br /&gt;
*[[Примеры неразрешимых задач: задача о замощении|Задача о замощении полимино]]&lt;br /&gt;
*[[Примеры неразрешимых задач: задача о выводе в полусистеме Туэ|Задача о выводе в полусистеме Туэ]]&lt;br /&gt;
*[[Неразрешимость исчисления предикатов первого порядка]]&lt;br /&gt;
*[[Неразрешимость проблемы существования решения диофантова уравнения в целых числах]]&lt;br /&gt;
*[[Игра «Жизнь»]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Неразрешимость игры Braid]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Теорема Райса-Шапиро]]&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9D%D0%B5%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D1%88%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D1%8C_%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8_%D0%BE_%D0%BF%D1%80%D0%BE%D0%B2%D0%B5%D1%80%D0%BA%D0%B5_%D0%BD%D0%B0_%D0%BF%D1%83%D1%81%D1%82%D0%BE%D1%82%D1%83_%D0%BF%D0%B5%D1%80%D0%B5%D1%81%D0%B5%D1%87%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B4%D0%B2%D1%83%D1%85_%D0%9A%D0%A1-%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA&amp;diff=58750</id>
		<title>Неразрешимость задачи о проверке на пустоту пересечения двух КС-грамматик</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9D%D0%B5%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D1%88%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D1%8C_%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8_%D0%BE_%D0%BF%D1%80%D0%BE%D0%B2%D0%B5%D1%80%D0%BA%D0%B5_%D0%BD%D0%B0_%D0%BF%D1%83%D1%81%D1%82%D0%BE%D1%82%D1%83_%D0%BF%D0%B5%D1%80%D0%B5%D1%81%D0%B5%D1%87%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B4%D0%B2%D1%83%D1%85_%D0%9A%D0%A1-%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA&amp;diff=58750"/>
				<updated>2017-01-04T22:10:36Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Теорема&lt;br /&gt;
|statement= Задача о проверке на пустоту пересечения двух КС-грамматик неразрешима.&lt;br /&gt;
|proof= &lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A = \{ (G_1, G_2) \mid L(G_1) \cap L(G_2) = \varnothing \}&amp;lt;/tex&amp;gt;. Сведем [[Примеры неразрешимых задач: проблема соответствий Поста|проблему соответствий Поста]] к &amp;lt;tex&amp;gt;\overline{A}&amp;lt;/tex&amp;gt;, таким образом показав, что дополнение проблемы неразрешимо. Так как рекурсивные языки [[Замкнутость разрешимых и перечислимых языков относительно теоретико-множественных и алгебраических операций|замкнуты относительно дополнения]], то из неразрешимости дополнения проблемы будет следовать неразрешимость самой проблемы.&lt;br /&gt;
&lt;br /&gt;
Для любого экземпляра ПСП &amp;lt;tex&amp;gt;(x_1, x_2, ..., x_n)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;(y_1, y_2, ..., y_n)&amp;lt;/tex&amp;gt; над алфавитом &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt; можно подобрать символ &amp;lt;tex&amp;gt;\# \notin \Sigma&amp;lt;/tex&amp;gt;. Для каждого экземпляра построим грамматики:&lt;br /&gt;
* &amp;lt;tex&amp;gt;G_1 : S \rightarrow aSa \mid a\#a&amp;lt;/tex&amp;gt; для всех &amp;lt;tex&amp;gt;a \in \Sigma&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;L(G_1) = \{ w\#w^R \mid w \in \Sigma^* \}&amp;lt;/tex&amp;gt;, где обозначение &amp;lt;tex&amp;gt;w^R&amp;lt;/tex&amp;gt; {{---}} разворот &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* &amp;lt;tex&amp;gt;G_2 : S \rightarrow x_iSy^R_i \mid x_i\#y^R_i&amp;lt;/tex&amp;gt; для всех &amp;lt;tex&amp;gt;i = 1, 2, \dots n&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;L(G_2) = \{ x_{i_1} x_{i_2} \dots x_{i_m} \# (y_{i_1} y_{i_2} \dots y_{i_m})^R \mid i_1, i_2, \dots i_m \in \{ 1, 2, \dots n \}, m \geqslant 1 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если данный экземпляр ПСП имеет решение, то &amp;lt;tex&amp;gt;L(G_2)&amp;lt;/tex&amp;gt; содержит хотя бы одну строку вида &amp;lt;tex&amp;gt;w\#w^R&amp;lt;/tex&amp;gt;, поэтому &amp;lt;tex&amp;gt;L(G_1) \cap L(G_2) \ne \varnothing&amp;lt;/tex&amp;gt;, и наоборот, если он не имеет решения, то &amp;lt;tex&amp;gt;L(G_2)&amp;lt;/tex&amp;gt; не содержит строк такого вида, соответственно &amp;lt;tex&amp;gt;L(G_1) \cap L(G_2) = \varnothing&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом мы свели проблему соответствий Поста к &amp;lt;tex&amp;gt;\overline{A}&amp;lt;/tex&amp;gt;, следовательно, задача о проверке на пустоту пересечения двух КС-грамматик неразрешима.&lt;br /&gt;
}}&lt;br /&gt;
Из неразрешимости вышеприведенной задачи следует неразрешимость ряда других задач. Рассмотрим несколько примеров.&lt;br /&gt;
&lt;br /&gt;
По двум КС-грамматикам &amp;lt;tex&amp;gt;G_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;G_2&amp;lt;/tex&amp;gt; можно построить КС-грамматику для [[Замкнутость КС-языков относительно различных операций#.D0.9A.D0.BE.D0.BD.D0.BA.D0.B0.D1.82.D0.B5.D0.BD.D0.B0.D1.86.D0.B8.D1.8F|конкатенации]] задаваемых ими языков &amp;lt;tex&amp;gt;L(G_1)L(G_2)&amp;lt;/tex&amp;gt;. По аналогии с этим мы можем рассматривать язык &amp;lt;tex&amp;gt;L(G_1)\#L(G_2)\#&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\#&amp;lt;/tex&amp;gt; {{---}} новый символ, не встречающийся в алфавите. Заметим, что пересечение языков непусто, то есть &amp;lt;tex&amp;gt;L(G_1) \cap L(G_2) \ne \varnothing &amp;lt;/tex&amp;gt;, тогда и только тогда, когда &amp;lt;tex&amp;gt;L(G_1)\#L(G_2)\#&amp;lt;/tex&amp;gt; содержит [[Алгоритм Ландау-Шмидта#.D0.9E.D0.BF.D1.80.D0.B5.D0.B4.D0.B5.D0.BB.D0.B5.D0.BD.D0.B8.D1.8F|тандемный повтор]]. &lt;br /&gt;
&lt;br /&gt;
Аналогично можно заметить, что пересечение &amp;lt;tex&amp;gt;L(G_1) \cap L(G_2) \ne \varnothing &amp;lt;/tex&amp;gt; тогда и только тогда, когда &amp;lt;tex&amp;gt;L(G_1)\#L(G_2)^R&amp;lt;/tex&amp;gt; содержит палиндром. &lt;br /&gt;
&lt;br /&gt;
Таким образом, мы имеем:&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement= Пусть дана грамматика &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;L(G) = L&amp;lt;/tex&amp;gt;. Тогда следующие задачи неразрешимы:&lt;br /&gt;
# Содержит ли &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; тандемный повтор.&lt;br /&gt;
# Содержит ли &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; палиндром.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[Контекстно-свободные грамматики, вывод, лево- и правосторонний вывод, дерево разбора | Контекстно-свободные грамматики]]&lt;br /&gt;
* [[Разрешимые (рекурсивные) языки | Разрешимые языки]]&lt;br /&gt;
* [[Примеры неразрешимых задач: проблема соответствий Поста | Проблема соответствий Поста]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [http://liacs.leidenuniv.nl/~hoogeboomhj/second/codingcomputations.pdf Hendrik Jan Hoogeboom &amp;quot;Undecidable Problems for Context-free Grammars&amp;quot;.] &lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Теория вычислимости]]&lt;br /&gt;
[[Категория: Примеры неразрешимых задач]]&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9D%D0%B5%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D1%88%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D1%8C_%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8_%D0%BE_%D0%BF%D1%80%D0%BE%D0%B2%D0%B5%D1%80%D0%BA%D0%B5_%D0%BD%D0%B0_%D0%BF%D1%83%D1%81%D1%82%D0%BE%D1%82%D1%83_%D0%BF%D0%B5%D1%80%D0%B5%D1%81%D0%B5%D1%87%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B4%D0%B2%D1%83%D1%85_%D0%9A%D0%A1-%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA&amp;diff=58696</id>
		<title>Неразрешимость задачи о проверке на пустоту пересечения двух КС-грамматик</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9D%D0%B5%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D1%88%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D1%8C_%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8_%D0%BE_%D0%BF%D1%80%D0%BE%D0%B2%D0%B5%D1%80%D0%BA%D0%B5_%D0%BD%D0%B0_%D0%BF%D1%83%D1%81%D1%82%D0%BE%D1%82%D1%83_%D0%BF%D0%B5%D1%80%D0%B5%D1%81%D0%B5%D1%87%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B4%D0%B2%D1%83%D1%85_%D0%9A%D0%A1-%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA&amp;diff=58696"/>
				<updated>2017-01-04T18:34:01Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: Новая страница: «{{Теорема |statement= Задача о проверке на пустоту пересечения двух КС-грамматик неразрешима. ...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Теорема&lt;br /&gt;
|statement= Задача о проверке на пустоту пересечения двух КС-грамматик неразрешима.&lt;br /&gt;
|proof= &lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A = \{ (G_1, G_2) \mid L(G_1) \cap L(G_2) = \varnothing \}&amp;lt;/tex&amp;gt;. Сведем [[Примеры неразрешимых задач: проблема соответствий Поста|проблему соответствий Поста]] к &amp;lt;tex&amp;gt;\overline{A}&amp;lt;/tex&amp;gt;, таким образом показав, что дополнение проблемы неразрешимо. Так как рекурсивные языки [[Замкнутость разрешимых и перечислимых языков относительно теоретико-множественных и алгебраических операций|замкнуты относительно дополнения]], то из неразрешимости дополнения проблемы будет следовать неразрешимость самой проблемы.&lt;br /&gt;
&lt;br /&gt;
Для любого экземпляра ПСП &amp;lt;tex&amp;gt;(x_1, x_2, ..., x_n)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;(y_1, y_2, ..., y_n)&amp;lt;/tex&amp;gt; над алфавитом &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt; можно подобрать символ &amp;lt;tex&amp;gt;\# \notin \Sigma&amp;lt;/tex&amp;gt;. Для каждого экземпляра построим грамматики:&lt;br /&gt;
* &amp;lt;tex&amp;gt;G_1 : S \rightarrow aSa \mid a\#a&amp;lt;/tex&amp;gt; для всех &amp;lt;tex&amp;gt;a \in \Sigma&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;L(G_1) = \{ w\#w^R \mid w \in \Sigma^* \}&amp;lt;/tex&amp;gt;, где обозначение &amp;lt;tex&amp;gt;w^R&amp;lt;/tex&amp;gt; {{---}} разворот &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* &amp;lt;tex&amp;gt;G_2 : S \rightarrow x_iSy^R_i \mid x_i\#y^R_i&amp;lt;/tex&amp;gt; для всех &amp;lt;tex&amp;gt;i = 1, 2, \dots n&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;L(G_2) = \{ x_{i_1} x_{i_2} \dots x_{i_m} \# (y_{i_1} y_{i_2} \dots y_{i_m})^R \mid i_1, i_2, \dots i_m \in \{ 1, 2, \dots n \}, m \geqslant 1 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если данный экземпляр ПСП имеет решение, то &amp;lt;tex&amp;gt;L(G_2)&amp;lt;/tex&amp;gt; содержит хотя бы одну строку вида &amp;lt;tex&amp;gt;w\#w^R&amp;lt;/tex&amp;gt;, поэтому &amp;lt;tex&amp;gt;L(G_1) \cap L(G_2) \ne \varnothing&amp;lt;/tex&amp;gt;, и наоборот, если он не имеет решения, то &amp;lt;tex&amp;gt;L(G_2)&amp;lt;/tex&amp;gt; не содержит строк такого вида, соответственно &amp;lt;tex&amp;gt;L(G_1) \cap L(G_2) = \varnothing&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом мы свели проблему соответствий Поста к &amp;lt;tex&amp;gt;\overline{A}&amp;lt;/tex&amp;gt;, следовательно, задача о проверке на пустоту пересечения двух КС-грамматик неразрешима.&lt;br /&gt;
}}&lt;br /&gt;
Из неразрешимости вышеприведенной задачи следует неразрешимость ряда других задач. Рассмотрим несколько примеров.&lt;br /&gt;
&lt;br /&gt;
По двум КС-грамматикам &amp;lt;tex&amp;gt;G_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;G_2&amp;lt;/tex&amp;gt; можно построить КС-грамматику для [[Замкнутость КС-языков относительно различных операций#.D0.9A.D0.BE.D0.BD.D0.BA.D0.B0.D1.82.D0.B5.D0.BD.D0.B0.D1.86.D0.B8.D1.8F|конкатенации]] задаваемых ими языков &amp;lt;tex&amp;gt;L(G_1)L(G_2)&amp;lt;/tex&amp;gt;. По аналогии с этим мы можем рассматривать язык &amp;lt;tex&amp;gt;L(G_1)\#L(G_2)\#&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\#&amp;lt;/tex&amp;gt; {{---}} новый символ, не встречающийся в алфавите. Заметим, что пересечение языков непусто, то есть &amp;lt;tex&amp;gt;L(G_1) \cap L(G_2) \ne \varnothing &amp;lt;/tex&amp;gt;, тогда и только тогда, когда &amp;lt;tex&amp;gt;L(G_1)\#L(G_2)\#&amp;lt;/tex&amp;gt; содержит [[Алгоритм Ландау-Шмидта#.D0.9E.D0.BF.D1.80.D0.B5.D0.B4.D0.B5.D0.BB.D0.B5.D0.BD.D0.B8.D1.8F|тандемный повтор]]. &lt;br /&gt;
&lt;br /&gt;
Аналогично можно заметить, что пересечение &amp;lt;tex&amp;gt;L(G_1) \cap L(G_2) \ne \varnothing &amp;lt;/tex&amp;gt; тогда и только тогда, когда &amp;lt;tex&amp;gt;L(G_1)\#L(G_2)^R&amp;lt;/tex&amp;gt; содержит палиндром. &lt;br /&gt;
&lt;br /&gt;
Таким образом, мы имеем:&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement= Пусть дана грамматика &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;L(G) = L&amp;lt;/tex&amp;gt;. Тогда следующие задачи неразрешимы:&lt;br /&gt;
# Содержит ли &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; тандемный повтор.&lt;br /&gt;
# Содержит ли &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; палиндром.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[Контекстно-свободные грамматики, вывод, лево- и правосторонний вывод, дерево разбора | Контекстно-свободные грамматики]]&lt;br /&gt;
* [[Разрешимые (рекурсивные) языки | Разрешимые языки]]&lt;br /&gt;
* [[Примеры неразрешимых задач: проблема соответствий Поста | Проблема соответствий Поста]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Теория вычислимости]]&lt;br /&gt;
[[Категория: Примеры неразрешимых задач]]&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D0%B5%D0%BE%D1%80%D0%B8%D1%8F_%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D1%85_%D1%8F%D0%B7%D1%8B%D0%BA%D0%BE%D0%B2&amp;diff=58692</id>
		<title>Теория формальных языков</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D0%B5%D0%BE%D1%80%D0%B8%D1%8F_%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D1%85_%D1%8F%D0%B7%D1%8B%D0%BA%D0%BE%D0%B2&amp;diff=58692"/>
				<updated>2017-01-04T18:31:58Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: /* Примеры неразрешимых задач */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория: Теория формальных языков]]&lt;br /&gt;
Символом &amp;lt;tex&amp;gt; \star &amp;lt;/tex&amp;gt; помечены дополнительные темы (возможно, сложные), которые не были подробно рассмотрены (или вообще рассмотрены) в рамках курса.&lt;br /&gt;
== Автоматы и регулярные языки ==&lt;br /&gt;
=== Регулярные языки и ДКА ===&lt;br /&gt;
*[[Основные определения: алфавит, слово, язык, конкатенация, свободный моноид слов; операции над языками]]&lt;br /&gt;
*[[Регулярные языки: два определения и их эквивалентность | Регулярные языки: два определения и их эквивалентность, регулярные выражения]]&lt;br /&gt;
*[[Детерминированные конечные автоматы]]&lt;br /&gt;
*[[Прямое произведение ДКА]]&lt;br /&gt;
*[[Простой сопоставитель регулярных выражений]] &amp;lt;tex&amp;gt; \star &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== НКА ===&lt;br /&gt;
*[[Недетерминированные конечные автоматы]]&lt;br /&gt;
*[[Построение по НКА эквивалентного ДКА, алгоритм Томпсона]]&lt;br /&gt;
*[[Автоматы с eps-переходами. Eps-замыкание]]&lt;br /&gt;
*[[Теорема Клини (совпадение классов автоматных и регулярных языков)]]&lt;br /&gt;
*[[Альтернативное доказательство теоремы Клини (через систему уравнений в регулярных выражениях)]]&lt;br /&gt;
=== Минимизация ДКА ===&lt;br /&gt;
*[[Эквивалентность состояний ДКА]]&lt;br /&gt;
*[[Минимизация ДКА, алгоритм за O(n^2) с построением пар различимых состояний]]&lt;br /&gt;
*[[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))]]&lt;br /&gt;
*[[Алгоритм Бржозовского]]&amp;lt;tex&amp;gt; ^\star &amp;lt;/tex&amp;gt;&lt;br /&gt;
=== Свойства конечных автоматов ===&lt;br /&gt;
*[[Доказательство нерегулярности языков: лемма о разрастании]]&lt;br /&gt;
*[[Интерпретация булевых формул с кванторами как игр для двух игроков]]&lt;br /&gt;
*[[Решение уравнений в регулярных выражениях]]&lt;br /&gt;
*[[Замкнутость регулярных языков относительно различных операций]]&lt;br /&gt;
*[[Анализ свойств регулярных языков (пустота, совпадение, включение, конечность, подсчет числа слов)]]&lt;br /&gt;
*[[Контексты и синтаксические моноиды]]&lt;br /&gt;
=== Другие автоматы ===&lt;br /&gt;
*[[Локальные автоматы]]&amp;lt;tex&amp;gt; ^\star &amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Двусторонний детерминированный конечный автомат]]&amp;lt;tex&amp;gt; ^\star &amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Квантовые конечные автоматы]]&amp;lt;tex&amp;gt; ^\star &amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Автоматы Мура и Мили]]&amp;lt;tex&amp;gt; ^\star &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Контекстно-свободные грамматики ==&lt;br /&gt;
=== Базовые понятия о грамматиках ===&lt;br /&gt;
*[[Формальные грамматики]]&lt;br /&gt;
*[[Иерархия Хомского формальных грамматик]]&lt;br /&gt;
*[[Неукорачивающие и контекстно-зависимые грамматики, эквивалентность]]&lt;br /&gt;
*[[Правоконтекстные грамматики, эквивалентность автоматам]]&lt;br /&gt;
*[[Контекстно-свободные грамматики, вывод, лево- и правосторонний вывод, дерево разбора]]&lt;br /&gt;
*[[Замкнутость КС-языков относительно различных операций]]&lt;br /&gt;
*[[Регулярная аппроксимация КС-языков]]&amp;lt;tex&amp;gt; ^\star &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Нормальные формы КС-грамматик ===&lt;br /&gt;
*[[Удаление бесполезных символов из грамматики]]&lt;br /&gt;
*[[Удаление длинных правил из грамматики]]&lt;br /&gt;
*[[Удаление eps-правил из грамматики]]&lt;br /&gt;
*[[Удаление цепных правил из грамматики]]&lt;br /&gt;
*[[Нормальная форма Хомского]]&lt;br /&gt;
*[[Устранение левой рекурсии]]&lt;br /&gt;
*[[Приведение грамматики к ослабленной нормальной форме Грейбах]]&lt;br /&gt;
*[[Нормальная форма Куроды]]&amp;lt;tex&amp;gt; ^\star &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Алгоритмы разбора ===&lt;br /&gt;
*[[Алгоритм Кока-Янгера-Касами разбора грамматики в НФХ]]&lt;br /&gt;
*[[Алгоритм Кока-Янгера-Касами, модификация для произвольной грамматики]]&lt;br /&gt;
*[[Алгоритм Эрли]]&lt;br /&gt;
*[[Алгоритм Эрли, доказательство оценки O(n^2) для однозначной грамматики]]&lt;br /&gt;
&lt;br /&gt;
=== Опровержение контекстно-свободности языка ===&lt;br /&gt;
*[[Лемма о разрастании для КС-грамматик]]&lt;br /&gt;
*[[Лемма Огдена]]&lt;br /&gt;
*[[Существенно неоднозначные языки]]&lt;br /&gt;
*[[Теорема Парика]]&amp;lt;tex&amp;gt; ^\star &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== МП-автоматы ===&lt;br /&gt;
*[[Автоматы с магазинной памятью]]&lt;br /&gt;
*[[МП-автоматы, допуск по пустому стеку и по допускающему состоянию, эквивалентность]]&lt;br /&gt;
*[[Совпадение множества языков МП-автоматов и контекстно-свободных языков]]&lt;br /&gt;
*[[Детерминированные автоматы с магазинной памятью]]&lt;br /&gt;
*[[Детерминированные автоматы с магазинной памятью, допуск по пустому стеку]]&lt;br /&gt;
*[[Нормальная форма ДМП-автомата]]&lt;br /&gt;
*[[Несовпадение класса языков, распознаваемых ДМП автоматами и произвольными МП автоматами]]&lt;br /&gt;
*[[ДМП-автоматы и неоднозначность]]&lt;br /&gt;
&lt;br /&gt;
== Теория вычислимости ==&lt;br /&gt;
=== Разрешимые и перечислимые языки ===&lt;br /&gt;
*[[Разрешимые (рекурсивные) языки]]&lt;br /&gt;
*[[Перечислимые языки]]&lt;br /&gt;
*[[Замкнутость разрешимых и перечислимых языков относительно теоретико-множественных и алгебраических операций]]&lt;br /&gt;
*[[Вычислимые функции]]&lt;br /&gt;
*[[Вычислимые числа]]&lt;br /&gt;
*[[Универсальная функция|Универсальная функция и главные нумерации]] &lt;br /&gt;
*[[Свойства перечислимых языков. Теорема Успенского-Райса]]&lt;br /&gt;
*[[Неотделимые множества]]&lt;br /&gt;
*[[Иммунные и простые множества]]&lt;br /&gt;
*[[Теорема о рекурсии]]&lt;br /&gt;
*[[Квайны]]&amp;lt;tex&amp;gt; ^\star &amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Busy beaver]]&lt;br /&gt;
*[[Колмогоровская сложность]]&amp;lt;tex&amp;gt; ^\star &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительные формализмы ===&lt;br /&gt;
*[[Машина Тьюринга]]&lt;br /&gt;
*[[Лямбда-исчисление]]&amp;lt;tex&amp;gt; ^\star &amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Рекурсивные функции, представимость в формальной арифметике | Примитивно рекурсивные функции]]&amp;lt;tex&amp;gt; ^\star &amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Частично рекурсивные функции]]&amp;lt;tex&amp;gt; ^\star &amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Стековые машины, эквивалентность двухстековой машины МТ]]&lt;br /&gt;
*[[Счетчиковые машины, эквивалентность двухсчетчиковой машины МТ]]&lt;br /&gt;
*[[Линейный клеточный автомат, эквивалентность МТ]]&lt;br /&gt;
*[[Возможность порождения формальной грамматикой произвольного перечислимого языка]]&lt;br /&gt;
*[[Линейный ограниченный автомат]]&lt;br /&gt;
*[[Сверхтьюринговые вычисления (гипервычисления)]]&amp;lt;tex&amp;gt; ^\star &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Примеры неразрешимых задач ===&lt;br /&gt;
*[[m-сводимость]]&lt;br /&gt;
*[[Примеры неразрешимых задач: проблема соответствий Поста |Проблема соответствий Поста]]&lt;br /&gt;
*[[Примеры неразрешимых задач: однозначность грамматики|Однозначность КС-грамматики]]&lt;br /&gt;
*[[Неразрешимость задачи об эквивалентности КС-грамматик|Эквивалентность КС-грамматик]]&lt;br /&gt;
*[[Неразрешимость задачи о проверке на пустоту пересечения двух КС-грамматик|Пересечение КС-грамматик]]&lt;br /&gt;
*[[Примеры неразрешимых задач: задача о замощении|Задача о замощении полимино]]&lt;br /&gt;
*[[Примеры неразрешимых задач: задача о выводе в полусистеме Туэ|Задача о выводе в полусистеме Туэ]]&lt;br /&gt;
*[[Неразрешимость исчисления предикатов первого порядка]]&lt;br /&gt;
*[[Неразрешимость проблемы существования решения диофантова уравнения в целых числах]]&lt;br /&gt;
*[[Игра «Жизнь»]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Неразрешимость игры Braid]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Теорема Райса-Шапиро]]&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=58628</id>
		<title>Обсуждение участницы:Анна</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=58628"/>
				<updated>2017-01-04T13:16:28Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Теорема&lt;br /&gt;
|statement= Задача о проверке на пустоту пересечения двух КС-грамматик неразрешима.&lt;br /&gt;
|proof= &lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A = \{ (G_1, G_2) \mid L(G_1) \cap L(G_2) = \varnothing \}&amp;lt;/tex&amp;gt;. Сведем [[Примеры неразрешимых задач: проблема соответствий Поста|проблему соответствий Поста]] к &amp;lt;tex&amp;gt;\overline{A}&amp;lt;/tex&amp;gt;, таким образом показав, что дополнение проблемы неразрешимо. Так как рекурсивные языки [[Замкнутость разрешимых и перечислимых языков относительно теоретико-множественных и алгебраических операций|замкнуты относительно дополнения]], то из неразрешимости дополнения проблемы будет следовать неразрешимость самой проблемы.&lt;br /&gt;
&lt;br /&gt;
Для любого экземпляра ПСП &amp;lt;tex&amp;gt;(x_1, x_2, ..., x_n)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;(y_1, y_2, ..., y_n)&amp;lt;/tex&amp;gt; над алфавитом &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt; можно подобрать символ &amp;lt;tex&amp;gt;\# \notin \Sigma&amp;lt;/tex&amp;gt;. Для каждого экземпляра построим грамматики:&lt;br /&gt;
* &amp;lt;tex&amp;gt;G_1 : S \rightarrow aSa \mid a\#a&amp;lt;/tex&amp;gt; для всех &amp;lt;tex&amp;gt;a \in \Sigma&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;L(G_1) = \{ w\#w^R \mid w \in \Sigma^* \}&amp;lt;/tex&amp;gt;, где обозначение &amp;lt;tex&amp;gt;w^R&amp;lt;/tex&amp;gt; {{---}} разворот &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* &amp;lt;tex&amp;gt;G_2 : S \rightarrow x_iSy^R_i \mid x_i\#y^R_i&amp;lt;/tex&amp;gt; для всех &amp;lt;tex&amp;gt;i = 1, 2, \dots n&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;L(G_2) = \{ x_{i_1} x_{i_2} \dots x_{i_m} \# (y_{i_1} y_{i_2} \dots y_{i_m})^R \mid i_1, i_2, \dots i_m \in \{ 1, 2, \dots n \}, m \geqslant 1 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если данный экземпляр ПСП имеет решение, то &amp;lt;tex&amp;gt;L(G_2)&amp;lt;/tex&amp;gt; содержит хотя бы одну строку вида &amp;lt;tex&amp;gt;w\#w^R&amp;lt;/tex&amp;gt;, поэтому &amp;lt;tex&amp;gt;L(G_1) \cap L(G_2) \ne \varnothing&amp;lt;/tex&amp;gt;, и наоборот, если он не имеет решения, то &amp;lt;tex&amp;gt;L(G_2)&amp;lt;/tex&amp;gt; не содержит строк такого вида, соответственно &amp;lt;tex&amp;gt;L(G_1) \cap L(G_2) = \varnothing&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом мы свели проблему соответствий Поста к &amp;lt;tex&amp;gt;\overline{A}&amp;lt;/tex&amp;gt;, следовательно, задача о проверке на пустоту пересечения двух КС-грамматик неразрешима.&lt;br /&gt;
}}&lt;br /&gt;
Из неразрешимости вышеприведенной задачи следует неразрешимость ряда других задач. Рассмотрим несколько примеров.&lt;br /&gt;
&lt;br /&gt;
По двум КС-грамматикам &amp;lt;tex&amp;gt;G_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;G_2&amp;lt;/tex&amp;gt; можно построить КС-грамматику для [[Замкнутость КС-языков относительно различных операций#.D0.9A.D0.BE.D0.BD.D0.BA.D0.B0.D1.82.D0.B5.D0.BD.D0.B0.D1.86.D0.B8.D1.8F|конкатенации]] задаваемых ими языков &amp;lt;tex&amp;gt;L(G_1)L(G_2)&amp;lt;/tex&amp;gt;. По аналогии с этим мы можем рассматривать язык &amp;lt;tex&amp;gt;L(G_1)\#L(G_2)\#&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\#&amp;lt;/tex&amp;gt; {{---}} новый символ, не встречающийся в алфавите. Заметим, что пересечение языков непусто, то есть &amp;lt;tex&amp;gt;L(G_1) \cap L(G_2) \ne \varnothing &amp;lt;/tex&amp;gt;, тогда и только тогда, когда &amp;lt;tex&amp;gt;L(G_1)\#L(G_2)\#&amp;lt;/tex&amp;gt; содержит [[Алгоритм Ландау-Шмидта#.D0.9E.D0.BF.D1.80.D0.B5.D0.B4.D0.B5.D0.BB.D0.B5.D0.BD.D0.B8.D1.8F|тандемный повтор]]. &lt;br /&gt;
&lt;br /&gt;
Аналогично можно заметить, что пересечение &amp;lt;tex&amp;gt;L(G_1) \cap L(G_2) \ne \varnothing &amp;lt;/tex&amp;gt; тогда и только тогда, когда &amp;lt;tex&amp;gt;L(G_1)\#L(G_2)^R&amp;lt;/tex&amp;gt; содержит палиндром. &lt;br /&gt;
&lt;br /&gt;
Таким образом, мы имеем:&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement= Пусть дана грамматика &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;L(G) = L&amp;lt;/tex&amp;gt;. Тогда следующие задачи неразрешимы:&lt;br /&gt;
# Содержит ли &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; тандемный повтор.&lt;br /&gt;
# Содержит ли &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; палиндром.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=58624</id>
		<title>Обсуждение участницы:Анна</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=58624"/>
				<updated>2017-01-04T08:25:07Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Теорема&lt;br /&gt;
|statement= Задача о проверке на пустоту пересечения двух КС-грамматик неразрешима.&lt;br /&gt;
|proof= &lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A = \{ (G_1, G_2) \mid L(G_1) \cap L(G_2) = \varnothing \}&amp;lt;/tex&amp;gt;. Сведем [[Примеры неразрешимых задач: проблема соответствий Поста|проблему соответствий Поста]] к &amp;lt;tex&amp;gt;\overline{A}&amp;lt;/tex&amp;gt;, таким образом показав, что дополнение проблемы неразрешимо. Так как рекурсивные языки [[Замкнутость разрешимых и перечислимых языков относительно теоретико-множественных и алгебраических операций|замкнуты относительно дополнения]], то из неразрешимости дополнения проблемы будет следовать неразрешимость самой проблемы.&lt;br /&gt;
}}&lt;br /&gt;
Из неразрешимости вышеприведенной задачи следует неразрешимость ряда других задач. Рассмотрим несколько примеров.&lt;br /&gt;
&lt;br /&gt;
По двум КС-грамматикам &amp;lt;tex&amp;gt;G_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;G_2&amp;lt;/tex&amp;gt; можно построить КС-грамматику для [[Замкнутость КС-языков относительно различных операций#.D0.9A.D0.BE.D0.BD.D0.BA.D0.B0.D1.82.D0.B5.D0.BD.D0.B0.D1.86.D0.B8.D1.8F|конкатенации]] задаваемых ими языков &amp;lt;tex&amp;gt;L(G_1)L(G_2)&amp;lt;/tex&amp;gt;. По аналогии с этим мы можем рассматривать язык &amp;lt;tex&amp;gt;L(G_1)\#L(G_2)\#&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\#&amp;lt;/tex&amp;gt; {{---}} новый символ, не встречающийся в алфавите. Заметим, что пересечение языков непусто, то есть &amp;lt;tex&amp;gt;L(G_1) \cap L(G_2) \ne \varnothing &amp;lt;/tex&amp;gt;, тогда и только тогда, когда &amp;lt;tex&amp;gt;L(G_1)\#L(G_2)\#&amp;lt;/tex&amp;gt; содержит [[Алгоритм Ландау-Шмидта#.D0.9E.D0.BF.D1.80.D0.B5.D0.B4.D0.B5.D0.BB.D0.B5.D0.BD.D0.B8.D1.8F|тандемный повтор]]. &lt;br /&gt;
&lt;br /&gt;
Аналогично можно заметить, что пересечение &amp;lt;tex&amp;gt;L(G_1) \cap L(G_2) \ne \varnothing &amp;lt;/tex&amp;gt; тогда и только тогда, когда &amp;lt;tex&amp;gt;L(G_1)\#L(G_2)^R&amp;lt;/tex&amp;gt; содержит палиндром, где обозначение &amp;lt;tex&amp;gt;L^R&amp;lt;/tex&amp;gt; {{---}} разворот &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Таким образом, мы имеем:&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement= Пусть дана грамматика &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;L(G) = L&amp;lt;/tex&amp;gt;. Тогда следующие задачи неразрешимы:&lt;br /&gt;
# Содержит ли &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; тандемный повтор.&lt;br /&gt;
# Содержит ли &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; палиндром.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=58591</id>
		<title>Обсуждение участницы:Анна</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=58591"/>
				<updated>2017-01-03T14:19:32Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Теорема&lt;br /&gt;
|statement= Задача о проверке на пустоту пересечения двух КС-грамматик неразрешима.&lt;br /&gt;
|proof= &lt;br /&gt;
Тут будет доказательство.&lt;br /&gt;
}}&lt;br /&gt;
Из неразрешимости вышеприведенной задачи следует неразрешимость ряда других задач. Рассмотрим несколько примеров.&lt;br /&gt;
&lt;br /&gt;
По двум КС-грамматикам &amp;lt;tex&amp;gt;G_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;G_2&amp;lt;/tex&amp;gt; можно построить КС-грамматику для [[Замкнутость КС-языков относительно различных операций#.D0.9A.D0.BE.D0.BD.D0.BA.D0.B0.D1.82.D0.B5.D0.BD.D0.B0.D1.86.D0.B8.D1.8F|конкатенации]] задаваемых ими языков &amp;lt;tex&amp;gt;L(G_1)L(G_2)&amp;lt;/tex&amp;gt;. По аналогии с этим мы можем рассматривать язык &amp;lt;tex&amp;gt;L(G_1)\#L(G_2)\#&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\#&amp;lt;/tex&amp;gt; {{---}} новый символ, не встречающийся в алфавите. Заметим, что пересечение языков непусто, то есть &amp;lt;tex&amp;gt;L(G_1) \cap L(G_2) \ne \varnothing &amp;lt;/tex&amp;gt;, тогда и только тогда, когда &amp;lt;tex&amp;gt;L(G_1)\#L(G_2)\#&amp;lt;/tex&amp;gt; содержит [[Алгоритм Ландау-Шмидта#.D0.9E.D0.BF.D1.80.D0.B5.D0.B4.D0.B5.D0.BB.D0.B5.D0.BD.D0.B8.D1.8F|тандемный повтор]]. &lt;br /&gt;
&lt;br /&gt;
Аналогично можно заметить, что пересечение &amp;lt;tex&amp;gt;L(G_1) \cap L(G_2) \ne \varnothing &amp;lt;/tex&amp;gt; тогда и только тогда, когда &amp;lt;tex&amp;gt;L(G_1)\#L(G_2)^R&amp;lt;/tex&amp;gt; содержит палиндром, где обозначение &amp;lt;tex&amp;gt;L^R&amp;lt;/tex&amp;gt; {{---}} разворот &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Таким образом, мы имеем:&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement= Пусть дана грамматика &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;L(G) = L&amp;lt;/tex&amp;gt;. Тогда следующие задачи неразрешимы:&lt;br /&gt;
# Содержит ли &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; тандемный повтор.&lt;br /&gt;
# Содержит ли &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; палиндром.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=58586</id>
		<title>Обсуждение участницы:Анна</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=58586"/>
				<updated>2017-01-03T13:39:29Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Теорема&lt;br /&gt;
|statement= Задача о проверке на пустоту пересечения двух КС-грамматик неразрешима.&lt;br /&gt;
|proof= &lt;br /&gt;
Тут будет доказательство.&lt;br /&gt;
}}&lt;br /&gt;
Из неразрешимости вышеприведенной задачи следует неразрешимость ряда других задач. Рассмотрим несколько примеров.&lt;br /&gt;
&lt;br /&gt;
По двум КС-грамматикам &amp;lt;tex&amp;gt;G_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;G_2&amp;lt;/tex&amp;gt; можно построить КС-грамматику для [[Замкнутость КС-языков относительно различных операций#.D0.9A.D0.BE.D0.BD.D0.BA.D0.B0.D1.82.D0.B5.D0.BD.D0.B0.D1.86.D0.B8.D1.8F|конкатенации]] задаваемых ими языков &amp;lt;tex&amp;gt;L(G_1)L(G_2)&amp;lt;/tex&amp;gt;. По аналогии с этим мы можем рассматривать язык &amp;lt;tex&amp;gt;L(G_1)\#L(G_2)\#&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\#&amp;lt;/tex&amp;gt; {{---}} новый символ, не встречающийся в алфавите. Заметим, что пересечение языков непусто, то есть &amp;lt;tex&amp;gt;L(G_1) \cap L(G_2) \ne \varnothing &amp;lt;/tex&amp;gt;, тогда и только тогда, когда &amp;lt;tex&amp;gt;L(G_1)\#L(G_2)\#&amp;lt;/tex&amp;gt; содержит [[Алгоритм Ландау-Шмидта#.D0.9E.D0.BF.D1.80.D0.B5.D0.B4.D0.B5.D0.BB.D0.B5.D0.BD.D0.B8.D1.8F|тандемный повтор]]. &lt;br /&gt;
&lt;br /&gt;
Аналогично можно заметить, что пересечение &amp;lt;tex&amp;gt;L(G_1) \cap L(G_2) \ne \varnothing &amp;lt;/tex&amp;gt; тогда и только тогда, когда &amp;lt;tex&amp;gt;L(G_1)\#L(G_2)^R&amp;lt;/tex&amp;gt; содержит палиндром. Таким образом, мы имеем:&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement= Пусть дана грамматика &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;L(G) = L&amp;lt;/tex&amp;gt;. Тогда следующие задачи неразрешимы:&lt;br /&gt;
# Содержит ли &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; тандемный повтор.&lt;br /&gt;
# Содержит ли &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; палиндром.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=58218</id>
		<title>Обсуждение участницы:Анна</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=58218"/>
				<updated>2016-12-23T22:00:44Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: Удалено содержимое страницы&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=58217</id>
		<title>Обсуждение участницы:Анна</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=58217"/>
				<updated>2016-12-23T21:46:26Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Доказательство того, что следующие языки неразрешимы:&lt;br /&gt;
# &amp;lt;tex&amp;gt;A_{TM} = \{ (M, w) \mid M - &amp;lt;/tex&amp;gt; машина Тьюринга, допускающая строку &amp;lt;tex&amp;gt;w \}&amp;lt;/tex&amp;gt; &lt;br /&gt;
# &amp;lt;tex&amp;gt;L_{TM} = \{ (M, w) \mid M - &amp;lt;/tex&amp;gt; машина Тьюринга, допускающая строку &amp;lt;tex&amp;gt;w^R&amp;lt;/tex&amp;gt; и не допускающая строку &amp;lt;tex&amp;gt;w \}&amp;lt;/tex&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt;A\varepsilon_{TM} = \{ M \mid M - &amp;lt;/tex&amp;gt; машина Тьюринга, допускающая &amp;lt;tex&amp;gt;\varepsilon \}&amp;lt;/tex&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt;R_{TM} = \{ M \mid M - &amp;lt;/tex&amp;gt; машина Тьюринга и &amp;lt;tex&amp;gt;L(M) - &amp;lt;/tex&amp;gt; регулярный &amp;lt;tex&amp;gt; \}&amp;lt;/tex&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt;E_{TM} = \{ M \mid M - &amp;lt;/tex&amp;gt; машина Тьюринга и &amp;lt;tex&amp;gt;L(M) = \varnothing \}&amp;lt;/tex&amp;gt;&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=58205</id>
		<title>Обсуждение участницы:Анна</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=58205"/>
				<updated>2016-12-22T22:12:05Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: Удалено содержимое страницы&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%BC%D0%BA%D0%BD%D1%83%D1%82%D0%BE%D1%81%D1%82%D1%8C_%D1%80%D0%B5%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%8F%D0%B7%D1%8B%D0%BA%D0%BE%D0%B2_%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE_%D1%80%D0%B0%D0%B7%D0%BB%D0%B8%D1%87%D0%BD%D1%8B%D1%85_%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%B9&amp;diff=58204</id>
		<title>Замкнутость регулярных языков относительно различных операций</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%BC%D0%BA%D0%BD%D1%83%D1%82%D0%BE%D1%81%D1%82%D1%8C_%D1%80%D0%B5%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%8F%D0%B7%D1%8B%D0%BA%D0%BE%D0%B2_%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE_%D1%80%D0%B0%D0%B7%D0%BB%D0%B8%D1%87%D0%BD%D1%8B%D1%85_%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%B9&amp;diff=58204"/>
				<updated>2016-12-22T22:10:06Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Теорема ==&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L_1, L_2&amp;lt;/tex&amp;gt; {{---}} [[Регулярные языки: два определения и их эквивалентность|регулярные языки]] над одним алфавитом &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;. Тогда следующие языки также являются регулярными:&lt;br /&gt;
#Языки, полученные путём применения следующих теоретико-множественных операций:&lt;br /&gt;
#*&amp;lt;tex&amp;gt;L_1 \cup L_2&amp;lt;/tex&amp;gt;,&lt;br /&gt;
#*&amp;lt;tex&amp;gt;\overline{L_1}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
#*&amp;lt;tex&amp;gt;L_1 \cap L_2&amp;lt;/tex&amp;gt;,&lt;br /&gt;
#*&amp;lt;tex&amp;gt;L_1 \setminus L_2&amp;lt;/tex&amp;gt;;&lt;br /&gt;
#&amp;lt;tex&amp;gt;L_1^*&amp;lt;/tex&amp;gt;;&lt;br /&gt;
#&amp;lt;tex&amp;gt;L_1 L_2&amp;lt;/tex&amp;gt;;&lt;br /&gt;
#&amp;lt;tex&amp;gt;\overset{\leftarrow}{L_1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
Как известно, [[Теорема Клини (совпадение классов автоматных и регулярных языков|классы регулярных и автоматных языков совпадают]]. Пусть языки &amp;lt;tex&amp;gt;L_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;L_2&amp;lt;/tex&amp;gt; распознаются автоматами &amp;lt;tex&amp;gt;A_1 = \langle \Sigma , Q_1 , s_1 , T_1 , \delta_1 : Q_1 \times \Sigma \rightarrow 2^{Q_1} \rangle &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;A_2 = \langle \Sigma , Q_2 , s_2 , T_2 , \delta_2 : Q_2 \times \Sigma \rightarrow 2^{Q_2} \rangle &amp;lt;/tex&amp;gt; соответственно.&lt;br /&gt;
#&lt;br /&gt;
#*&amp;lt;tex&amp;gt;L_1 \cup L_2&amp;lt;/tex&amp;gt; является регулярным по определению [[Регулярные языки: два определения и их эквивалентность|регулярных языков]].&lt;br /&gt;
#*Рассмотрим автомат &amp;lt;tex&amp;gt;A_1' = \langle \Sigma , Q_1 , s_1 , Q_1 \setminus T_1 , \delta_1 \rangle &amp;lt;/tex&amp;gt;, то есть автомат &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, в котором терминальные и нетерминальные состояния инвертированы (при таком построении следует помнить, что если в исходном автомате было опущено дьявольское состояние, его нужно явно добавить и сделать допускающим.) Очевидно, он допускает те и только те слова, которые не допускает автомат &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt;, а значит, задаёт язык &amp;lt;tex&amp;gt;\overline{L_1}&amp;lt;/tex&amp;gt;. Таким образом, &amp;lt;tex&amp;gt;\overline{L_1}&amp;lt;/tex&amp;gt; {{---}} регулярный.&lt;br /&gt;
#*&amp;lt;tex&amp;gt;L_1 \cap L_2 = \overline{\overline{L_1} \cup \overline{L_2}}&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;L_1 \cap L_2&amp;lt;/tex&amp;gt; {{---}} регулярный. Также автомат для пересечения языков можно построить явно, используя конструкцию [[Прямое произведение ДКА|произведения автоматов]].&lt;br /&gt;
#*&amp;lt;tex&amp;gt;L_1 \setminus L_2 = L_1 \cap \overline{L_2}&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;L_1 \setminus L_2&amp;lt;/tex&amp;gt; {{---}} регулярный.&lt;br /&gt;
#&amp;lt;tex&amp;gt;L_1^*&amp;lt;/tex&amp;gt; является регулярным по определению [[Регулярные языки: два определения и их эквивалентность|регулярных языков]].&lt;br /&gt;
#&amp;lt;tex&amp;gt;L_1 L_2&amp;lt;/tex&amp;gt; также является регулярным по определению [[Регулярные языки: два определения и их эквивалентность|регулярных языков]].&lt;br /&gt;
#Рассмотрим [[Автоматы_с_eps-переходами._Eps-замыкание|НКА c &amp;lt;tex&amp;gt;\varepsilon&amp;lt;/tex&amp;gt;-переходами]] &amp;lt;tex&amp;gt;A_1' = \langle \Sigma, Q_1, s' , \lbrace s_1 \rbrace, \delta_1' \rangle &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\delta_1' (v,c) = \lbrace u | \delta_1(u,c) = v \rbrace &amp;lt;/tex&amp;gt;; &amp;lt;tex&amp;gt;\delta_1'(s', \varepsilon) = \lbrace T_i \rbrace&amp;lt;/tex&amp;gt;. Если в исходном автомате путь по &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;s_1&amp;lt;/tex&amp;gt; приводил в терминальное состояние, то в новом автомате существует путь по &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; из этого терминального состояния в &amp;lt;tex&amp;gt;s_1&amp;lt;/tex&amp;gt; (и наоборот). Следовательно, этот автомат распознает в точности развернутые слова языка &amp;lt;tex&amp;gt;L_1&amp;lt;/tex&amp;gt;. Тогда язык &amp;lt;tex&amp;gt;\overset{\leftarrow}{L_1}&amp;lt;/tex&amp;gt; {{---}} регулярный.&lt;br /&gt;
}}&lt;br /&gt;
== Примеры доказательств ==&lt;br /&gt;
=== Гомоморфизм цепочек ===&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id=st1&lt;br /&gt;
|statement=&lt;br /&gt;
&amp;lt;tex&amp;gt;L \subset \Sigma_1^*&amp;lt;/tex&amp;gt; {{---}} регулярный , &amp;lt;tex&amp;gt;\varphi:\Sigma_1^* \rightarrow \Sigma_2^* &amp;lt;/tex&amp;gt; {{---}} [[Основные определения: алфавит, слово, язык, конкатенация, свободный моноид слов; операции над языками#Гомоморфизм_языков | гомоморфизм цепочек]]. Тогда  &amp;lt;tex&amp;gt;\varphi(L)&amp;lt;/tex&amp;gt; {{---}} регулярный.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим [[Детерминированные_конечные_автоматы|ДКА]], распознающий &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Заменим в нем все переходы по символам на переходы по их образам при гомоморфизме. Полученный автомат (с переходами по строкам) распознает в точности &amp;lt;tex&amp;gt;\varphi(L)&amp;lt;/tex&amp;gt; и [[Автоматы_с_eps-переходами._Eps-замыкание|имеет эквивалентный ДКА]].&lt;br /&gt;
}}&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id=st2&lt;br /&gt;
|statement=&lt;br /&gt;
&amp;lt;tex&amp;gt;L \subset \Sigma_2^*&amp;lt;/tex&amp;gt; {{---}} регулярный , &amp;lt;tex&amp;gt;\varphi:\Sigma_1^* \rightarrow \Sigma_2^* &amp;lt;/tex&amp;gt; {{---}} [[Основные определения: алфавит, слово, язык, конкатенация, свободный моноид слов; операции над языками#Гомоморфизм_языков | гомоморфизм цепочек]]. Тогда  &amp;lt;tex&amp;gt;\varphi^{-1}(L)&amp;lt;/tex&amp;gt; {{---}} регулярный.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим [[Детерминированные_конечные_автоматы|ДКА]], распознающий &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Отследим для каждого состояния &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и символа &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; строку &amp;lt;tex&amp;gt;\varphi(c)&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt; \langle u,\varphi(c) \rangle \vdash^* \langle v,\varepsilon \rangle&amp;lt;/tex&amp;gt; и положим &amp;lt;tex&amp;gt;\delta (u,c) = v&amp;lt;/tex&amp;gt; в новом автомате (на том же множестве состояний). Автомат с построенной таким образом функцией переходов, очевидно, распознает слова языка &amp;lt;tex&amp;gt;\varphi^{-1}(L)&amp;lt;/tex&amp;gt; и только их.&lt;br /&gt;
}}&lt;br /&gt;
=== Язык half(L) ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;\mathrm{half(L)}&amp;lt;/tex&amp;gt; как множество первых половин цепочек языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть множество &amp;lt;tex&amp;gt;\{ w \mid \exists x : wx \in L \land |w| = |x| \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ \varepsilon, 0010, 011, 010110 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\mathrm{half(L)} = \{ \varepsilon, 00, 010 \}&amp;lt;/tex&amp;gt;. Заметим, что цепочки нечетной длины не влияют на &amp;lt;tex&amp;gt;\mathrm{half(L)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st3&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} [[Регулярные языки: два определения и их эквивалентность|регулярный язык]]. Тогда язык &amp;lt;tex&amp;gt;\mathrm{half(L)}&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык, то существует ДКА &amp;lt;tex&amp;gt;M = \langle \Sigma , Q , q_0 , F , \delta \rangle &amp;lt;/tex&amp;gt;, допускающий его. Рассмотрим строку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Для того, чтобы проверить, что &amp;lt;tex&amp;gt;x \in \mathrm{half(L)}&amp;lt;/tex&amp;gt;, нам надо убедиться, что существует строка &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; такой же длины, что и &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, которая, будучи сконкатенированной с &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, даст строку из &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть если на вход автомату подать &amp;lt;tex&amp;gt;xy&amp;lt;/tex&amp;gt;, то в конце обработки мы окажемся в терминальном состоянии. Предположим, что автомат, закончив обработку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, находится в состоянии &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_0, x) = q_i&amp;lt;/tex&amp;gt;. Мы должны проверить, что существует строка &amp;lt;tex&amp;gt;y, |y| = |x|,&amp;lt;/tex&amp;gt; которая ведет из состояния &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt; до какого-нибудь терминального состояния &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_i, y) \in F&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Предположим, что мы прошли &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин автомата, то есть &amp;lt;tex&amp;gt;|x| = n&amp;lt;/tex&amp;gt;. Обозначим за &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; множество всех состояний, с которых можно попасть в терминальные за &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; шагов. Тогда &amp;lt;tex&amp;gt;q_i \in S_n \Leftrightarrow x \in \mathrm{half(L)}&amp;lt;/tex&amp;gt;. Если мы сможем отслеживать &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то сможем определять, верно ли, что &amp;lt;tex&amp;gt;x \in \mathrm{half(L)}&amp;lt;/tex&amp;gt;. Заметим, что &amp;lt;tex&amp;gt;S_0 \equiv F&amp;lt;/tex&amp;gt;. Очевидно мы можем построить &amp;lt;tex&amp;gt;S_{n+1}&amp;lt;/tex&amp;gt; зная &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S_{n+1} = prev(S_n) = \{ q \in Q \mid \exists a \in \Sigma, q' \in S_n, \delta(q, a) = q' \}&amp;lt;/tex&amp;gt; {{---}} множество состояний, из которых есть переход в какое-либо состояние из &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; (по единственному символу). Теперь надо найти способ отслеживать и обновлять &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Построим ДКА &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt;, который будет хранить эту информацию в своих состояниях. Определим &amp;lt;tex&amp;gt;Q' = Q \times 2^Q&amp;lt;/tex&amp;gt;, то есть каждое состояние &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; {{---}} это пара из одиночного состояния из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; и множества состояний из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;. Функцию перехода &amp;lt;tex&amp;gt;\delta'&amp;lt;/tex&amp;gt; автомата &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; определим так, чтобы если по какой-то строке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; длины &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; в автомате &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; мы перешли в состояние &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то по этой же строке в автомате &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; мы перейдем в состояние &amp;lt;tex&amp;gt;(q_i, S_n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; {{---}} множество состояний из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, определенное выше. Вспомним приведенную выше функцию &amp;lt;tex&amp;gt;prev(S_n) = S_{n+1}&amp;lt;/tex&amp;gt;. С ее помощью мы можем определить функцию перехода следующим образом: &amp;lt;tex&amp;gt;\delta'((q, S), a) = (\delta(q, a), prev(S))&amp;lt;/tex&amp;gt;. Начальное состояние &amp;lt;tex&amp;gt;q_0' = (q_0, S_0) = (q_0, F)&amp;lt;/tex&amp;gt;. Множество терминальных состояний {{---}} &amp;lt;tex&amp;gt;F' = \{ (q, S) \mid q \in S, S \in 2^Q \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теперь по индукции не сложно доказать, что &amp;lt;tex&amp;gt;\delta'(q_0', x) = (\delta(q_0, x), S_n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;|x| = n&amp;lt;/tex&amp;gt;. По определению множества терминальных вершин, автомат &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; допускает строку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; тогда и только тогда, когда &amp;lt;tex&amp;gt;\delta(q_0, x) \in S_n&amp;lt;/tex&amp;gt;. Следовательно, автомат &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; допускает язык &amp;lt;tex&amp;gt;\mathrm{half(L)}&amp;lt;/tex&amp;gt;.Таким образом, мы построили ДКА, который допускает язык &amp;lt;tex&amp;gt;\mathrm{half(L)}&amp;lt;/tex&amp;gt;. Следовательно, данный язык является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
=== Язык cycle(L) ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;\mathrm{cycle(L)}&amp;lt;/tex&amp;gt; как множество &amp;lt;tex&amp;gt;\{ w \mid &amp;lt;/tex&amp;gt; цепочку &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; можно представить в виде &amp;lt;tex&amp;gt;w = xy&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;yx \in L \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ 01, 011 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\mathrm{cycle(L)} = \{ 01, 10, 011, 110, 101 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st5&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} [[Регулярные языки: два определения и их эквивалентность|регулярный язык]]. Тогда язык &amp;lt;tex&amp;gt;\mathrm{cycle(L)}&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
[[Файл:Enfa_before.jpg|right|thumb|380px|Рис. 1. Разбиение автомата.]]&lt;br /&gt;
[[Файл:Enfa-after.jpg|right|thumb|380px|Рис. 2. Перестроение.]]&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык, то существует допускающий его ДКА &amp;lt;tex&amp;gt;M = \langle \Sigma , Q , q_0 , F , \delta \rangle &amp;lt;/tex&amp;gt;. Построим из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; [[Автоматы_с_eps-переходами._Eps-замыкание|недетерминированный автомат с &amp;lt;tex&amp;gt;\varepsilon&amp;lt;/tex&amp;gt;-переходами]] следующим образом: рассмотрим состояние &amp;lt;tex&amp;gt;q \in Q&amp;lt;/tex&amp;gt;, из которого есть переходы в другие состояния (то есть начиная с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; можно построить непустое слово, заканчивающееся в терминальной вершине). Тогда если какое-то слово проходит через это состояние, оно может быть зациклено таким образом, что его суффикс, начинающийся с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, станет префиксом нового слова, а префикс, заканчивающийся в &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; {{---}} суффиксом. Разделим автомат на две части &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt; будет содержать все вершины, из которых достижима &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; {{---}} все вершины, которые достижимы из &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; (см. рис. 1). Заметим, что каждая вершина может содержаться в обеих частях одновременно, такое может случиться, если автомат &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; содержит циклы. Теперь перестроим автомат так, что он будет принимать слова &amp;quot;зацикленные&amp;quot; вокруг &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, то есть начинающиеся с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; и после достижения терминальной вершины продолжающиеся с &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; (см. рис. 2). Для этого стартовой вершиной сделаем &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; и построим от нее часть &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt;. Теперь добавим состояние &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; и соединим с ним все терминальные состояния из &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; с помощью &amp;lt;tex&amp;gt;\varepsilon&amp;lt;/tex&amp;gt;-переходов. Далее построим от &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; часть &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt;. Добавим вершину &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt;, эквивалентную &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, и сделаем ее терминальной. Данный автомат принимает слова, зацикленные вокруг выбранной вершины &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. Мы хотим, чтобы автомат принимал слова, зацикленные вокруг любой такой &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. Для этого создадим новую стартовую вершину &amp;lt;tex&amp;gt;q_0'&amp;lt;/tex&amp;gt; и свяжем ее &amp;lt;tex&amp;gt;\varepsilon&amp;lt;/tex&amp;gt;-переходами со всеми перестроенными автоматами (зацикленными вокруг всех подходящих &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;), в том числе и с изначальным автоматом. Построенный автомат допускает язык &amp;lt;tex&amp;gt;\mathrm{cycle(L)}&amp;lt;/tex&amp;gt;, следовательно, данный язык является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Ex_1_before.jpg|left|thumb|260px|Рис. 3. Автомат, принимающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
[[Файл:Ex_1_after.jpg|right|thumb|380px|Рис. 4. Автомат, принимающий язык &amp;lt;tex&amp;gt;\mathrm{cycle(L)}&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
Для лучшего понимания алгоритма перестроения автомата рассмотрим пример.&lt;br /&gt;
&lt;br /&gt;
На рис. 3 представлен автомат, допускающий язык &amp;lt;tex&amp;gt;L = \{ ab, abb, ac \}&amp;lt;/tex&amp;gt;. На рис. 4 показано, как этот автомат был перестроен. Были добавлены части, зацикленные  относительно вершин &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;. Появилась новая стартовая вершина &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, которая связана &amp;lt;tex&amp;gt;\varepsilon&amp;lt;/tex&amp;gt;-переходами с изначальным автоматом и его измененными версиями. Данный автомат распознает язык &amp;lt;tex&amp;gt;\mathrm{cycle(L)} = \{ ab, abb, ac, ba, bba, ca, bab \}&amp;lt;/tex&amp;gt;: первые три слова распознает первая часть, которая совпадает с изначальным автоматом; следующие три {{---}} вторая, перестроенная относительно вершины &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;; последнее слово распознает третья часть, зацикленная относительно вершины &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Язык alt(L, M) ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Пусть &amp;lt;tex&amp;gt;w = w_1 w_2 \dots w_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;x = x_1 x_2 \dots x_n&amp;lt;/tex&amp;gt;. Определим &amp;lt;tex&amp;gt;alternation(w, x) = w_1 x_1 w_2 x_2 \dots w_n x_n&amp;lt;/tex&amp;gt;.}}&lt;br /&gt;
Теперь распространим это определение:&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; {{---}} два языка над одним алфавитом &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;\mathrm{alt(L, M)} = \{ alternation(w, x) \mid |w| = |x|, w \in L, x \in M \}&amp;lt;/tex&amp;gt;.}}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ 10, 00, 111, 1001 \}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M = \{ 11, 0101 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\mathrm{alt(L, M)} = \{ 1101, 0101, 10010011 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st4&lt;br /&gt;
|statement = Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; {{---}} [[Регулярные языки: два определения и их эквивалентность|регулярные языки]]. Тогда &amp;lt;tex&amp;gt;\mathrm{alt(L, M)}&amp;lt;/tex&amp;gt; также является регулярным.&lt;br /&gt;
|proof = Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; {{---}} регулярные языки, то существуют ДКА &amp;lt;tex&amp;gt;D_L = \langle \Sigma , Q_L , q_{0L} , F_L, \delta_L \rangle&amp;lt;/tex&amp;gt;, распознающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;D_M = \langle \Sigma , Q_M , q_{0M} , F_M, \delta_M \rangle&amp;lt;/tex&amp;gt;, распознающий язык &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;. Построим автомат &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt;, который будет распознавать язык &amp;lt;tex&amp;gt;\mathrm{alt(L, M)}&amp;lt;/tex&amp;gt;. Идея следующая: каждое состояние этого автомата будем описывать тремя значениями &amp;lt;tex&amp;gt;(p, q, b)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;p \in Q_L&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;q \in Q_M&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;b \in \{ 1, 0 \}&amp;lt;/tex&amp;gt;. Нам нужно организовать чередование переходов по состояниям автоматов, то есть если мы на определенном шаге перешли от одного состояния автомата &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt; до другого, то на следующем мы обязаны совершить переход по состояниям автомата &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt;. Для этого нам нужно обновлять состояние одного автомата и при этом сохранять состояние другого для следующего перехода. Тут мы будем использовать третье значение: если &amp;lt;tex&amp;gt;b = 0&amp;lt;/tex&amp;gt;, то будет двигаться по состояниям первого автомата, то есть значение &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; при переходе в новое состояние автомата &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt; поменяется, &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; останется неизменной, &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; станет &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;b = 1&amp;lt;/tex&amp;gt;, то, соответственно, все наоборот. То есть у нас будут две функции перехода, выбирать нужную будем в зависимости от четности третьего параметра. Важно, что на каждом шаге мы инвертируем значение &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt;, что гарантирует чередование. Определим автомат &amp;lt;tex&amp;gt;D_{alt} = \langle \Sigma, Q', q_0', F', \delta' \rangle&amp;lt;/tex&amp;gt; следующим образом:&lt;br /&gt;
# &amp;lt;tex&amp;gt;Q' = Q_L \times Q_M \times \{ 0, 1 \}&amp;lt;/tex&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt;q_0' = (q_{0L}, q_{0M}, 0)&amp;lt;/tex&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt;F' = F_L \times F_M \times \{ 0 \}&amp;lt;/tex&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt;\delta'((p, q, 0), a) = (\delta_L(p, a), q, 1)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta'((p, q, 1), a) = (p, \delta_M(q, a), 0)&amp;lt;/tex&amp;gt;&lt;br /&gt;
Стартовая вершина имеет третий параметр &amp;lt;tex&amp;gt;b = 0&amp;lt;/tex&amp;gt;, так как первое значение должно быть получено из автомата &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt;. Аналогично все терминальные вершины должны иметь то же значение последнего параметра, так как количество переходов должно быть четным и последний переход должен был быть осуществлен по автомату &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt;. Функция перехода &amp;lt;tex&amp;gt;\delta'&amp;lt;/tex&amp;gt; использует &amp;lt;tex&amp;gt;\delta_L&amp;lt;/tex&amp;gt; для получения нечетных символов и &amp;lt;tex&amp;gt;\delta_M&amp;lt;/tex&amp;gt; для четных. Таким образом, &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt; состоит из чередующихся символов &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt; принимает &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; тогда и только тогда, когда &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt; последовательно принимает все нечетные символы &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt; {{---}} все четные, а так же &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; имеет четную длину. Следовательно, &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt; распознает язык &amp;lt;tex&amp;gt;\mathrm{alt(L, M)}&amp;lt;/tex&amp;gt;, что доказывает, что &amp;lt;tex&amp;gt;\mathrm{alt(L, M)}&amp;lt;/tex&amp;gt; является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Alt ex 1.jpg|left|thumb|265px|Рис. 5. Автоматы для языков &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
[[Файл:Alt ex 2.jpg|right|thumb|390px|Рис. 6. Автомат, принимающий язык &amp;lt;tex&amp;gt;\mathrm{alt(L, M)}&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
Чтобы более наглядно показать, как строится автомат &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt;, разберем пример. Пусть &amp;lt;tex&amp;gt;L = \{ 1, 11 \}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M = \{ 00 \}&amp;lt;/tex&amp;gt; (см. рис. 5). Все состояния нового автомата представлены на рис. 6. Стартовая вершина &amp;lt;tex&amp;gt;q_0' = (1, 1, 0)&amp;lt;/tex&amp;gt;, множество терминальных вершин {{---}} &amp;lt;tex&amp;gt;F' = \{ (2, 3, 0), (3, 3, 0) \}&amp;lt;/tex&amp;gt;. Мы видим, что построенные по функции &amp;lt;tex&amp;gt;\delta'&amp;lt;/tex&amp;gt; переходы на каждом шаге меняют состояние одного из автоматов, а именно того, по которому происходит переход, сохраняя состояние другого для следующего шага. Таким образом, каждый следующий символ получен из автомата, отличного от того, что был использован на предыдущем шаге. Декартово произведение состояний гарантирует, что мы рассмотрим все состояния и переходы изначальных автоматов. Для данного примера мы получаем, что &amp;lt;tex&amp;gt;\mathrm{alt(L, M)} = \{ 1010 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[Анализ свойств регулярных языков (пустота, совпадение, включение, конечность, подсчет числа слов)]]&lt;br /&gt;
* [[Теорема Клини (совпадение классов автоматных и регулярных языков)]]&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
* Хопкрофт Д., Мотвани Р., Ульман Д. &amp;quot;Введение в теорию автоматов, языков и вычислений&amp;quot;, 2-е изд. : Пер. с англ. — М.:Издательский дом «Вильямс», 2002. {{---}} С. 149 — ISBN 5-8459-0261-4&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;br /&gt;
[[Категория: Свойства конечных автоматов]]&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%BC%D0%BA%D0%BD%D1%83%D1%82%D0%BE%D1%81%D1%82%D1%8C_%D1%80%D0%B5%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%8F%D0%B7%D1%8B%D0%BA%D0%BE%D0%B2_%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE_%D1%80%D0%B0%D0%B7%D0%BB%D0%B8%D1%87%D0%BD%D1%8B%D1%85_%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%B9&amp;diff=58203</id>
		<title>Замкнутость регулярных языков относительно различных операций</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%BC%D0%BA%D0%BD%D1%83%D1%82%D0%BE%D1%81%D1%82%D1%8C_%D1%80%D0%B5%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%8F%D0%B7%D1%8B%D0%BA%D0%BE%D0%B2_%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE_%D1%80%D0%B0%D0%B7%D0%BB%D0%B8%D1%87%D0%BD%D1%8B%D1%85_%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%B9&amp;diff=58203"/>
				<updated>2016-12-22T22:08:42Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Теорема ==&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L_1, L_2&amp;lt;/tex&amp;gt; {{---}} [[Регулярные языки: два определения и их эквивалентность|регулярные языки]] над одним алфавитом &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;. Тогда следующие языки также являются регулярными:&lt;br /&gt;
#Языки, полученные путём применения следующих теоретико-множественных операций:&lt;br /&gt;
#*&amp;lt;tex&amp;gt;L_1 \cup L_2&amp;lt;/tex&amp;gt;,&lt;br /&gt;
#*&amp;lt;tex&amp;gt;\overline{L_1}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
#*&amp;lt;tex&amp;gt;L_1 \cap L_2&amp;lt;/tex&amp;gt;,&lt;br /&gt;
#*&amp;lt;tex&amp;gt;L_1 \setminus L_2&amp;lt;/tex&amp;gt;;&lt;br /&gt;
#&amp;lt;tex&amp;gt;L_1^*&amp;lt;/tex&amp;gt;;&lt;br /&gt;
#&amp;lt;tex&amp;gt;L_1 L_2&amp;lt;/tex&amp;gt;;&lt;br /&gt;
#&amp;lt;tex&amp;gt;\overset{\leftarrow}{L_1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
Как известно, [[Теорема Клини (совпадение классов автоматных и регулярных языков|классы регулярных и автоматных языков совпадают]]. Пусть языки &amp;lt;tex&amp;gt;L_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;L_2&amp;lt;/tex&amp;gt; распознаются автоматами &amp;lt;tex&amp;gt;A_1 = \langle \Sigma , Q_1 , s_1 , T_1 , \delta_1 : Q_1 \times \Sigma \rightarrow 2^{Q_1} \rangle &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;A_2 = \langle \Sigma , Q_2 , s_2 , T_2 , \delta_2 : Q_2 \times \Sigma \rightarrow 2^{Q_2} \rangle &amp;lt;/tex&amp;gt; соответственно.&lt;br /&gt;
#&lt;br /&gt;
#*&amp;lt;tex&amp;gt;L_1 \cup L_2&amp;lt;/tex&amp;gt; является регулярным по определению [[Регулярные языки: два определения и их эквивалентность|регулярных языков]].&lt;br /&gt;
#*Рассмотрим автомат &amp;lt;tex&amp;gt;A_1' = \langle \Sigma , Q_1 , s_1 , Q_1 \setminus T_1 , \delta_1 \rangle &amp;lt;/tex&amp;gt;, то есть автомат &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, в котором терминальные и нетерминальные состояния инвертированы (при таком построении следует помнить, что если в исходном автомате было опущено дьявольское состояние, его нужно явно добавить и сделать допускающим.) Очевидно, он допускает те и только те слова, которые не допускает автомат &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt;, а значит, задаёт язык &amp;lt;tex&amp;gt;\overline{L_1}&amp;lt;/tex&amp;gt;. Таким образом, &amp;lt;tex&amp;gt;\overline{L_1}&amp;lt;/tex&amp;gt; {{---}} регулярный.&lt;br /&gt;
#*&amp;lt;tex&amp;gt;L_1 \cap L_2 = \overline{\overline{L_1} \cup \overline{L_2}}&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;L_1 \cap L_2&amp;lt;/tex&amp;gt; {{---}} регулярный. Также автомат для пересечения языков можно построить явно, используя конструкцию [[Прямое произведение ДКА|произведения автоматов]].&lt;br /&gt;
#*&amp;lt;tex&amp;gt;L_1 \setminus L_2 = L_1 \cap \overline{L_2}&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;L_1 \setminus L_2&amp;lt;/tex&amp;gt; {{---}} регулярный.&lt;br /&gt;
#&amp;lt;tex&amp;gt;L_1^*&amp;lt;/tex&amp;gt; является регулярным по определению [[Регулярные языки: два определения и их эквивалентность|регулярных языков]].&lt;br /&gt;
#&amp;lt;tex&amp;gt;L_1 L_2&amp;lt;/tex&amp;gt; также является регулярным по определению [[Регулярные языки: два определения и их эквивалентность|регулярных языков]].&lt;br /&gt;
#Рассмотрим [[Автоматы_с_eps-переходами._Eps-замыкание|НКА c &amp;lt;tex&amp;gt;\varepsilon&amp;lt;/tex&amp;gt;-переходами]] &amp;lt;tex&amp;gt;A_1' = \langle \Sigma, Q_1, s' , \lbrace s_1 \rbrace, \delta_1' \rangle &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\delta_1' (v,c) = \lbrace u | \delta_1(u,c) = v \rbrace &amp;lt;/tex&amp;gt;; &amp;lt;tex&amp;gt;\delta_1'(s', \varepsilon) = \lbrace T_i \rbrace&amp;lt;/tex&amp;gt;. Если в исходном автомате путь по &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;s_1&amp;lt;/tex&amp;gt; приводил в терминальное состояние, то в новом автомате существует путь по &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; из этого терминального состояния в &amp;lt;tex&amp;gt;s_1&amp;lt;/tex&amp;gt; (и наоборот). Следовательно, этот автомат распознает в точности развернутые слова языка &amp;lt;tex&amp;gt;L_1&amp;lt;/tex&amp;gt;. Тогда язык &amp;lt;tex&amp;gt;\overset{\leftarrow}{L_1}&amp;lt;/tex&amp;gt; {{---}} регулярный.&lt;br /&gt;
}}&lt;br /&gt;
== Примеры доказательств ==&lt;br /&gt;
=== Гомоморфизм цепочек ===&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id=st1&lt;br /&gt;
|statement=&lt;br /&gt;
&amp;lt;tex&amp;gt;L \subset \Sigma_1^*&amp;lt;/tex&amp;gt; {{---}} регулярный , &amp;lt;tex&amp;gt;\varphi:\Sigma_1^* \rightarrow \Sigma_2^* &amp;lt;/tex&amp;gt; {{---}} [[Основные определения: алфавит, слово, язык, конкатенация, свободный моноид слов; операции над языками#Гомоморфизм_языков | гомоморфизм цепочек]]. Тогда  &amp;lt;tex&amp;gt;\varphi(L)&amp;lt;/tex&amp;gt; {{---}} регулярный.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим [[Детерминированные_конечные_автоматы|ДКА]], распознающий &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Заменим в нем все переходы по символам на переходы по их образам при гомоморфизме. Полученный автомат (с переходами по строкам) распознает в точности &amp;lt;tex&amp;gt;\varphi(L)&amp;lt;/tex&amp;gt; и [[Автоматы_с_eps-переходами._Eps-замыкание|имеет эквивалентный ДКА]].&lt;br /&gt;
}}&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id=st2&lt;br /&gt;
|statement=&lt;br /&gt;
&amp;lt;tex&amp;gt;L \subset \Sigma_2^*&amp;lt;/tex&amp;gt; {{---}} регулярный , &amp;lt;tex&amp;gt;\varphi:\Sigma_1^* \rightarrow \Sigma_2^* &amp;lt;/tex&amp;gt; {{---}} [[Основные определения: алфавит, слово, язык, конкатенация, свободный моноид слов; операции над языками#Гомоморфизм_языков | гомоморфизм цепочек]]. Тогда  &amp;lt;tex&amp;gt;\varphi^{-1}(L)&amp;lt;/tex&amp;gt; {{---}} регулярный.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим [[Детерминированные_конечные_автоматы|ДКА]], распознающий &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Отследим для каждого состояния &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и символа &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; строку &amp;lt;tex&amp;gt;\varphi(c)&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt; \langle u,\varphi(c) \rangle \vdash^* \langle v,\varepsilon \rangle&amp;lt;/tex&amp;gt; и положим &amp;lt;tex&amp;gt;\delta (u,c) = v&amp;lt;/tex&amp;gt; в новом автомате (на том же множестве состояний). Автомат с построенной таким образом функцией переходов, очевидно, распознает слова языка &amp;lt;tex&amp;gt;\varphi^{-1}(L)&amp;lt;/tex&amp;gt; и только их.&lt;br /&gt;
}}&lt;br /&gt;
=== Язык half(L) ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;\mathrm{half(L)}&amp;lt;/tex&amp;gt; как множество первых половин цепочек языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть множество &amp;lt;tex&amp;gt;\{ w \mid \exists x : wx \in L \land |w| = |x| \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ \varepsilon, 0010, 011, 010110 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\mathrm{half(L)} = \{ \varepsilon, 00, 010 \}&amp;lt;/tex&amp;gt;. Заметим, что цепочки нечетной длины не влияют на &amp;lt;tex&amp;gt;\mathrm{half(L)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st3&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} [[Регулярные языки: два определения и их эквивалентность|регулярный язык]]. Тогда язык &amp;lt;tex&amp;gt;\mathrm{half(L)}&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык, то существует ДКА &amp;lt;tex&amp;gt;M = \langle \Sigma , Q , q_0 , F , \delta \rangle &amp;lt;/tex&amp;gt;, допускающий его. Рассмотрим строку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Для того, чтобы проверить, что &amp;lt;tex&amp;gt;x \in \mathrm{half(L)}&amp;lt;/tex&amp;gt;, нам надо убедиться, что существует строка &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; такой же длины, что и &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, которая, будучи сконкатенированной с &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, даст строку из &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть если на вход автомату подать &amp;lt;tex&amp;gt;xy&amp;lt;/tex&amp;gt;, то в конце обработки мы окажемся в терминальном состоянии. Предположим, что автомат, закончив обработку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, находится в состоянии &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_0, x) = q_i&amp;lt;/tex&amp;gt;. Мы должны проверить, что существует строка &amp;lt;tex&amp;gt;y, |y| = |x|,&amp;lt;/tex&amp;gt; которая ведет из состояния &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt; до какого-нибудь терминального состояния &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_i, y) \in F&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Предположим, что мы прошли &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин автомата, то есть &amp;lt;tex&amp;gt;|x| = n&amp;lt;/tex&amp;gt;. Обозначим за &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; множество всех состояний, с которых можно попасть в терминальные за &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; шагов. Тогда &amp;lt;tex&amp;gt;q_i \in S_n \Leftrightarrow x \in \mathrm{half(L)}&amp;lt;/tex&amp;gt;. Если мы сможем отслеживать &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то сможем определять, верно ли, что &amp;lt;tex&amp;gt;x \in \mathrm{half(L)}&amp;lt;/tex&amp;gt;. Заметим, что &amp;lt;tex&amp;gt;S_0 \equiv F&amp;lt;/tex&amp;gt;. Очевидно мы можем построить &amp;lt;tex&amp;gt;S_{n+1}&amp;lt;/tex&amp;gt; зная &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S_{n+1} = prev(S_n) = \{ q \in Q \mid \exists a \in \Sigma, q' \in S_n, \delta(q, a) = q' \}&amp;lt;/tex&amp;gt; {{---}} множество состояний, из которых есть переход в какое-либо состояние из &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; (по единственному символу). Теперь надо найти способ отслеживать и обновлять &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Построим ДКА &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt;, который будет хранить эту информацию в своих состояниях. Определим &amp;lt;tex&amp;gt;Q' = Q \times 2^Q&amp;lt;/tex&amp;gt;, то есть каждое состояние &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; {{---}} это пара из одиночного состояния из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; и множества состояний из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;. Функцию перехода &amp;lt;tex&amp;gt;\delta'&amp;lt;/tex&amp;gt; автомата &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; определим так, чтобы если по какой-то строке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; длины &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; в автомате &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; мы перешли в состояние &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то по этой же строке в автомате &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; мы перейдем в состояние &amp;lt;tex&amp;gt;(q_i, S_n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; {{---}} множество состояний из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, определенное выше. Вспомним приведенную выше функцию &amp;lt;tex&amp;gt;prev(S_n) = S_{n+1}&amp;lt;/tex&amp;gt;. С ее помощью мы можем определить функцию перехода следующим образом: &amp;lt;tex&amp;gt;\delta'((q, S), a) = (\delta(q, a), prev(S))&amp;lt;/tex&amp;gt;. Начальное состояние &amp;lt;tex&amp;gt;q_0' = (q_0, S_0) = (q_0, F)&amp;lt;/tex&amp;gt;. Множество терминальных состояний {{---}} &amp;lt;tex&amp;gt;F' = \{ (q, S) \mid q \in S, S \in 2^Q \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теперь по индукции не сложно доказать, что &amp;lt;tex&amp;gt;\delta'(q_0', x) = (\delta(q_0, x), S_n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;|x| = n&amp;lt;/tex&amp;gt;. По определению множества терминальных вершин, автомат &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; допускает строку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; тогда и только тогда, когда &amp;lt;tex&amp;gt;\delta(q_0, x) \in S_n&amp;lt;/tex&amp;gt;. Следовательно, автомат &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; допускает язык &amp;lt;tex&amp;gt;\mathrm{half(L)}&amp;lt;/tex&amp;gt;.Таким образом, мы построили ДКА, который допускает язык &amp;lt;tex&amp;gt;\mathrm{half(L)}&amp;lt;/tex&amp;gt;. Следовательно, данный язык является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
=== Язык cycle(L) ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;\mathrm{cycle(L)}&amp;lt;/tex&amp;gt; как множество &amp;lt;tex&amp;gt;\{ w \mid &amp;lt;/tex&amp;gt; цепочку &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; можно представить в виде &amp;lt;tex&amp;gt;w = xy&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;yx \in L \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ 01, 011 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\mathrm{cycle(L)} = \{ 01, 10, 011, 110, 101 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st5&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} [[Регулярные языки: два определения и их эквивалентность|регулярный язык]]. Тогда язык &amp;lt;tex&amp;gt;\mathrm{cycle(L)}&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
[[Файл:Enfa_before.jpg|right|thumb|380px|Рис. 1. Разбиение автомата.]]&lt;br /&gt;
[[Файл:Enfa-after.jpg|right|thumb|380px|Рис. 2. Перестроение.]]&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык, то существует допускающий его ДКА &amp;lt;tex&amp;gt;M = \langle \Sigma , Q , q_0 , F , \delta \rangle &amp;lt;/tex&amp;gt;. Построим из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; [[Автоматы_с_eps-переходами._Eps-замыкание|недетерминированный автомат с &amp;lt;tex&amp;gt;\varepsilon&amp;lt;/tex&amp;gt;-переходами]] следующим образом: рассмотрим состояние &amp;lt;tex&amp;gt;q \in Q&amp;lt;/tex&amp;gt;, из которого есть переходы в другие состояния (то есть начиная с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; можно построить непустое слово, заканчивающееся в терминальной вершине). Тогда если какое-то слово проходит через это состояние, оно может быть зациклено таким образом, что его суффикс, начинающийся с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, станет префиксом нового слова, а префикс, заканчивающийся в &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; {{---}} суффиксом. Разделим автомат на две части &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt; будет содержать все вершины, из которых достижима &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; {{---}} все вершины, которые достижимы из &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; (см. рис. 1). Заметим, что каждая вершина может содержаться в обеих частях одновременно, такое может случиться, если автомат &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; содержит циклы. Теперь перестроим автомат так, что он будет принимать слова &amp;quot;зацикленные&amp;quot; вокруг &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, то есть начинающиеся с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; и после достижения терминальной вершины продолжающиеся с &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; (см. рис. 2). Для этого стартовой вершиной сделаем &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; и построим от нее часть &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt;. Теперь добавим состояние &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; и соединим с ним все терминальные состояния из &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; с помощью &amp;lt;tex&amp;gt;\varepsilon&amp;lt;/tex&amp;gt;-переходов. Далее построим от &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; часть &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt;. Добавим вершину &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt;, эквивалентную &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, и сделаем ее терминальной. Данный автомат принимает слова, зацикленные вокруг выбранной вершины &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. Мы хотим, чтобы автомат принимал слова, зацикленные вокруг любой такой &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. Для этого создадим новую стартовую вершину &amp;lt;tex&amp;gt;q_0'&amp;lt;/tex&amp;gt; и свяжем ее &amp;lt;tex&amp;gt;\varepsilon&amp;lt;/tex&amp;gt;-переходами со всеми перестроенными автоматами (зацикленными вокруг всех подходящих &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;), в том числе и с изначальным автоматом. Построенный автомат допускает язык &amp;lt;tex&amp;gt;\mathrm{cycle(L)}&amp;lt;/tex&amp;gt;, следовательно, данный язык является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Ex_1_before.jpg|left|thumb|260px|Рис. 3. Автомат, принимающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
[[Файл:Ex_1_after.jpg|right|thumb|380px|Рис. 4. Автомат, принимающий язык &amp;lt;tex&amp;gt;\mathrm{cycle(L)}&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
Для лучшего понимания алгоритма перестроения автомата рассмотрим пример.&lt;br /&gt;
&lt;br /&gt;
На рис. 3 представлен автомат, допускающий язык &amp;lt;tex&amp;gt;L = \{ ab, abb, ac \}&amp;lt;/tex&amp;gt;. На рис. 4 показано, как этот автомат был перестроен. Были добавлены части, зацикленные  относительно вершин &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;. Появилась новая стартовая вершина &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, которая связана &amp;lt;tex&amp;gt;\varepsilon&amp;lt;/tex&amp;gt;-переходами с изначальным автоматом и его измененными версиями. Данный автомат распознает язык &amp;lt;tex&amp;gt;\mathrm{cycle(L)} = \{ ab, abb, ac, ba, bba, ca, bab \}&amp;lt;/tex&amp;gt;: первые три слова распознает первая часть, которая совпадает с изначальным автоматом; следующие три {{---}} вторая, перестроенная относительно вершины &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;; последнее слово распознает третья часть, зацикленная относительно вершины &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Язык alt(L, M) ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Пусть &amp;lt;tex&amp;gt;w = w_1 w_2 \dots w_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;x = x_1 x_2 \dots x_n&amp;lt;/tex&amp;gt;. Определим &amp;lt;tex&amp;gt;alternation(w, x) = w_1 x_1 w_2 x_2 \dots w_n x_n&amp;lt;/tex&amp;gt;.}}&lt;br /&gt;
Теперь распространим это определение:&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; {{---}} два языка над одним алфавитом &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;\mathrm{alt(L, M)} = \{ alternation(w, x) \mid |w| = |x|, w \in L, x \in M \}&amp;lt;/tex&amp;gt;.}}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ 10, 00, 111, 1001 \}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M = \{ 11, 0101 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\mathrm{alt(L, M)} = \{ 1101, 0101, 10010011 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st4&lt;br /&gt;
|statement = Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; {{---}} [[Регулярные языки: два определения и их эквивалентность|регулярные языки]]. Тогда &amp;lt;tex&amp;gt;\mathrm{alt(L, M)}&amp;lt;/tex&amp;gt; также является регулярным.&lt;br /&gt;
|proof = Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; {{---}} регулярные языки, то существуют ДКА &amp;lt;tex&amp;gt;D_L = \langle \Sigma , Q_L , q_{0L} , F_L, \delta_L \rangle&amp;lt;/tex&amp;gt;, распознающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;D_M = \langle \Sigma , Q_M , q_{0M} , F_M, \delta_M \rangle&amp;lt;/tex&amp;gt;, распознающий язык &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;. Построим автомат &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt;, который будет распознавать язык &amp;lt;tex&amp;gt;\mathrm{alt(L, M)}&amp;lt;/tex&amp;gt;. Идея следующая: каждое состояние этого автомата будем описывать тремя значениями &amp;lt;tex&amp;gt;(p, q, b)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;p \in Q_L&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;q \in Q_M&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;b \in \{ 1, 0 \}&amp;lt;/tex&amp;gt;. Нам нужно организовать чередование переходов по состояниям автоматов, то есть если мы на определенном шаге перешли от одного состояния автомата &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt; до другого, то на следующем мы обязаны совершить переход по состояниям автомата &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt;. Для этого нам нужно обновлять состояние одного автомата и при этом сохранять состояние другого для следующего перехода. Тут мы будем использовать третье значение: если &amp;lt;tex&amp;gt;b = 0&amp;lt;/tex&amp;gt;, то будет двигаться по состояниям первого автомата, то есть значение &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; при переходе в новое состояние автомата &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt; поменяется, &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; останется неизменной, &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; станет &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;b = 1&amp;lt;/tex&amp;gt;, то, соответственно, все наоборот. То есть у нас будут две функции перехода, выбирать нужную будем в зависимости от четности третьего параметра. Важно, что на каждом шаге мы инвертируем значение &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt;, что гарантирует чередование. Определим автомат &amp;lt;tex&amp;gt;D_{alt} = \langle \Sigma, Q', q_0', F', \delta' \rangle&amp;lt;/tex&amp;gt; следующим образом:&lt;br /&gt;
# &amp;lt;tex&amp;gt;Q' = Q_L \times Q_M \times \{ 0, 1 \}&amp;lt;/tex&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt;q_0' = (q_{0L}, q_{0M}, 0)&amp;lt;/tex&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt;F' = F_L \times F_M \times \{ 0 \}&amp;lt;/tex&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt;\delta'((p, q, 0), a) = (\delta_L(p, a), q, 1)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta'((p, q, 1), a) = (p, \delta_M(q, a), 0)&amp;lt;/tex&amp;gt;&lt;br /&gt;
Стартовая вершина имеет третий параметр &amp;lt;tex&amp;gt;b = 0&amp;lt;/tex&amp;gt;, так как первое значение должно быть получено из автомата &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt;. Аналогично все терминальные вершины должны иметь то же значение последнего параметра, так как количество переходов должно быть четным и последний переход должен был быть осуществлен по автомату &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt;. Функция перехода &amp;lt;tex&amp;gt;\delta'&amp;lt;/tex&amp;gt; использует &amp;lt;tex&amp;gt;\delta_L&amp;lt;/tex&amp;gt; для получения нечетных символов и &amp;lt;tex&amp;gt;\delta_M&amp;lt;/tex&amp;gt; для четных. Таким образом, &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt; состоит из чередующихся символов &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt; принимает &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; тогда и только тогда, когда &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt; последовательно принимает все нечетные символы &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt; {{---}} все четные, а так же &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; имеет четную длину. Следовательно, &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt; распознает язык &amp;lt;tex&amp;gt;\mathrm{alt(L, M)}&amp;lt;/tex&amp;gt;, что доказывает, что &amp;lt;tex&amp;gt;\mathrm{alt(L, M)}&amp;lt;/tex&amp;gt; является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Alt ex 1.jpg|left|thumb|265px|Рис. 5. Автоматы для языков &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
[[Файл:Alt ex 2.jpg|right|thumb|390px|Рис. 6. Автомат, принимающий язык &amp;lt;tex&amp;gt;\mathrm{alt(L, M)}&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
Чтобы более наглядно показать, как строится автомат &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt;, разберем пример. Пусть &amp;lt;tex&amp;gt;L = \{ 1, 11 \}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M = \{ 00 \}&amp;lt;/tex&amp;gt; (см. рис. 5). Все состояния нового автомата представлены на рис. 6. Стартовая вершина &amp;lt;tex&amp;gt;q_0' = (1, 1, 0)&amp;lt;/tex&amp;gt;, множество терминальных вершин {{---}} &amp;lt;tex&amp;gt;F' = \{ (2, 3, 0), (3, 3, 0) \}&amp;lt;/tex&amp;gt;. Мы видим, что построенные по функции &amp;lt;tex&amp;gt;\delta'&amp;lt;/tex&amp;gt; переходы на каждом шаге меняют состояние одного из автоматов, а именно того, по которому происходит переход, сохраняя состояние другого для следующего шага. Таким образом, каждый следующий символ получен из автомата, отличного от того, что был использован на предыдущем шаге. Декартово произведение состояний гарантирует, что мы рассмотрим все состояния и переходы изначальных автоматов. Для данного примера мы получаем, что &amp;lt;tex&amp;gt;\mathrm{alt(L, M)} = \{ 1010 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[Анализ свойств регулярных языков (пустота, совпадение, включение, конечность, подсчет числа слов)]]&lt;br /&gt;
* [[Теорема Клини (совпадение классов автоматных и регулярных языков)]]&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
* Хопкрофт Д., Мотвани Р., Ульман Д. &amp;quot;Введение в теорию автоматов, языков и вычислений&amp;quot;, 2-е изд. : Пер. с англ. — М.:Издательский дом «Вильямс», 2002. {{---}} С. 149 — ISBN 5-8459-0261-4&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;br /&gt;
[[Категория: Свойства конечных автоматов]]&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%BC%D0%BA%D0%BD%D1%83%D1%82%D0%BE%D1%81%D1%82%D1%8C_%D1%80%D0%B5%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%8F%D0%B7%D1%8B%D0%BA%D0%BE%D0%B2_%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE_%D1%80%D0%B0%D0%B7%D0%BB%D0%B8%D1%87%D0%BD%D1%8B%D1%85_%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%B9&amp;diff=58196</id>
		<title>Замкнутость регулярных языков относительно различных операций</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%97%D0%B0%D0%BC%D0%BA%D0%BD%D1%83%D1%82%D0%BE%D1%81%D1%82%D1%8C_%D1%80%D0%B5%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D1%85_%D1%8F%D0%B7%D1%8B%D0%BA%D0%BE%D0%B2_%D0%BE%D1%82%D0%BD%D0%BE%D1%81%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE_%D1%80%D0%B0%D0%B7%D0%BB%D0%B8%D1%87%D0%BD%D1%8B%D1%85_%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%B9&amp;diff=58196"/>
				<updated>2016-12-22T21:16:54Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Теорема ==&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L_1, L_2&amp;lt;/tex&amp;gt; {{---}} [[Регулярные языки: два определения и их эквивалентность|регулярные языки]] над одним алфавитом &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;. Тогда следующие языки также являются регулярными:&lt;br /&gt;
#Языки, полученные путём применения следующих теоретико-множественных операций:&lt;br /&gt;
#*&amp;lt;tex&amp;gt;L_1 \cup L_2&amp;lt;/tex&amp;gt;,&lt;br /&gt;
#*&amp;lt;tex&amp;gt;\overline{L_1}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
#*&amp;lt;tex&amp;gt;L_1 \cap L_2&amp;lt;/tex&amp;gt;,&lt;br /&gt;
#*&amp;lt;tex&amp;gt;L_1 \setminus L_2&amp;lt;/tex&amp;gt;;&lt;br /&gt;
#&amp;lt;tex&amp;gt;L_1^*&amp;lt;/tex&amp;gt;;&lt;br /&gt;
#&amp;lt;tex&amp;gt;L_1 L_2&amp;lt;/tex&amp;gt;;&lt;br /&gt;
#&amp;lt;tex&amp;gt;\overset{\leftarrow}{L_1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
Как известно, [[Теорема Клини (совпадение классов автоматных и регулярных языков|классы регулярных и автоматных языков совпадают]]. Пусть языки &amp;lt;tex&amp;gt;L_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;L_2&amp;lt;/tex&amp;gt; распознаются автоматами &amp;lt;tex&amp;gt;A_1 = \langle \Sigma , Q_1 , s_1 , T_1 , \delta_1 : Q_1 \times \Sigma \rightarrow 2^{Q_1} \rangle &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;A_2 = \langle \Sigma , Q_2 , s_2 , T_2 , \delta_2 : Q_2 \times \Sigma \rightarrow 2^{Q_2} \rangle &amp;lt;/tex&amp;gt; соответственно.&lt;br /&gt;
#&lt;br /&gt;
#*&amp;lt;tex&amp;gt;L_1 \cup L_2&amp;lt;/tex&amp;gt; является регулярным по определению [[Регулярные языки: два определения и их эквивалентность|регулярных языков]].&lt;br /&gt;
#*Рассмотрим автомат &amp;lt;tex&amp;gt;A_1' = \langle \Sigma , Q_1 , s_1 , Q_1 \setminus T_1 , \delta_1 \rangle &amp;lt;/tex&amp;gt;, то есть автомат &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, в котором терминальные и нетерминальные состояния инвертированы (при таком построении следует помнить, что если в исходном автомате было опущено дьявольское состояние, его нужно явно добавить и сделать допускающим.) Очевидно, он допускает те и только те слова, которые не допускает автомат &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt;, а значит, задаёт язык &amp;lt;tex&amp;gt;\overline{L_1}&amp;lt;/tex&amp;gt;. Таким образом, &amp;lt;tex&amp;gt;\overline{L_1}&amp;lt;/tex&amp;gt; {{---}} регулярный.&lt;br /&gt;
#*&amp;lt;tex&amp;gt;L_1 \cap L_2 = \overline{\overline{L_1} \cup \overline{L_2}}&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;L_1 \cap L_2&amp;lt;/tex&amp;gt; {{---}} регулярный. Также автомат для пересечения языков можно построить явно, используя конструкцию [[Прямое произведение ДКА|произведения автоматов]].&lt;br /&gt;
#*&amp;lt;tex&amp;gt;L_1 \setminus L_2 = L_1 \cap \overline{L_2}&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;L_1 \setminus L_2&amp;lt;/tex&amp;gt; {{---}} регулярный.&lt;br /&gt;
#&amp;lt;tex&amp;gt;L_1^*&amp;lt;/tex&amp;gt; является регулярным по определению [[Регулярные языки: два определения и их эквивалентность|регулярных языков]].&lt;br /&gt;
#&amp;lt;tex&amp;gt;L_1 L_2&amp;lt;/tex&amp;gt; также является регулярным по определению [[Регулярные языки: два определения и их эквивалентность|регулярных языков]].&lt;br /&gt;
#Рассмотрим [[Автоматы_с_eps-переходами._Eps-замыкание|НКА c &amp;lt;tex&amp;gt;\varepsilon&amp;lt;/tex&amp;gt;-переходами]] &amp;lt;tex&amp;gt;A_1' = \langle \Sigma, Q_1, s' , \lbrace s_1 \rbrace, \delta_1' \rangle &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\delta_1' (v,c) = \lbrace u | \delta_1(u,c) = v \rbrace &amp;lt;/tex&amp;gt;; &amp;lt;tex&amp;gt;\delta_1'(s', \varepsilon) = \lbrace T_i \rbrace&amp;lt;/tex&amp;gt;. Если в исходном автомате путь по &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;s_1&amp;lt;/tex&amp;gt; приводил в терминальное состояние, то в новом автомате существует путь по &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; из этого терминального состояния в &amp;lt;tex&amp;gt;s_1&amp;lt;/tex&amp;gt; (и наоборот). Следовательно, этот автомат распознает в точности развернутые слова языка &amp;lt;tex&amp;gt;L_1&amp;lt;/tex&amp;gt;. Тогда язык &amp;lt;tex&amp;gt;\overset{\leftarrow}{L_1}&amp;lt;/tex&amp;gt; {{---}} регулярный.&lt;br /&gt;
}}&lt;br /&gt;
== Примеры доказательств ==&lt;br /&gt;
=== Гомоморфизм цепочек ===&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id=st1&lt;br /&gt;
|statement=&lt;br /&gt;
&amp;lt;tex&amp;gt;L \subset \Sigma_1^*&amp;lt;/tex&amp;gt; {{---}} регулярный , &amp;lt;tex&amp;gt;\varphi:\Sigma_1^* \rightarrow \Sigma_2^* &amp;lt;/tex&amp;gt; {{---}} [[Основные определения: алфавит, слово, язык, конкатенация, свободный моноид слов; операции над языками#Гомоморфизм_языков | гомоморфизм цепочек]]. Тогда  &amp;lt;tex&amp;gt;\varphi(L)&amp;lt;/tex&amp;gt; {{---}} регулярный.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим [[Детерминированные_конечные_автоматы|ДКА]], распознающий &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Заменим в нем все переходы по символам на переходы по их образам при гомоморфизме. Полученный автомат (с переходами по строкам) распознает в точности &amp;lt;tex&amp;gt;\varphi(L)&amp;lt;/tex&amp;gt; и [[Автоматы_с_eps-переходами._Eps-замыкание|имеет эквивалентный ДКА]].&lt;br /&gt;
}}&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id=st2&lt;br /&gt;
|statement=&lt;br /&gt;
&amp;lt;tex&amp;gt;L \subset \Sigma_2^*&amp;lt;/tex&amp;gt; {{---}} регулярный , &amp;lt;tex&amp;gt;\varphi:\Sigma_1^* \rightarrow \Sigma_2^* &amp;lt;/tex&amp;gt; {{---}} [[Основные определения: алфавит, слово, язык, конкатенация, свободный моноид слов; операции над языками#Гомоморфизм_языков | гомоморфизм цепочек]]. Тогда  &amp;lt;tex&amp;gt;\varphi^{-1}(L)&amp;lt;/tex&amp;gt; {{---}} регулярный.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим [[Детерминированные_конечные_автоматы|ДКА]], распознающий &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Отследим для каждого состояния &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и символа &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; строку &amp;lt;tex&amp;gt;\varphi(c)&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt; \langle u,\varphi(c) \rangle \vdash^* \langle v,\varepsilon \rangle&amp;lt;/tex&amp;gt; и положим &amp;lt;tex&amp;gt;\delta (u,c) = v&amp;lt;/tex&amp;gt; в новом автомате (на том же множестве состояний). Автомат с построенной таким образом функцией переходов, очевидно, распознает слова языка &amp;lt;tex&amp;gt;\varphi^{-1}(L)&amp;lt;/tex&amp;gt; и только их.&lt;br /&gt;
}}&lt;br /&gt;
=== Язык half(L) ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;\mathrm{half(L)}&amp;lt;/tex&amp;gt; как множество первых половин цепочек языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть множество &amp;lt;tex&amp;gt;\{ w \mid &amp;lt;/tex&amp;gt; существует &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, для которой &amp;lt;tex&amp;gt;wx \in L&amp;lt;/tex&amp;gt;, причем &amp;lt;tex&amp;gt;|w| = |x| \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ \varepsilon, 0010, 011, 010110 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\mathrm{half(L)} = \{ \varepsilon, 00, 010 \}&amp;lt;/tex&amp;gt;. Заметим, что цепочки нечетной длины не влияют на &amp;lt;tex&amp;gt;\mathrm{half(L)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st3&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} [[Регулярные языки: два определения и их эквивалентность|регулярный язык]]. Тогда язык &amp;lt;tex&amp;gt;\mathrm{half(L)}&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык, то существует ДКА &amp;lt;tex&amp;gt;M = \langle \Sigma , Q , q_0 , F , \delta \rangle &amp;lt;/tex&amp;gt;, допускающий его. Рассмотрим строку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Для того, чтобы проверить, что &amp;lt;tex&amp;gt;x \in \mathrm{half(L)}&amp;lt;/tex&amp;gt;, нам надо убедиться, что существует строка &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; такой же длины, что и &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, которая, будучи сконкатенированной с &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, даст строку из &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть если на вход автомату подать &amp;lt;tex&amp;gt;xy&amp;lt;/tex&amp;gt;, то в конце обработки мы окажемся в терминальном состоянии. Предположим, что автомат, закончив обработку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, находится в состоянии &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_0, x) = q_i&amp;lt;/tex&amp;gt;. Мы должны проверить, что существует строка &amp;lt;tex&amp;gt;y, |y| = |x|,&amp;lt;/tex&amp;gt; которая ведет из состояния &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt; до какого-нибудь терминального состояния &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_i, y) \in F&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Предположим, что мы прошли &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин автомата, то есть &amp;lt;tex&amp;gt;|x| = n&amp;lt;/tex&amp;gt;. Обозначим за &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; множество всех состояний, с которых можно попасть в терминальные за &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; шагов. Тогда &amp;lt;tex&amp;gt;q_i \in S_n \Leftrightarrow x \in \mathrm{half(L)}&amp;lt;/tex&amp;gt;. Если мы сможем отслеживать &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то сможем определять, верно ли, что &amp;lt;tex&amp;gt;x \in \mathrm{half(L)}&amp;lt;/tex&amp;gt;. Заметим, что &amp;lt;tex&amp;gt;S_0 \equiv F&amp;lt;/tex&amp;gt;. Очевидно мы можем построить &amp;lt;tex&amp;gt;S_{n+1}&amp;lt;/tex&amp;gt; зная &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S_{n+1} = prev(S_n) = \{ q \in Q \mid \exists a \in \Sigma, q' \in S_n, \delta(q, a) = q' \}&amp;lt;/tex&amp;gt; {{---}} множество состояний, из которых есть переход в какое-либо состояние из &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; (по единственному символу). Теперь надо найти способ отслеживать и обновлять &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Построим ДКА &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt;, который будет хранить эту информацию в своих состояниях. Определим &amp;lt;tex&amp;gt;Q' = Q \times 2^Q&amp;lt;/tex&amp;gt;, то есть каждое состояние &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; {{---}} это пара из одиночного состояния из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; и множества состояний из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;. Функцию перехода &amp;lt;tex&amp;gt;\delta'&amp;lt;/tex&amp;gt; автомата &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; определим так, чтобы если по какой-то строке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; длины &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; в автомате &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; мы перешли в состояние &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то по этой же строке в автомате &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; мы перейдем в состояние &amp;lt;tex&amp;gt;(q_i, S_n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; {{---}} множество состояний из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, определенное выше. Вспомним приведенную выше функцию &amp;lt;tex&amp;gt;prev(S_n) = S_{n+1}&amp;lt;/tex&amp;gt;. С ее помощью мы можем определить функцию перехода следующим образом: &amp;lt;tex&amp;gt;\delta'((q, S), a) = (\delta(q, a), prev(S))&amp;lt;/tex&amp;gt;. Начальное состояние &amp;lt;tex&amp;gt;q_0' = (q_0, S_0) = (q_0, F)&amp;lt;/tex&amp;gt;. Множество терминальных состояний {{---}} &amp;lt;tex&amp;gt;F' = \{ (q, S) \mid q \in S, S \in 2^Q \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теперь по индукции не сложно доказать, что &amp;lt;tex&amp;gt;\delta'(q_0', x) = (\delta(q_0, x), S_n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;|x| = n&amp;lt;/tex&amp;gt;. По определению множества терминальных вершин, автомат &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; допускает строку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; тогда и только тогда, когда &amp;lt;tex&amp;gt;\delta(q_0, x) \in S_n&amp;lt;/tex&amp;gt;. Следовательно, автомат &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; допускает язык &amp;lt;tex&amp;gt;\mathrm{half(L)}&amp;lt;/tex&amp;gt;.Таким образом, мы построили ДКА, который допускает язык &amp;lt;tex&amp;gt;\mathrm{half(L)}&amp;lt;/tex&amp;gt;. Следовательно, данный язык является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
=== Язык cycle(L) ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;\mathrm{cycle(L)}&amp;lt;/tex&amp;gt; как множество &amp;lt;tex&amp;gt;\{ w \mid &amp;lt;/tex&amp;gt; цепочку &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; можно представить в виде &amp;lt;tex&amp;gt;w = xy&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;yx \in L \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ 01, 011 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\mathrm{cycle(L)} = \{ 01, 10, 011, 110, 101 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st5&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} [[Регулярные языки: два определения и их эквивалентность|регулярный язык]]. Тогда язык &amp;lt;tex&amp;gt;\mathrm{cycle(L)}&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
[[Файл:Enfa_before.jpg|right|thumb|380px|Рис. 1. Разбиение автомата.]]&lt;br /&gt;
[[Файл:Enfa-after.jpg|right|thumb|380px|Рис. 2. Перестроение.]]&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык, то существует допускающий его ДКА &amp;lt;tex&amp;gt;M = \langle \Sigma , Q , q_0 , F , \delta \rangle &amp;lt;/tex&amp;gt;. Построим из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; [[Автоматы_с_eps-переходами._Eps-замыкание|недетерминированный автомат с &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходами]] следующим образом: рассмотрим состояние &amp;lt;tex&amp;gt;q \in Q&amp;lt;/tex&amp;gt;, из которого есть переходы в другие состояния (то есть начиная с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; можно построить непустое слово, заканчивающееся в терминальной вершине). Тогда если какое-то слово проходит через это состояние, оно может быть зациклено таким образом, что его суффикс, начинающийся с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, станет префиксом нового слова, а префикс, заканчивающийся в &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; {{---}} суффиксом. Разделим автомат на две части &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt; будет содержать все вершины, из которых достижима &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; {{---}} все вершины, которые достижимы из &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; (см. рис. 1). Заметим, что каждая вершина может содержаться в обеих частях одновременно, такое может случиться, если автомат &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; содержит циклы. Теперь перестроим автомат так, что он будет принимать слова &amp;quot;зацикленные&amp;quot; вокруг &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, то есть начинающиеся с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; и после достижения терминальной вершины продолжающиеся с &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; (см. рис. 2). Для этого стартовой вершиной сделаем &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; и построим от нее часть &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt;. Теперь добавим состояние &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; и соединим с ним все терминальные состояния из &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; с помощью &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходов. Далее построим от &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; часть &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt;. Добавим вершину &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt;, эквивалентную &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, и сделаем ее терминальной. Данный автомат принимает слова, зацикленные вокруг выбранной вершины &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. Мы хотим, чтобы автомат принимал слова, зацикленные вокруг любой такой &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. Для этого создадим новую стартовую вершину &amp;lt;tex&amp;gt;q_0'&amp;lt;/tex&amp;gt; и свяжем ее &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходами со всеми перестроенными автоматами (зацикленными вокруг всех подходящих &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;), в том числе и с изначальным автоматом. Построенный автомат допускает язык &amp;lt;tex&amp;gt;\mathrm{cycle(L)}&amp;lt;/tex&amp;gt;, следовательно, данный язык является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Ex_1_before.jpg|left|thumb|260px|Рис. 3. Автомат, принимающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
[[Файл:Ex_1_after.jpg|right|thumb|380px|Рис. 4. Автомат, принимающий язык &amp;lt;tex&amp;gt;\mathrm{cycle(L)}&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
Для лучшего понимания алгоритма перестроения автомата рассмотрим пример.&lt;br /&gt;
&lt;br /&gt;
На рис. 3 представлен автомат, допускающий язык &amp;lt;tex&amp;gt;L = \{ ab, abb, ac \}&amp;lt;/tex&amp;gt;. На рис. 4 показано, как этот автомат был перестроен. Были добавлены части, зацикленные  относительно вершин &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;. Появилась новая стартовая вершина &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, которая связана &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходами с изначальным автоматом и его измененными версиями. Данный автомат распознает язык &amp;lt;tex&amp;gt;\mathrm{cycle(L)} = \{ ab, abb, ac, ba, bba, ca, bab \}&amp;lt;/tex&amp;gt;: первые три слова распознает первая часть, которая совпадает с изначальным автоматом; следующие три {{---}} вторая, перестроенная относительно вершины &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;; последнее слово распознает третья часть, зацикленная относительно вершины &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Язык alt(L, M) ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Пусть &amp;lt;tex&amp;gt;w = w_1 w_2 \dots w_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;x = x_1 x_2 \dots x_n&amp;lt;/tex&amp;gt;. Определим &amp;lt;tex&amp;gt;alt(w, x) = w_1 x_1 w_2 x_2 \dots w_n x_n&amp;lt;/tex&amp;gt;. Распространим это определение на языки следующим образом: пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; {{---}} два языка над одним алфавитом &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;\mathrm{alt(L, M)} = \{ alt(w, x) \mid |w| = |x|, w \in L, x \in M \}&amp;lt;/tex&amp;gt;.}}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ 10, 00, 111, 1001 \}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M = \{ 11, 0101 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\mathrm{alt(L, M)} = \{ 1101, 0101, 10010011 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st4&lt;br /&gt;
|statement = Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; {{---}} [[Регулярные языки: два определения и их эквивалентность|регулярные языки]]. Тогда &amp;lt;tex&amp;gt;\mathrm{alt(L, M)}&amp;lt;/tex&amp;gt; также является регулярным.&lt;br /&gt;
|proof = Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; {{---}} регулярные языки, то существуют ДКА &amp;lt;tex&amp;gt;D_L = \langle \Sigma , Q_L , q_{0L} , F_L, \delta_L \rangle&amp;lt;/tex&amp;gt;, распознающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;D_M = \langle \Sigma , Q_M , q_{0M} , F_M, \delta_M \rangle&amp;lt;/tex&amp;gt;, распознающий язык &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;. Построим автомат &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt;, который будет распознавать язык &amp;lt;tex&amp;gt;\mathrm{alt(L, M)}&amp;lt;/tex&amp;gt;. Идея следующая: каждое состояние этого автомата будем описывать тремя значениями &amp;lt;tex&amp;gt;(p, q, b)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;p \in Q_L&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;q \in Q_M&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;b \in \{ 1, 0 \}&amp;lt;/tex&amp;gt;. Нам нужно организовать чередование переходов по состояниям автоматов, то есть если мы на определенном шаге перешли от одного состояния автомата &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt; до другого, то на следующем мы обязаны совершить переход по состояниям автомата &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt;. Для этого нам нужно обновлять состояние одного автомата и при этом сохранять состояние другого для следующего перехода. Тут мы будем использовать третье значение: если &amp;lt;tex&amp;gt;b = 0&amp;lt;/tex&amp;gt;, то будет двигаться по состояниям первого автомата, то есть значение &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; при переходе в новое состояние автомата &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt; поменяется, &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; останется неизменной, &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; станет &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;b = 1&amp;lt;/tex&amp;gt;, то, соответственно, все наоборот. То есть у нас будут две функции перехода, выбирать нужную будем в зависимости от четности третьего параметра. Важно, что на каждом шаге мы инвертируем значение &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt;, что гарантирует чередование. Определим автомат &amp;lt;tex&amp;gt;D_{alt} = \langle \Sigma, Q', q_0', F', \delta' \rangle&amp;lt;/tex&amp;gt; следующим образом:&lt;br /&gt;
# &amp;lt;tex&amp;gt;Q' = Q_L \times Q_M \times \{ 0, 1 \}&amp;lt;/tex&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt;q_0' = (q_{0L}, q_{0M}, 0)&amp;lt;/tex&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt;F' = F_L \times F_M \times \{ 0 \}&amp;lt;/tex&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt;\delta'((p, q, 0), a) = (\delta_L(p, a), q, 1)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta'((p, q, 1), a) = (p, \delta_M(q, a), 0)&amp;lt;/tex&amp;gt;&lt;br /&gt;
Стартовая вершина имеет третий параметр &amp;lt;tex&amp;gt;b = 0&amp;lt;/tex&amp;gt;, так как первое значение должно быть получено из автомата &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt;. Аналогично все терминальные вершины должны иметь то же значение последнего параметра, так как количество переходов должно быть четным и последний переход должен был быть осуществлен по автомату &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt;. Функция перехода &amp;lt;tex&amp;gt;\delta'&amp;lt;/tex&amp;gt; использует &amp;lt;tex&amp;gt;\delta_L&amp;lt;/tex&amp;gt; для получения нечетных символов и &amp;lt;tex&amp;gt;\delta_M&amp;lt;/tex&amp;gt; для четных. Таким образом, &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt; состоит из чередующихся символов &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt; принимает &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; тогда и только тогда, когда &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt; последовательно принимает все нечетные символы &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt; {{---}} все четные, а так же &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; имеет четную длину. Следовательно, &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt; распознает язык &amp;lt;tex&amp;gt;\mathrm{alt(L, M)}&amp;lt;/tex&amp;gt;, что доказывает, что &amp;lt;tex&amp;gt;\mathrm{alt(L, M)}&amp;lt;/tex&amp;gt; является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Alt ex 1.jpg|left|thumb|265px|Рис. 5. Автоматы для языков &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
[[Файл:Alt ex 2.jpg|right|thumb|390px|Рис. 6. Автомат, принимающий язык &amp;lt;tex&amp;gt;\mathrm{alt(L, M)}&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
Чтобы более наглядно показать, как строится автомат &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt;, разберем пример. Пусть &amp;lt;tex&amp;gt;L = \{ 1, 11 \}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M = \{ 00 \}&amp;lt;/tex&amp;gt; (см. рис. 5). Все состояния нового автомата представлены на рис. 6. Стартовая вершина &amp;lt;tex&amp;gt;q_0' = (1, 1, 0)&amp;lt;/tex&amp;gt;, множество терминальных вершин {{---}} &amp;lt;tex&amp;gt;F' = \{ (2, 3, 0), (3, 3, 0) \}&amp;lt;/tex&amp;gt;. Мы видим, что построенные по функции &amp;lt;tex&amp;gt;\delta'&amp;lt;/tex&amp;gt; переходы на каждом шаге меняют состояние одного из автоматов, а именно того, по которому происходит переход, сохраняя состояние другого для следующего шага. Таким образом, каждый следующий символ получен из автомата, отличного от того, что был использован на предыдущем шаге. Декартово произведение состояний гарантирует, что мы рассмотрим все состояния и переходы изначальных автоматов. Для данного примера мы получаем, что &amp;lt;tex&amp;gt;\mathrm{alt(L, M)} = \{ 1010 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=58195</id>
		<title>Обсуждение участницы:Анна</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=58195"/>
				<updated>2016-12-22T21:10:33Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Примеры доказательств ==&lt;br /&gt;
=== Язык &amp;lt;tex&amp;gt;\mathrm{half(L)}&amp;lt;/tex&amp;gt; ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;\mathrm{half(L)}&amp;lt;/tex&amp;gt; как множество первых половин цепочек языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть множество &amp;lt;tex&amp;gt;\{ w \mid &amp;lt;/tex&amp;gt; существует &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, для которой &amp;lt;tex&amp;gt;wx \in L&amp;lt;/tex&amp;gt;, причем &amp;lt;tex&amp;gt;|w| = |x| \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ \varepsilon, 0010, 011, 010110 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\mathrm{half(L)} = \{ \varepsilon, 00, 010 \}&amp;lt;/tex&amp;gt;. Заметим, что цепочки нечетной длины не влияют на &amp;lt;tex&amp;gt;\mathrm{half(L)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st3&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} [[Регулярные языки: два определения и их эквивалентность|регулярный язык]]. Тогда язык &amp;lt;tex&amp;gt;\mathrm{half(L)}&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык, то существует ДКА &amp;lt;tex&amp;gt;M = \langle \Sigma , Q , q_0 , F , \delta \rangle &amp;lt;/tex&amp;gt;, допускающий его. Рассмотрим строку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Для того, чтобы проверить, что &amp;lt;tex&amp;gt;x \in \mathrm{half(L)}&amp;lt;/tex&amp;gt;, нам надо убедиться, что существует строка &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; такой же длины, что и &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, которая, будучи сконкатенированной с &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, даст строку из &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть если на вход автомату подать &amp;lt;tex&amp;gt;xy&amp;lt;/tex&amp;gt;, то в конце обработки мы окажемся в терминальном состоянии. Предположим, что автомат, закончив обработку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, находится в состоянии &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_0, x) = q_i&amp;lt;/tex&amp;gt;. Мы должны проверить, что существует строка &amp;lt;tex&amp;gt;y, |y| = |x|,&amp;lt;/tex&amp;gt; которая ведет из состояния &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt; до какого-нибудь терминального состояния &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_i, y) \in F&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Предположим, что мы прошли &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин автомата, то есть &amp;lt;tex&amp;gt;|x| = n&amp;lt;/tex&amp;gt;. Обозначим за &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; множество всех состояний, с которых можно попасть в терминальные за &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; шагов. Тогда &amp;lt;tex&amp;gt;q_i \in S_n \Leftrightarrow x \in \mathrm{half(L)}&amp;lt;/tex&amp;gt;. Если мы сможем отслеживать &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то сможем определять, верно ли, что &amp;lt;tex&amp;gt;x \in \mathrm{half(L)}&amp;lt;/tex&amp;gt;. Заметим, что &amp;lt;tex&amp;gt;S_0 \equiv F&amp;lt;/tex&amp;gt;. Очевидно мы можем построить &amp;lt;tex&amp;gt;S_{n+1}&amp;lt;/tex&amp;gt; зная &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S_{n+1} = prev(S_n) = \{ q \in Q \mid \exists a \in \Sigma, q' \in S_n, \delta(q, a) = q' \}&amp;lt;/tex&amp;gt; {{---}} множество состояний, из которых есть переход в какое-либо состояние из &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; (по единственному символу). Теперь надо найти способ отслеживать и обновлять &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Построим ДКА &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt;, который будет хранить эту информацию в своих состояниях. Определим &amp;lt;tex&amp;gt;Q' = Q \times 2^Q&amp;lt;/tex&amp;gt;, то есть каждое состояние &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; {{---}} это пара из одиночного состояния из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; и множества состояний из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;. Функцию перехода &amp;lt;tex&amp;gt;\delta'&amp;lt;/tex&amp;gt; автомата &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; определим так, чтобы если по какой-то строке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; длины &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; в автомате &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; мы перешли в состояние &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то по этой же строке в автомате &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; мы перейдем в состояние &amp;lt;tex&amp;gt;(q_i, S_n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; {{---}} множество состояний из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, определенное выше. Вспомним приведенную выше функцию &amp;lt;tex&amp;gt;prev(S_n) = S_{n+1}&amp;lt;/tex&amp;gt;. С ее помощью мы можем определить функцию перехода следующим образом: &amp;lt;tex&amp;gt;\delta'((q, S), a) = (\delta(q, a), prev(S))&amp;lt;/tex&amp;gt;. Начальное состояние &amp;lt;tex&amp;gt;q_0' = (q_0, S_0) = (q_0, F)&amp;lt;/tex&amp;gt;. Множество терминальных состояний {{---}} &amp;lt;tex&amp;gt;F' = \{ (q, S) \mid q \in S, S \in 2^Q \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Теперь по индукции не сложно доказать, что &amp;lt;tex&amp;gt;\delta'(q_0', x) = (\delta(q_0, x), S_n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;|x| = n&amp;lt;/tex&amp;gt;. По определению множества терминальных вершин, автомат &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; допускает строку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; тогда и только тогда, когда &amp;lt;tex&amp;gt;\delta(q_0, x) \in S_n&amp;lt;/tex&amp;gt;. Следовательно, автомат &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; допускает язык &amp;lt;tex&amp;gt;\mathrm{half(L)}&amp;lt;/tex&amp;gt;.Таким образом, мы построили ДКА, который допускает язык &amp;lt;tex&amp;gt;\mathrm{half(L)}&amp;lt;/tex&amp;gt;. Следовательно, данный язык является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
=== Язык &amp;lt;tex&amp;gt;\mathrm{cycle(L)}&amp;lt;/tex&amp;gt; ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;\mathrm{cycle(L)}&amp;lt;/tex&amp;gt; как множество &amp;lt;tex&amp;gt;\{ w \mid &amp;lt;/tex&amp;gt; цепочку &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; можно представить в виде &amp;lt;tex&amp;gt;w = xy&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;yx \in L \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ 01, 011 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\mathrm{cycle(L)} = \{ 01, 10, 011, 110, 101 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st5&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} [[Регулярные языки: два определения и их эквивалентность|регулярный язык]]. Тогда язык &amp;lt;tex&amp;gt;\mathrm{cycle(L)}&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
[[Файл:Enfa_before.jpg|right|thumb|380px|Рис. 1. Разбиение автомата.]]&lt;br /&gt;
[[Файл:Enfa-after.jpg|right|thumb|380px|Рис. 2. Перестроение.]]&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык, то существует допускающий его ДКА &amp;lt;tex&amp;gt;M = \langle \Sigma , Q , q_0 , F , \delta \rangle &amp;lt;/tex&amp;gt;. Построим из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; [[Автоматы_с_eps-переходами._Eps-замыкание|недетерминированный автомат с &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходами]] следующим образом: рассмотрим состояние &amp;lt;tex&amp;gt;q \in Q&amp;lt;/tex&amp;gt;, из которого есть переходы в другие состояния (то есть начиная с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; можно построить непустое слово, заканчивающееся в терминальной вершине). Тогда если какое-то слово проходит через это состояние, оно может быть зациклено таким образом, что его суффикс, начинающийся с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, станет префиксом нового слова, а префикс, заканчивающийся в &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; {{---}} суффиксом. Разделим автомат на две части &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt; будет содержать все вершины, из которых достижима &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; {{---}} все вершины, которые достижимы из &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; (см. рис. 1). Заметим, что каждая вершина может содержаться в обеих частях одновременно, такое может случиться, если автомат &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; содержит циклы. Теперь перестроим автомат так, что он будет принимать слова &amp;quot;зацикленные&amp;quot; вокруг &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, то есть начинающиеся с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; и после достижения терминальной вершины продолжающиеся с &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; (см. рис. 2). Для этого стартовой вершиной сделаем &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; и построим от нее часть &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt;. Теперь добавим состояние &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; и соединим с ним все терминальные состояния из &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; с помощью &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходов. Далее построим от &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; часть &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt;. Добавим вершину &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt;, эквивалентную &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, и сделаем ее терминальной. Данный автомат принимает слова, зацикленные вокруг выбранной вершины &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. Мы хотим, чтобы автомат принимал слова, зацикленные вокруг любой такой &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. Для этого создадим новую стартовую вершину &amp;lt;tex&amp;gt;q_0'&amp;lt;/tex&amp;gt; и свяжем ее &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходами со всеми перестроенными автоматами (зацикленными вокруг всех подходящих &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;), в том числе и с изначальным автоматом. Построенный автомат допускает язык &amp;lt;tex&amp;gt;\mathrm{cycle(L)}&amp;lt;/tex&amp;gt;, следовательно, данный язык является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Ex_1_before.jpg|left|thumb|260px|Рис. 3. Автомат, принимающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
[[Файл:Ex_1_after.jpg|right|thumb|380px|Рис. 4. Автомат, принимающий язык &amp;lt;tex&amp;gt;\mathrm{cycle(L)}&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
Для лучшего понимания алгоритма перестроения автомата рассмотрим пример.&lt;br /&gt;
&lt;br /&gt;
На рис. 3 представлен автомат, допускающий язык &amp;lt;tex&amp;gt;L = \{ ab, abb, ac \}&amp;lt;/tex&amp;gt;. На рис. 4 показано, как этот автомат был перестроен. Были добавлены части, зацикленные  относительно вершин &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;. Появилась новая стартовая вершина &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, которая связана &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходами с изначальным автоматом и его измененными версиями. Данный автомат распознает язык &amp;lt;tex&amp;gt;\mathrm{cycle(L)} = \{ ab, abb, ac, ba, bba, ca, bab \}&amp;lt;/tex&amp;gt;: первые три слова распознает первая часть, которая совпадает с изначальным автоматом; следующие три {{---}} вторая, перестроенная относительно вершины &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;; последнее слово распознает третья часть, зацикленная относительно вершины &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Язык &amp;lt;tex&amp;gt;\mathrm{alt(L, M)}&amp;lt;/tex&amp;gt; ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Пусть &amp;lt;tex&amp;gt;w = w_1 w_2 \dots w_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;x = x_1 x_2 \dots x_n&amp;lt;/tex&amp;gt;. Определим &amp;lt;tex&amp;gt;alt(w, x) = w_1 x_1 w_2 x_2 \dots w_n x_n&amp;lt;/tex&amp;gt;. Распространим это определение на языки следующим образом: пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; {{---}} два языка над одним алфавитом &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;\mathrm{alt(L, M)} = \{ alt(w, x) \mid |w| = |x|, w \in L, x \in M \}&amp;lt;/tex&amp;gt;.}}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ 10, 00, 111, 1001 \}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M = \{ 11, 0101 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\mathrm{alt(L, M)} = \{ 1101, 0101, 10010011 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st4&lt;br /&gt;
|statement = Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; {{---}} [[Регулярные языки: два определения и их эквивалентность|регулярные языки]]. Тогда &amp;lt;tex&amp;gt;\mathrm{alt(L, M)}&amp;lt;/tex&amp;gt; также является регулярным.&lt;br /&gt;
|proof = Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; {{---}} регулярные языки, то существуют ДКА &amp;lt;tex&amp;gt;D_L = \langle \Sigma , Q_L , q_{0L} , F_L, \delta_L \rangle&amp;lt;/tex&amp;gt;, распознающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;D_M = \langle \Sigma , Q_M , q_{0M} , F_M, \delta_M \rangle&amp;lt;/tex&amp;gt;, распознающий язык &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;. Построим автомат &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt;, который будет распознавать язык &amp;lt;tex&amp;gt;\mathrm{alt(L, M)}&amp;lt;/tex&amp;gt;. Идея следующая: каждое состояние этого автомата будем описывать тремя значениями &amp;lt;tex&amp;gt;(p, q, b)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;p \in Q_L&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;q \in Q_M&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;b \in \{ 1, 0 \}&amp;lt;/tex&amp;gt;. Нам нужно организовать чередование переходов по состояниям автоматов, то есть если мы на определенном шаге перешли от одного состояния автомата &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt; до другого, то на следующем мы обязаны совершить переход по состояниям автомата &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt;. Для этого нам нужно обновлять состояние одного автомата и при этом сохранять состояние другого для следующего перехода. Тут мы будем использовать третье значение: если &amp;lt;tex&amp;gt;b = 0&amp;lt;/tex&amp;gt;, то будет двигаться по состояниям первого автомата, то есть значение &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; при переходе в новое состояние автомата &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt; поменяется, &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; останется неизменной, &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; станет &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;b = 1&amp;lt;/tex&amp;gt;, то, соответственно, все наоборот. То есть у нас будут две функции перехода, выбирать нужную будем в зависимости от четности третьего параметра. Важно, что на каждом шаге мы инвертируем значение &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt;, что гарантирует чередование. Определим автомат &amp;lt;tex&amp;gt;D_{alt} = \langle \Sigma, Q', q_0', F', \delta' \rangle&amp;lt;/tex&amp;gt; следующим образом:&lt;br /&gt;
# &amp;lt;tex&amp;gt;Q' = Q_L \times Q_M \times \{ 0, 1 \}&amp;lt;/tex&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt;q_0' = (q_{0L}, q_{0M}, 0)&amp;lt;/tex&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt;F' = F_L \times F_M \times \{ 0 \}&amp;lt;/tex&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt;\delta'((p, q, 0), a) = (\delta_L(p, a), q, 1)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta'((p, q, 1), a) = (p, \delta_M(q, a), 0)&amp;lt;/tex&amp;gt;&lt;br /&gt;
Стартовая вершина имеет третий параметр &amp;lt;tex&amp;gt;b = 0&amp;lt;/tex&amp;gt;, так как первое значение должно быть получено из автомата &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt;. Аналогично все терминальные вершины должны иметь то же значение последнего параметра, так как количество переходов должно быть четным и последний переход должен был быть осуществлен по автомату &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt;. Функция перехода &amp;lt;tex&amp;gt;\delta'&amp;lt;/tex&amp;gt; использует &amp;lt;tex&amp;gt;\delta_L&amp;lt;/tex&amp;gt; для получения нечетных символов и &amp;lt;tex&amp;gt;\delta_M&amp;lt;/tex&amp;gt; для четных. Таким образом, &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt; состоит из чередующихся символов &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt; принимает &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; тогда и только тогда, когда &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt; последовательно принимает все нечетные символы &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt; {{---}} все четные, а так же &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; имеет четную длину. Следовательно, &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt; распознает язык &amp;lt;tex&amp;gt;\mathrm{alt(L, M)}&amp;lt;/tex&amp;gt;, что доказывает, что &amp;lt;tex&amp;gt;\mathrm{alt(L, M)}&amp;lt;/tex&amp;gt; является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Alt ex 1.jpg|left|thumb|265px|Рис. 5. Автоматы для языков &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
[[Файл:Alt ex 2.jpg|right|thumb|390px|Рис. 6. Автомат, принимающий язык &amp;lt;tex&amp;gt;\mathrm{alt(L, M)}&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
Чтобы более наглядно показать, как строится автомат &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt;, разберем пример. Пусть &amp;lt;tex&amp;gt;L = \{ 1, 11 \}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M = \{ 00 \}&amp;lt;/tex&amp;gt; (см. рис. 5). Все состояния нового автомата представлены на рис. 6. Стартовая вершина &amp;lt;tex&amp;gt;q_0' = (1, 1, 0)&amp;lt;/tex&amp;gt;, множество терминальных вершин {{---}} &amp;lt;tex&amp;gt;F' = \{ (2, 3, 0), (3, 3, 0) \}&amp;lt;/tex&amp;gt;. Мы видим, что построенные по функции &amp;lt;tex&amp;gt;\delta'&amp;lt;/tex&amp;gt; переходы на каждом шаге меняют состояние одного из автоматов, а именно того, по которому происходит переход, сохраняя состояние другого для следующего шага. Таким образом, каждый следующий символ получен из автомата, отличного от того, что был использован на предыдущем шаге. Декартово произведение состояний гарантирует, что мы рассмотрим все состояния и переходы изначальных автоматов. Для данного примера мы получаем, что &amp;lt;tex&amp;gt;\mathrm{alt(L, M)} = \{ 1010 \}&amp;lt;/tex&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=58192</id>
		<title>Обсуждение участницы:Анна</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=58192"/>
				<updated>2016-12-22T20:51:09Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: /* Язык alt(L, M) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Примеры доказательств ==&lt;br /&gt;
=== Язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt; ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt; как множество первых половин цепочек языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть множество &amp;lt;tex&amp;gt;\{ w \mid &amp;lt;/tex&amp;gt; существует &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, для которой &amp;lt;tex&amp;gt;wx \in L&amp;lt;/tex&amp;gt;, причем &amp;lt;tex&amp;gt;|w| = |x| \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ \varepsilon, 0010, 011, 010110 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;half(L) = \{ \varepsilon, 00, 010 \}&amp;lt;/tex&amp;gt;. Заметим, что цепочки нечетной длины не влияют на &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st3&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык. Тогда язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык, то существует ДКА &amp;lt;tex&amp;gt;M = \langle \Sigma , Q , q_0 , F , \delta \rangle &amp;lt;/tex&amp;gt;, допускающий его. Рассмотрим строку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Для того, чтобы проверить, что &amp;lt;tex&amp;gt;x \in half(L)&amp;lt;/tex&amp;gt;, нам надо убедиться, что существует строка &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; такой же длины, что и &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, которая, будучи сконкатенированной с &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, даст строку из &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть если на вход автомату подать &amp;lt;tex&amp;gt;xy&amp;lt;/tex&amp;gt;, то в конце обработки мы окажемся в терминальном состоянии. Предположим, что автомат, закончив обработку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, находится в состоянии &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_0, x) = q_i&amp;lt;/tex&amp;gt;. Мы должны проверить, что существует строка &amp;lt;tex&amp;gt;y, |y| = |x|,&amp;lt;/tex&amp;gt; которая ведет из состояния &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt; до какого-нибудь терминального состояния &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_i, y) \in F&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Предположим, что мы прошли &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин автомата, то есть &amp;lt;tex&amp;gt;|x| = n&amp;lt;/tex&amp;gt;. Обозначим за &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; множество всех состояний, с которых можно попасть в терминальные за &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; шагов. Тогда &amp;lt;tex&amp;gt;q_i \in S_n \Leftrightarrow x \in half(L)&amp;lt;/tex&amp;gt;. Если мы сможем отслеживать &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то сможем определять, верно ли, что &amp;lt;tex&amp;gt;x \in half(L)&amp;lt;/tex&amp;gt;. Заметим, что &amp;lt;tex&amp;gt;S_0 \equiv F&amp;lt;/tex&amp;gt;. Очевидно мы можем построить &amp;lt;tex&amp;gt;S_{n+1}&amp;lt;/tex&amp;gt; зная &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S_{n+1} = prev(S_n) = \{ q \in Q \mid \exists a \in \Sigma, q' \in S_n, \delta(q, a) = q' \}&amp;lt;/tex&amp;gt; {{---}} множество состояний, из которых есть переход в какое-либо состояние из &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; (по единственному символу). Теперь надо найти способ отслеживать и обновлять &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Построим ДКА &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt;, который будет хранить эту информацию в своих состояниях. Определим &amp;lt;tex&amp;gt;Q' = Q \times 2^Q&amp;lt;/tex&amp;gt;, то есть каждое состояние &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; {{---}} это пара из одиночного состояния из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; и множества состояний из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;. Функцию перехода &amp;lt;tex&amp;gt;\delta'&amp;lt;/tex&amp;gt; автомата &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; определим так, чтобы если по какой-то строке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; длины &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; в автомате &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; мы перешли в состояние &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то по этой же строке в автомате &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; мы перейдем в состояние &amp;lt;tex&amp;gt;(q_i, S_n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; {{---}} множество состояний из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, определенное выше. Вспомним приведенную выше функцию &amp;lt;tex&amp;gt;prev(S_n) = S_{n+1}&amp;lt;/tex&amp;gt;. С ее помощью мы можем определить функцию перехода следующим образом: &amp;lt;tex&amp;gt;\delta'((q, S), a) = (\delta(q, a), prev(S))&amp;lt;/tex&amp;gt;. Начальное состояние &amp;lt;tex&amp;gt;q_0' = (q_0, S_0) = (q_0, F)&amp;lt;/tex&amp;gt;. Множество терминальных состояний {{---}} &amp;lt;tex&amp;gt;F' = \{ (q, S) \mid q \in S, S \in 2^Q \}&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь по индукции не сложно доказать, что &amp;lt;tex&amp;gt;\delta'(q_0', x) = (\delta(q_0, x), S_n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;|x| = n&amp;lt;/tex&amp;gt;. По определению множества терминальных вершин, автомат &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; допускает строку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; тогда и только тогда, когда &amp;lt;tex&amp;gt;\delta(q_0, x) \in S_n&amp;lt;/tex&amp;gt;. Следовательно, автомат &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; допускает язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;.Таким образом, мы построили ДКА, который допускает язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;. Следовательно, данный язык является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
=== Язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt; ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt; как множество &amp;lt;tex&amp;gt;\{ w \mid &amp;lt;/tex&amp;gt; цепочку &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; можно представить в виде &amp;lt;tex&amp;gt;w = xy&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;yx \in L \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ 01, 011 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;cycle(L) = \{ 01, 10, 011, 110, 101 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st5&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык. Тогда язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
[[Файл:Enfa_before.jpg|right|thumb|380px|Рис. 1. Разбиение автомата.]]&lt;br /&gt;
[[Файл:Enfa-after.jpg|right|thumb|380px|Рис. 2. Перестроение.]]&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык, то существует допускающий его ДКА &amp;lt;tex&amp;gt;M = \langle \Sigma , Q , q_0 , F , \delta \rangle &amp;lt;/tex&amp;gt;. Построим из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; недетерминированный автомат с &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходами следующим образом: рассмотрим состояние &amp;lt;tex&amp;gt;q \in Q&amp;lt;/tex&amp;gt;, из которого есть переходы в другие состояния (то есть начиная с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; можно построить непустое слово, заканчивающееся в терминальной вершине). Тогда если какое-то слово проходит через это состояние, оно может быть зациклено таким образом, что его суффикс, начинающийся с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, станет префиксом нового слова, а префикс, заканчивающийся в &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; {{---}} суффиксом. Разделим автомат на две части &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt; будет содержать все вершины, из которых достижима &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; {{---}} все вершины, которые достижимы из &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; (см. рис. 1). Заметим, что каждая вершина может содержаться в обеих частях одновременно, такое может случиться, если автомат &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; содержит циклы. Теперь перестроим автомат так, что он будет принимать слова &amp;quot;зацикленные&amp;quot; вокруг &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, то есть начинающиеся с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; и после достижения терминальной вершины продолжающиеся с &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; (см. рис. 2). Для этого стартовой вершиной сделаем &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; и построим от нее часть &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt;. Теперь добавим состояние &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; и соединим с ним все терминальные состояния из &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; с помощью &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходов. Далее построим от &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; часть &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt;. Добавим вершину &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt;, эквивалентную &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, и сделаем ее терминальной. Данный автомат принимает слова, зацикленные вокруг выбранной вершины &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. Мы хотим, чтобы автомат принимал слова, зацикленные вокруг любой такой &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. Для этого создадим новую стартовую вершину &amp;lt;tex&amp;gt;q_0'&amp;lt;/tex&amp;gt; и свяжем ее &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходами со всеми перестроенными автоматами (зацикленными вокруг всех подходящих &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;), в том числе и с изначальным автоматом. Построенный автомат допускает язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt;, следовательно, данный язык является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Ex_1_before.jpg|left|thumb|260px|Рис. 3. Автомат, принимающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
[[Файл:Ex_1_after.jpg|right|thumb|380px|Рис. 4. Автомат, принимающий язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
Для лучшего понимания алгоритма перестроения автомата рассмотрим пример.&amp;lt;br&amp;gt;&lt;br /&gt;
На рис. 3 представлен автомат, допускающий язык &amp;lt;tex&amp;gt;L = \{ ab, abb, ac \}&amp;lt;/tex&amp;gt;. На рис. 4 показано, как этот автомат был перестроен. Были добавлены части, зацикленные  относительно вершин &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;. Появилась новая стартовая вершина &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, которая связана &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходами с изначальным автоматом и его измененными версиями. Данный автомат распознает язык &amp;lt;tex&amp;gt;cycle(L) = \{ ab, abb, ac, ba, bba, ca, bab \}&amp;lt;/tex&amp;gt;: первые три слова распознает первая часть, которая совпадает с изначальным автоматом; следующие три {{---}} вторая, перестроенная относительно вершины &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;; последнее слово распознает третья часть, зацикленная относительно вершины &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Язык &amp;lt;tex&amp;gt;alt(L, M)&amp;lt;/tex&amp;gt; ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Пусть &amp;lt;tex&amp;gt;w = w_1 w_2 \dots w_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;x = x_1 x_2 \dots x_n&amp;lt;/tex&amp;gt;. Определим &amp;lt;tex&amp;gt;alt(w, x) = w_1 x_1 w_2 x_2 \dots w_n x_n&amp;lt;/tex&amp;gt;. Распространим это определение на языки следующим образом: пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; {{---}} два языка над одним алфавитом &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;alt(L, M) = \{ alt(w, x) \mid |w| = |x|, w \in L, x \in M \}&amp;lt;/tex&amp;gt;.}}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ 10, 00, 111, 1001 \}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M = \{ 11, 0101 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;alt(L, M) = \{ 1101, 0101, 10010011 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st4&lt;br /&gt;
|statement = Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; {{---}} регулярные языки. Тогда &amp;lt;tex&amp;gt;alt(L, M)&amp;lt;/tex&amp;gt; также является регулярным.&lt;br /&gt;
|proof = Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; {{---}} регулярные языки, то существуют ДКА &amp;lt;tex&amp;gt;D_L = \langle \Sigma , Q_L , q_{0L} , F_L, \delta_L \rangle&amp;lt;/tex&amp;gt;, распознающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;D_M = \langle \Sigma , Q_M , q_{0M} , F_M, \delta_M \rangle&amp;lt;/tex&amp;gt;, распознающий язык &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;. Построим автомат &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt;, который будет распознавать язык &amp;lt;tex&amp;gt;alt(L, M)&amp;lt;/tex&amp;gt;. Идея следующая: каждое состояние этого автомата будем описывать тремя значениями &amp;lt;tex&amp;gt;(p, q, b)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;p \in Q_L&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;q \in Q_M&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;b \in \{ 1, 0 \}&amp;lt;/tex&amp;gt;. Нам нужно организовать чередование переходов по состояниям автоматов, то есть если мы на определенном шаге перешли от одного состояния автомата &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt; до другого, то на следующем мы обязаны совершить переход по состояниям автомата &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt;. Для этого нам нужно обновлять состояние одного автомата и при этом сохранять состояние другого для следующего перехода. Тут мы будем использовать третье значение: если &amp;lt;tex&amp;gt;b = 0&amp;lt;/tex&amp;gt;, то будет двигаться по состояниям первого автомата, то есть значение &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; при переходе в новое состояние автомата &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt; поменяется, &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; останется неизменной, &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; станет &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;b = 1&amp;lt;/tex&amp;gt;, то, соответственно, все наоборот. То есть у нас будут две функции перехода, выбирать нужную будем в зависимости от четности третьего параметра. Важно, что на каждом шаге мы инвертируем значение &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt;, что гарантирует чередование. Определим автомат &amp;lt;tex&amp;gt;D_{alt} = \langle \Sigma, Q', q_0', F', \delta' \rangle&amp;lt;/tex&amp;gt; следующим образом:&lt;br /&gt;
# &amp;lt;tex&amp;gt;Q' = Q_L \times Q_M \times \{ 0, 1 \}&amp;lt;/tex&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt;q_0' = (q_{0L}, q_{0M}, 0)&amp;lt;/tex&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt;F' = F_L \times F_M \times \{ 0 \}&amp;lt;/tex&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt;\delta'((p, q, 0), a) = (\delta_L(p, a), q, 1)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta'((p, q, 1), a) = (p, \delta_M(q, a), 0)&amp;lt;/tex&amp;gt;&lt;br /&gt;
Стартовая вершина имеет третий параметр &amp;lt;tex&amp;gt;b = 0&amp;lt;/tex&amp;gt;, так как первое значение должно быть получено из автомата &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt;. Аналогично все терминальные вершины должны иметь то же значение последнего параметра, так как количество переходов должно быть четным и последний переход должен был быть осуществлен по автомату &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt;. Функция перехода &amp;lt;tex&amp;gt;\delta'&amp;lt;/tex&amp;gt; использует &amp;lt;tex&amp;gt;\delta_L&amp;lt;/tex&amp;gt; для получения нечетных символов и &amp;lt;tex&amp;gt;\delta_M&amp;lt;/tex&amp;gt; для четных. Таким образом, &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt; состоит из чередующихся символов &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt; принимает &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; тогда и только тогда, когда &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt; последовательно принимает все нечетные символы &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt; {{---}} все четные, а так же &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; имеет четную длину. Следовательно, &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt; распознает язык &amp;lt;tex&amp;gt;alt(L, M)&amp;lt;/tex&amp;gt;, что доказывает, что &amp;lt;tex&amp;gt;alt(L, M)&amp;lt;/tex&amp;gt; является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Alt ex 1.jpg|left|thumb|265px|Рис. 5. Автоматы для языков &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
[[Файл:Alt ex 2.jpg|right|thumb|390px|Рис. 6. Автомат, принимающий язык &amp;lt;tex&amp;gt;alt(L, M)&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
Чтобы более наглядно показать, как строится автомат &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt;, разберем пример. Пусть &amp;lt;tex&amp;gt;L = \{ 1, 11 \}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M = \{ 00 \}&amp;lt;/tex&amp;gt; (см. рис. 5). Все состояния нового автомата представлены на рис. 6. Стартовая вершина &amp;lt;tex&amp;gt;q_0' = (1, 1, 0)&amp;lt;/tex&amp;gt;, множество терминальных вершин {{---}} &amp;lt;tex&amp;gt;F' = \{ (2, 3, 0), (3, 3, 0) \}&amp;lt;/tex&amp;gt;. Мы видим, что построенные по функции &amp;lt;tex&amp;gt;\delta'&amp;lt;/tex&amp;gt; переходы на каждом шаге меняют состояние одного из автоматов, а именно того, по которому происходит переход, сохраняя состояние другого для следующего шага. Таким образом, каждый следующий символ получен из автомата, отличного от того, что был использован на предыдущем шаге. Декартово произведение состояний гарантирует, что мы рассмотрим все состояния и переходы изначальных автоматов.&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=58191</id>
		<title>Обсуждение участницы:Анна</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=58191"/>
				<updated>2016-12-22T20:34:45Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Примеры доказательств ==&lt;br /&gt;
=== Язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt; ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt; как множество первых половин цепочек языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть множество &amp;lt;tex&amp;gt;\{ w \mid &amp;lt;/tex&amp;gt; существует &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, для которой &amp;lt;tex&amp;gt;wx \in L&amp;lt;/tex&amp;gt;, причем &amp;lt;tex&amp;gt;|w| = |x| \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ \varepsilon, 0010, 011, 010110 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;half(L) = \{ \varepsilon, 00, 010 \}&amp;lt;/tex&amp;gt;. Заметим, что цепочки нечетной длины не влияют на &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st3&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык. Тогда язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык, то существует ДКА &amp;lt;tex&amp;gt;M = \langle \Sigma , Q , q_0 , F , \delta \rangle &amp;lt;/tex&amp;gt;, допускающий его. Рассмотрим строку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Для того, чтобы проверить, что &amp;lt;tex&amp;gt;x \in half(L)&amp;lt;/tex&amp;gt;, нам надо убедиться, что существует строка &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; такой же длины, что и &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, которая, будучи сконкатенированной с &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, даст строку из &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть если на вход автомату подать &amp;lt;tex&amp;gt;xy&amp;lt;/tex&amp;gt;, то в конце обработки мы окажемся в терминальном состоянии. Предположим, что автомат, закончив обработку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, находится в состоянии &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_0, x) = q_i&amp;lt;/tex&amp;gt;. Мы должны проверить, что существует строка &amp;lt;tex&amp;gt;y, |y| = |x|,&amp;lt;/tex&amp;gt; которая ведет из состояния &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt; до какого-нибудь терминального состояния &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_i, y) \in F&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Предположим, что мы прошли &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин автомата, то есть &amp;lt;tex&amp;gt;|x| = n&amp;lt;/tex&amp;gt;. Обозначим за &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; множество всех состояний, с которых можно попасть в терминальные за &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; шагов. Тогда &amp;lt;tex&amp;gt;q_i \in S_n \Leftrightarrow x \in half(L)&amp;lt;/tex&amp;gt;. Если мы сможем отслеживать &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то сможем определять, верно ли, что &amp;lt;tex&amp;gt;x \in half(L)&amp;lt;/tex&amp;gt;. Заметим, что &amp;lt;tex&amp;gt;S_0 \equiv F&amp;lt;/tex&amp;gt;. Очевидно мы можем построить &amp;lt;tex&amp;gt;S_{n+1}&amp;lt;/tex&amp;gt; зная &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S_{n+1} = prev(S_n) = \{ q \in Q \mid \exists a \in \Sigma, q' \in S_n, \delta(q, a) = q' \}&amp;lt;/tex&amp;gt; {{---}} множество состояний, из которых есть переход в какое-либо состояние из &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; (по единственному символу). Теперь надо найти способ отслеживать и обновлять &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Построим ДКА &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt;, который будет хранить эту информацию в своих состояниях. Определим &amp;lt;tex&amp;gt;Q' = Q \times 2^Q&amp;lt;/tex&amp;gt;, то есть каждое состояние &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; {{---}} это пара из одиночного состояния из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; и множества состояний из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;. Функцию перехода &amp;lt;tex&amp;gt;\delta'&amp;lt;/tex&amp;gt; автомата &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; определим так, чтобы если по какой-то строке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; длины &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; в автомате &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; мы перешли в состояние &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то по этой же строке в автомате &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; мы перейдем в состояние &amp;lt;tex&amp;gt;(q_i, S_n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; {{---}} множество состояний из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, определенное выше. Вспомним приведенную выше функцию &amp;lt;tex&amp;gt;prev(S_n) = S_{n+1}&amp;lt;/tex&amp;gt;. С ее помощью мы можем определить функцию перехода следующим образом: &amp;lt;tex&amp;gt;\delta'((q, S), a) = (\delta(q, a), prev(S))&amp;lt;/tex&amp;gt;. Начальное состояние &amp;lt;tex&amp;gt;q_0' = (q_0, S_0) = (q_0, F)&amp;lt;/tex&amp;gt;. Множество терминальных состояний {{---}} &amp;lt;tex&amp;gt;F' = \{ (q, S) \mid q \in S, S \in 2^Q \}&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь по индукции не сложно доказать, что &amp;lt;tex&amp;gt;\delta'(q_0', x) = (\delta(q_0, x), S_n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;|x| = n&amp;lt;/tex&amp;gt;. По определению множества терминальных вершин, автомат &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; допускает строку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; тогда и только тогда, когда &amp;lt;tex&amp;gt;\delta(q_0, x) \in S_n&amp;lt;/tex&amp;gt;. Следовательно, автомат &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; допускает язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;.Таким образом, мы построили ДКА, который допускает язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;. Следовательно, данный язык является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
=== Язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt; ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt; как множество &amp;lt;tex&amp;gt;\{ w \mid &amp;lt;/tex&amp;gt; цепочку &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; можно представить в виде &amp;lt;tex&amp;gt;w = xy&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;yx \in L \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ 01, 011 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;cycle(L) = \{ 01, 10, 011, 110, 101 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st5&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык. Тогда язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
[[Файл:Enfa_before.jpg|right|thumb|380px|Рис. 1. Разбиение автомата.]]&lt;br /&gt;
[[Файл:Enfa-after.jpg|right|thumb|380px|Рис. 2. Перестроение.]]&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык, то существует допускающий его ДКА &amp;lt;tex&amp;gt;M = \langle \Sigma , Q , q_0 , F , \delta \rangle &amp;lt;/tex&amp;gt;. Построим из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; недетерминированный автомат с &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходами следующим образом: рассмотрим состояние &amp;lt;tex&amp;gt;q \in Q&amp;lt;/tex&amp;gt;, из которого есть переходы в другие состояния (то есть начиная с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; можно построить непустое слово, заканчивающееся в терминальной вершине). Тогда если какое-то слово проходит через это состояние, оно может быть зациклено таким образом, что его суффикс, начинающийся с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, станет префиксом нового слова, а префикс, заканчивающийся в &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; {{---}} суффиксом. Разделим автомат на две части &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt; будет содержать все вершины, из которых достижима &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; {{---}} все вершины, которые достижимы из &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; (см. рис. 1). Заметим, что каждая вершина может содержаться в обеих частях одновременно, такое может случиться, если автомат &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; содержит циклы. Теперь перестроим автомат так, что он будет принимать слова &amp;quot;зацикленные&amp;quot; вокруг &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, то есть начинающиеся с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; и после достижения терминальной вершины продолжающиеся с &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; (см. рис. 2). Для этого стартовой вершиной сделаем &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; и построим от нее часть &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt;. Теперь добавим состояние &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; и соединим с ним все терминальные состояния из &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; с помощью &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходов. Далее построим от &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; часть &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt;. Добавим вершину &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt;, эквивалентную &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, и сделаем ее терминальной. Данный автомат принимает слова, зацикленные вокруг выбранной вершины &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. Мы хотим, чтобы автомат принимал слова, зацикленные вокруг любой такой &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. Для этого создадим новую стартовую вершину &amp;lt;tex&amp;gt;q_0'&amp;lt;/tex&amp;gt; и свяжем ее &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходами со всеми перестроенными автоматами (зацикленными вокруг всех подходящих &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;), в том числе и с изначальным автоматом. Построенный автомат допускает язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt;, следовательно, данный язык является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Ex_1_before.jpg|left|thumb|260px|Рис. 3. Автомат, принимающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
[[Файл:Ex_1_after.jpg|right|thumb|380px|Рис. 4. Автомат, принимающий язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
Для лучшего понимания алгоритма перестроения автомата рассмотрим пример.&amp;lt;br&amp;gt;&lt;br /&gt;
На рис. 3 представлен автомат, допускающий язык &amp;lt;tex&amp;gt;L = \{ ab, abb, ac \}&amp;lt;/tex&amp;gt;. На рис. 4 показано, как этот автомат был перестроен. Были добавлены части, зацикленные  относительно вершин &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;. Появилась новая стартовая вершина &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, которая связана &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходами с изначальным автоматом и его измененными версиями. Данный автомат распознает язык &amp;lt;tex&amp;gt;cycle(L) = \{ ab, abb, ac, ba, bba, ca, bab \}&amp;lt;/tex&amp;gt;: первые три слова распознает первая часть, которая совпадает с изначальным автоматом; следующие три {{---}} вторая, перестроенная относительно вершины &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;; последнее слово распознает третья часть, зацикленная относительно вершины &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Язык &amp;lt;tex&amp;gt;alt(L, M)&amp;lt;/tex&amp;gt; ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Пусть &amp;lt;tex&amp;gt;w = w_1 w_2 \dots w_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;x = x_1 x_2 \dots x_n&amp;lt;/tex&amp;gt;. Определим &amp;lt;tex&amp;gt;alt(w, x) = w_1 x_1 w_2 x_2 \dots w_n x_n&amp;lt;/tex&amp;gt;. Распространим это определение на языки следующим образом: пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; {{---}} два языка над одним алфавитом &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;alt(L, M) = \{ alt(w, x) \mid |w| = |x|, w \in L, x \in M \}&amp;lt;/tex&amp;gt;.}}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ 10, 00, 111, 1001 \}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M = \{ 11, 0101 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;alt(L, M) = \{ 1101, 0101, 10010011 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st4&lt;br /&gt;
|statement = Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; {{---}} регулярные языки. Тогда &amp;lt;tex&amp;gt;alt(L, M)&amp;lt;/tex&amp;gt; также является регулярным.&lt;br /&gt;
|proof = Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; {{---}} регулярные языки, то существуют ДКА &amp;lt;tex&amp;gt;D_L = \langle \Sigma , Q_L , q_{0L} , F_L, \delta_L \rangle&amp;lt;/tex&amp;gt;, распознающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;D_M = \langle \Sigma , Q_M , q_{0M} , F_M, \delta_M \rangle&amp;lt;/tex&amp;gt;, распознающий язык &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;. Построим автомат &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt;, который будет распознавать язык &amp;lt;tex&amp;gt;alt(L, M)&amp;lt;/tex&amp;gt;. Идея следующая: каждое состояние этого автомата будем описывать тремя значениями &amp;lt;tex&amp;gt;(p, q, b)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;p \in Q_L&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;q \in Q_M&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;b \in \{ 1, 0 \}&amp;lt;/tex&amp;gt;. Нам нужно организовать чередование переходов по состояниям автоматов, то есть если мы на определенном шаге перешли от одного состояния автомата &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt; до другого, то на следующем мы обязаны совершить переход по состояниям автомата &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt;. Для этого нам нужно обновлять состояние одного автомата и при этом сохранять состояние другого для следующего перехода. Тут мы будем использовать третье значение: если &amp;lt;tex&amp;gt;b = 0&amp;lt;/tex&amp;gt;, то будет двигаться по состояниям первого автомата, то есть значение &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; при переходе в новое состояние автомата &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt; поменяется, &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; останется неизменной, &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; станет &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;b = 1&amp;lt;/tex&amp;gt;, то, соответственно, все наоборот. То есть у нас будут две функции перехода, выбирать нужную будем в зависимости от четности третьего параметра. Важно, что на каждом шаге мы инвертируем значение &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt;, что гарантирует чередование. Определим автомат &amp;lt;tex&amp;gt;D_{alt} = \langle \Sigma, Q', q_0', F', \delta' \rangle&amp;lt;/tex&amp;gt; следующим образом:&lt;br /&gt;
# &amp;lt;tex&amp;gt;Q' = Q_L \times Q_M \times \{ 0, 1 \}&amp;lt;/tex&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt;q_0' = (q_{0L}, q_{0M}, 0)&amp;lt;/tex&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt;F' = F_L \times F_M \times \{ 0 \}&amp;lt;/tex&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt;\delta'((p, q, 0), a) = (\delta_L(p, a), q, 1)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta'((p, q, 1), a) = (p, \delta_M(q, a), 0)&amp;lt;/tex&amp;gt;&lt;br /&gt;
Стартовая вершина имеет третий параметр &amp;lt;tex&amp;gt;b = 0&amp;lt;/tex&amp;gt;, так как первое значение должно быть получено из автомата &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt;. Аналогично все терминальные вершины должны иметь то же значение последнего параметра, так как количество переходов должно быть четным и последний переход должен был быть осуществлен по автомату &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt;. Функция перехода &amp;lt;tex&amp;gt;\delta'&amp;lt;/tex&amp;gt; использует &amp;lt;tex&amp;gt;\delta_L&amp;lt;/tex&amp;gt; для получения нечетных символов и &amp;lt;tex&amp;gt;\delta_M&amp;lt;/tex&amp;gt; для четных. Таким образом, &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt; состоит из чередующихся символов &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt; принимает &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; тогда и только тогда, когда &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt; последовательно принимает все нечетные символы &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt; {{---}} все четные, а так же &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; имеет четную длину. Следовательно, &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt; распознает язык &amp;lt;tex&amp;gt;alt(L, M)&amp;lt;/tex&amp;gt;, что доказывает, что &amp;lt;tex&amp;gt;alt(L, M)&amp;lt;/tex&amp;gt; является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Alt ex 1.jpg|left|thumb|265px|Рис. 5. Автоматы для языков &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
[[Файл:Alt ex 2.jpg|right|thumb|390px|Рис. 6. Автомат, принимающий язык &amp;lt;tex&amp;gt;alt(L, M)&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
Чтобы более наглядно показать, как строится автомат &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt;, разберем пример. Пусть &amp;lt;tex&amp;gt;L = \{ 1, 11 \}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M = \{ 00 \}&amp;lt;/tex&amp;gt; (см. рис. 5). Все состояния нового автомата представлены на рис. 6. Стартовая вершина &amp;lt;tex&amp;gt;q_0' = (1, 1, 0)&amp;lt;/tex&amp;gt;, множество терминальных вершин {{---}} &amp;lt;tex&amp;gt;F' = \{ (2, 3, 0), (3, 3, 0) \}&amp;lt;/tex&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Alt_ex_2.jpg&amp;diff=58189</id>
		<title>Файл:Alt ex 2.jpg</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Alt_ex_2.jpg&amp;diff=58189"/>
				<updated>2016-12-22T20:09:10Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Alt_ex_1.jpg&amp;diff=58188</id>
		<title>Файл:Alt ex 1.jpg</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Alt_ex_1.jpg&amp;diff=58188"/>
				<updated>2016-12-22T20:03:07Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=57937</id>
		<title>Обсуждение участницы:Анна</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=57937"/>
				<updated>2016-12-17T21:26:27Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: /* Язык alt(L, M) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Примеры доказательств ==&lt;br /&gt;
=== Язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt; ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt; как множество первых половин цепочек языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть множество &amp;lt;tex&amp;gt;\{ w \mid &amp;lt;/tex&amp;gt; существует &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, для которой &amp;lt;tex&amp;gt;wx \in L&amp;lt;/tex&amp;gt;, причем &amp;lt;tex&amp;gt;|w| = |x| \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ \varepsilon, 0010, 011, 010110 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;half(L) = \{ \varepsilon, 00, 010 \}&amp;lt;/tex&amp;gt;. Заметим, что цепочки нечетной длины не влияют на &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st3&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык. Тогда язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык, то существует ДКА &amp;lt;tex&amp;gt;M = \langle \Sigma , Q , q_0 , F , \delta \rangle &amp;lt;/tex&amp;gt;, допускающий его. Рассмотрим строку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Для того, чтобы проверить, что &amp;lt;tex&amp;gt;x \in half(L)&amp;lt;/tex&amp;gt;, нам надо убедиться, что существует строка &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; такой же длины, что и &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, которая, будучи сконкатенированной с &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, даст строку из &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть если на вход автомату подать &amp;lt;tex&amp;gt;xy&amp;lt;/tex&amp;gt;, то в конце обработки мы окажемся в терминальном состоянии. Предположим, что автомат, закончив обработку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, находится в состоянии &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_0, x) = q_i&amp;lt;/tex&amp;gt;. Мы должны проверить, что существует строка &amp;lt;tex&amp;gt;y, |y| = |x|,&amp;lt;/tex&amp;gt; которая ведет из состояния &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt; до какого-нибудь терминального состояния &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_i, y) \in F&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Предположим, что мы прошли &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин автомата, то есть &amp;lt;tex&amp;gt;|x| = n&amp;lt;/tex&amp;gt;. Обозначим за &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; множество всех состояний, с которых можно попасть в терминальные за &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; шагов. Тогда &amp;lt;tex&amp;gt;q_i \in S_n \Leftrightarrow x \in half(L)&amp;lt;/tex&amp;gt;. Если мы сможем отслеживать &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то сможем определять, верно ли, что &amp;lt;tex&amp;gt;x \in half(L)&amp;lt;/tex&amp;gt;. Заметим, что &amp;lt;tex&amp;gt;S_0 \equiv F&amp;lt;/tex&amp;gt;. Очевидно мы можем построить &amp;lt;tex&amp;gt;S_{n+1}&amp;lt;/tex&amp;gt; зная &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S_{n+1} = prev(S_n) = \{ q \in Q \mid \exists a \in \Sigma, q' \in S_n, \delta(q, a) = q' \}&amp;lt;/tex&amp;gt; {{---}} множество состояний, из которых есть переход в какое-либо состояние из &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; (по единственному символу). Теперь надо найти способ отслеживать и обновлять &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Построим ДКА &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt;, который будет хранить эту информацию в своих состояниях. Определим &amp;lt;tex&amp;gt;Q' = Q \times 2^Q&amp;lt;/tex&amp;gt;, то есть каждое состояние &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; {{---}} это пара из одиночного состояния из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; и множества состояний из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;. Функцию перехода &amp;lt;tex&amp;gt;\delta'&amp;lt;/tex&amp;gt; автомата &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; определим так, чтобы если по какой-то строке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; длины &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; в автомате &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; мы перешли в состояние &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то по этой же строке в автомате &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; мы перейдем в состояние &amp;lt;tex&amp;gt;(q_i, S_n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; {{---}} множество состояний из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, определенное выше. Вспомним приведенную выше функцию &amp;lt;tex&amp;gt;prev(S_n) = S_{n+1}&amp;lt;/tex&amp;gt;. С ее помощью мы можем определить функцию перехода следующим образом: &amp;lt;tex&amp;gt;\delta'((q, S), a) = (\delta(q, a), prev(S))&amp;lt;/tex&amp;gt;. Начальное состояние &amp;lt;tex&amp;gt;q_0' = (q_0, S_0) = (q_0, F)&amp;lt;/tex&amp;gt;. Множество терминальных состояний {{---}} &amp;lt;tex&amp;gt;F' = \{ (q, S) \mid q \in S, S \in 2^Q \}&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь по индукции не сложно доказать, что &amp;lt;tex&amp;gt;\delta'(q_0', x) = (\delta(q_0, x), S_n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;|x| = n&amp;lt;/tex&amp;gt;. По определению множества терминальных вершин, автомат &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; допускает строку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; тогда и только тогда, когда &amp;lt;tex&amp;gt;\delta(q_0, x) \in S_n&amp;lt;/tex&amp;gt;. Следовательно, автомат &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; допускает язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;.Таким образом, мы построили ДКА, который допускает язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;. Следовательно, данный язык является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
=== Язык &amp;lt;tex&amp;gt;alt(L, M)&amp;lt;/tex&amp;gt; ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Пусть &amp;lt;tex&amp;gt;w = w_1 w_2 \dots w_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;x = x_1 x_2 \dots x_n&amp;lt;/tex&amp;gt;. Определим &amp;lt;tex&amp;gt;alt(w, x) = w_1 x_1 w_2 x_2 \dots w_n x_n&amp;lt;/tex&amp;gt;. Распространим это определение на языки следующим образом: пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; {{---}} два языка над одним алфавитом &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;alt(L, M) = \{ alt(w, x) \mid |w| = |x|, w \in L, x \in M \}&amp;lt;/tex&amp;gt;.}}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ 10, 00, 111, 1001 \}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M = \{ 11, 0101 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;alt(L, M) = \{ 1101, 0101, 10010011 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st4&lt;br /&gt;
|statement = Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; {{---}} регулярные языки. Тогда &amp;lt;tex&amp;gt;alt(L, M)&amp;lt;/tex&amp;gt; также является регулярным.&lt;br /&gt;
|proof = Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; {{---}} регулярные языки, то существуют ДКА &amp;lt;tex&amp;gt;D_L = \langle \Sigma , Q_L , q_{0L} , F_L, \delta_L \rangle&amp;lt;/tex&amp;gt;, распознающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;D_M = \langle \Sigma , Q_M , q_{0M} , F_M, \delta_M \rangle&amp;lt;/tex&amp;gt;, распознающий язык &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;. Построим автомат &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt;, который будет распознавать язык &amp;lt;tex&amp;gt;alt(L, M)&amp;lt;/tex&amp;gt;. Идея следующая: каждое состояние этого автомата будем описывать тремя значениями &amp;lt;tex&amp;gt;(p, q, b)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;p \in Q_L&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;q \in Q_M&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;b \in \{ 1, 0 \}&amp;lt;/tex&amp;gt;. Нам нужно организовать чередование переходов по состояниям автоматов, то есть если мы на определенном шаге перешли от одного состояния автомата &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt; до другого, то на следующем мы обязаны совершить переход по состояниям автомата &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt;. Для этого нам нужно обновлять состояние одного автомата и при этом сохранять состояние другого для следующего перехода. Тут мы будем использовать третье значение: если &amp;lt;tex&amp;gt;b = 0&amp;lt;/tex&amp;gt;, то будет двигаться по состояниям первого автомата, то есть значение &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; при переходе в новое состояние автомата &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt; поменяется, &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; останется неизменной, &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; станет &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;b = 1&amp;lt;/tex&amp;gt;, то, соответственно, все наоборот. То есть у нас будут две функции перехода, выбирать нужную будем в зависимости от четности третьего параметра. Важно, что на каждом шаге мы инвертируем значение &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt;, что гарантирует чередование. Определим автомат &amp;lt;tex&amp;gt;D_{alt} = \langle \Sigma, Q', q_0', F', \delta' \rangle&amp;lt;/tex&amp;gt; следующим образом:&lt;br /&gt;
# &amp;lt;tex&amp;gt;Q' = Q_L \times Q_M \times \{ 0, 1 \}&amp;lt;/tex&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt;q_0' = (q_{0L}, q_{0M}, 0)&amp;lt;/tex&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt;F' = F_L \times F_M \times \{ 0 \}&amp;lt;/tex&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt;\delta'((p, q, 0), a) = (\delta_L(p, a), q, 1)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta'((p, q, 1), a) = (p, \delta_M(q, a), 0)&amp;lt;/tex&amp;gt;&lt;br /&gt;
Стартовая вершина имеет третий параметр &amp;lt;tex&amp;gt;b = 0&amp;lt;/tex&amp;gt;, так как первое значение должно быть получено из автомата &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt;. Аналогично все терминальные вершины должны иметь то же значение последнего параметра, так как количество переходов должно быть четным и последний переход должен был быть осуществлен по автомату &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt;. Функция перехода &amp;lt;tex&amp;gt;\delta'&amp;lt;/tex&amp;gt; использует &amp;lt;tex&amp;gt;\delta_L&amp;lt;/tex&amp;gt; для получения нечетных символов и &amp;lt;tex&amp;gt;\delta_M&amp;lt;/tex&amp;gt; для четных. Таким образом, &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt; состоит из чередующихся символов &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt; принимает &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; тогда и только тогда, когда &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt; последовательно принимает все нечетные символы &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt; {{---}} все четные, а так же &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; имеет четную длину. Следовательно, &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt; распознает язык &amp;lt;tex&amp;gt;alt(L, M)&amp;lt;/tex&amp;gt;, что доказывает, что &amp;lt;tex&amp;gt;alt(L, M)&amp;lt;/tex&amp;gt; является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
Чтобы более наглядно показать, как строится автомат &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt;, разберем пример. Пусть &amp;lt;tex&amp;gt;L = \{ 1, 11 \}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M = \{ 00 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt; ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt; как множество &amp;lt;tex&amp;gt;\{ w \mid &amp;lt;/tex&amp;gt; цепочку &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; можно представить в виде &amp;lt;tex&amp;gt;w = xy&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;yx \in L \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ 01, 011 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;cycle(L) = \{ 01, 10, 011, 110, 101 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st5&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык. Тогда язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
[[Файл:Enfa_before.jpg|right|thumb|380px|Рис. 1. Разбиение автомата.]]&lt;br /&gt;
[[Файл:Enfa-after.jpg|right|thumb|380px|Рис. 2. Перестроение.]]&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык, то существует допускающий его ДКА &amp;lt;tex&amp;gt;M = \langle \Sigma , Q , q_0 , F , \delta \rangle &amp;lt;/tex&amp;gt;. Построим из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; недетерминированный автомат с &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходами следующим образом: рассмотрим состояние &amp;lt;tex&amp;gt;q \in Q&amp;lt;/tex&amp;gt;, из которого есть переходы в другие состояния (то есть начиная с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; можно построить непустое слово, заканчивающееся в терминальной вершине). Тогда если какое-то слово проходит через это состояние, оно может быть зациклено таким образом, что его суффикс, начинающийся с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, станет префиксом нового слова, а префикс, заканчивающийся в &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; {{---}} суффиксом. Разделим автомат на две части &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt; будет содержать все вершины, из которых достижима &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; {{---}} все вершины, которые достижимы из &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; (см. рис. 1). Заметим, что каждая вершина может содержаться в обеих частях одновременно, такое может случиться, если автомат &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; содержит циклы. Теперь перестроим автомат так, что он будет принимать слова &amp;quot;зацикленные&amp;quot; вокруг &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, то есть начинающиеся с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; и после достижения терминальной вершины продолжающиеся с &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; (см. рис. 2). Для этого стартовой вершиной сделаем &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; и построим от нее часть &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt;. Теперь добавим состояние &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; и соединим с ним все терминальные состояния из &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; с помощью &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходов. Далее построим от &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; часть &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt;. Добавим вершину &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt;, эквивалентную &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, и сделаем ее терминальной. Данный автомат принимает слова, зацикленные вокруг выбранной вершины &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. Мы хотим, чтобы автомат принимал слова, зацикленные вокруг любой такой &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. Для этого создадим новую стартовую вершину &amp;lt;tex&amp;gt;q_0'&amp;lt;/tex&amp;gt; и свяжем ее &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходами со всеми перестроенными автоматами (зацикленными вокруг всех подходящих &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;), в том числе и с изначальным автоматом. Построенный автомат допускает язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt;, следовательно, данный язык является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Ex_1_before.jpg|left|thumb|260px|Рис. 3. Автомат, принимающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
[[Файл:Ex_1_after.jpg|right|thumb|380px|Рис. 4. Автомат, принимающий язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
Для лучшего понимания алгоритма перестроения автомата рассмотрим пример.&amp;lt;br&amp;gt;&lt;br /&gt;
На рис. 3 представлен автомат, допускающий язык &amp;lt;tex&amp;gt;L = \{ ab, abb, ac \}&amp;lt;/tex&amp;gt;. На рис. 4 показано, как этот автомат был перестроен. Были добавлены части, зацикленные  относительно вершин &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;. Появилась новая стартовая вершина &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, которая связана &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходами с изначальным автоматом и его измененными версиями. Данный автомат распознает язык &amp;lt;tex&amp;gt;cycle(L) = \{ ab, abb, ac, ba, bba, ca, bab \}&amp;lt;/tex&amp;gt;: первые три слова распознает первая часть, которая совпадает с изначальным автоматом; следующие три {{---}} вторая, перестроенная относительно вершины &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;; последнее слово распознает третья часть, зацикленная относительно вершины &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=57931</id>
		<title>Обсуждение участницы:Анна</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=57931"/>
				<updated>2016-12-17T16:36:09Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: /* Язык alt(L, M) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Примеры доказательств ==&lt;br /&gt;
=== Язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt; ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt; как множество первых половин цепочек языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть множество &amp;lt;tex&amp;gt;\{ w \mid &amp;lt;/tex&amp;gt; существует &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, для которой &amp;lt;tex&amp;gt;wx \in L&amp;lt;/tex&amp;gt;, причем &amp;lt;tex&amp;gt;|w| = |x| \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ \varepsilon, 0010, 011, 010110 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;half(L) = \{ \varepsilon, 00, 010 \}&amp;lt;/tex&amp;gt;. Заметим, что цепочки нечетной длины не влияют на &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st3&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык. Тогда язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык, то существует ДКА &amp;lt;tex&amp;gt;M = \langle \Sigma , Q , q_0 , F , \delta \rangle &amp;lt;/tex&amp;gt;, допускающий его. Рассмотрим строку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Для того, чтобы проверить, что &amp;lt;tex&amp;gt;x \in half(L)&amp;lt;/tex&amp;gt;, нам надо убедиться, что существует строка &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; такой же длины, что и &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, которая, будучи сконкатенированной с &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, даст строку из &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть если на вход автомату подать &amp;lt;tex&amp;gt;xy&amp;lt;/tex&amp;gt;, то в конце обработки мы окажемся в терминальном состоянии. Предположим, что автомат, закончив обработку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, находится в состоянии &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_0, x) = q_i&amp;lt;/tex&amp;gt;. Мы должны проверить, что существует строка &amp;lt;tex&amp;gt;y, |y| = |x|,&amp;lt;/tex&amp;gt; которая ведет из состояния &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt; до какого-нибудь терминального состояния &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_i, y) \in F&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Предположим, что мы прошли &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин автомата, то есть &amp;lt;tex&amp;gt;|x| = n&amp;lt;/tex&amp;gt;. Обозначим за &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; множество всех состояний, с которых можно попасть в терминальные за &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; шагов. Тогда &amp;lt;tex&amp;gt;q_i \in S_n \Leftrightarrow x \in half(L)&amp;lt;/tex&amp;gt;. Если мы сможем отслеживать &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то сможем определять, верно ли, что &amp;lt;tex&amp;gt;x \in half(L)&amp;lt;/tex&amp;gt;. Заметим, что &amp;lt;tex&amp;gt;S_0 \equiv F&amp;lt;/tex&amp;gt;. Очевидно мы можем построить &amp;lt;tex&amp;gt;S_{n+1}&amp;lt;/tex&amp;gt; зная &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S_{n+1} = prev(S_n) = \{ q \in Q \mid \exists a \in \Sigma, q' \in S_n, \delta(q, a) = q' \}&amp;lt;/tex&amp;gt; {{---}} множество состояний, из которых есть переход в какое-либо состояние из &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; (по единственному символу). Теперь надо найти способ отслеживать и обновлять &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Построим ДКА &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt;, который будет хранить эту информацию в своих состояниях. Определим &amp;lt;tex&amp;gt;Q' = Q \times 2^Q&amp;lt;/tex&amp;gt;, то есть каждое состояние &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; {{---}} это пара из одиночного состояния из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; и множества состояний из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;. Функцию перехода &amp;lt;tex&amp;gt;\delta'&amp;lt;/tex&amp;gt; автомата &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; определим так, чтобы если по какой-то строке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; длины &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; в автомате &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; мы перешли в состояние &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то по этой же строке в автомате &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; мы перейдем в состояние &amp;lt;tex&amp;gt;(q_i, S_n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; {{---}} множество состояний из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, определенное выше. Вспомним приведенную выше функцию &amp;lt;tex&amp;gt;prev(S_n) = S_{n+1}&amp;lt;/tex&amp;gt;. С ее помощью мы можем определить функцию перехода следующим образом: &amp;lt;tex&amp;gt;\delta'((q, S), a) = (\delta(q, a), prev(S))&amp;lt;/tex&amp;gt;. Начальное состояние &amp;lt;tex&amp;gt;q_0' = (q_0, S_0) = (q_0, F)&amp;lt;/tex&amp;gt;. Множество терминальных состояний {{---}} &amp;lt;tex&amp;gt;F' = \{ (q, S) \mid q \in S, S \in 2^Q \}&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь по индукции не сложно доказать, что &amp;lt;tex&amp;gt;\delta'(q_0', x) = (\delta(q_0, x), S_n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;|x| = n&amp;lt;/tex&amp;gt;. По определению множества терминальных вершин, автомат &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; допускает строку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; тогда и только тогда, когда &amp;lt;tex&amp;gt;\delta(q_0, x) \in S_n&amp;lt;/tex&amp;gt;. Следовательно, автомат &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; допускает язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;.Таким образом, мы построили ДКА, который допускает язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;. Следовательно, данный язык является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
=== Язык &amp;lt;tex&amp;gt;alt(L, M)&amp;lt;/tex&amp;gt; ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Пусть &amp;lt;tex&amp;gt;w = w_1 w_2 \dots w_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;x = x_1 x_2 \dots x_n&amp;lt;/tex&amp;gt;. Определим &amp;lt;tex&amp;gt;alt(w, x) = w_1 x_1 w_2 x_2 \dots w_n x_n&amp;lt;/tex&amp;gt;. Распространим это определение на языки следующим образом: пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; {{---}} два языка над одним алфавитом &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;alt(L, M) = \{ alt(w, x) \mid |w| = |x|, w \in L, x \in M \}&amp;lt;/tex&amp;gt;.}}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ 10, 00, 111, 1001 \}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M = \{ 11, 0101 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;alt(L, M) = \{ 1101, 0101, 10010011 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st4&lt;br /&gt;
|statement = Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; {{---}} регулярные языки. Тогда &amp;lt;tex&amp;gt;alt(L, M)&amp;lt;/tex&amp;gt; также является регулярным.&lt;br /&gt;
|proof = Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; {{---}} регулярные языки, то существуют ДКА &amp;lt;tex&amp;gt;D_L = \langle \Sigma , Q_L , q_{0L} , F_L, \delta_L \rangle&amp;lt;/tex&amp;gt;, распознающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;D_M = \langle \Sigma , Q_M , q_{0M} , F_M, \delta_M \rangle&amp;lt;/tex&amp;gt;, распознающий язык &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;. Построим автомат &amp;lt;tex&amp;gt;D_{alt}&amp;lt;/tex&amp;gt;, который будет распознавать язык &amp;lt;tex&amp;gt;alt(L, M)&amp;lt;/tex&amp;gt;. Идея следующая: каждое состояние этого автомата будем описывать тремя значениями &amp;lt;tex&amp;gt;(p, q, b)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;p \in Q_L&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;q \in Q_M&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;b \in \{ 1, 0 \}&amp;lt;/tex&amp;gt;. Нам нужно организовать чередование переходов по состояниям автоматов, то есть если мы на определенном шаге перешли от одного состояния автомата &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt; до другого, то на следующем мы обязаны совершить переход по состояниям автомата &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt;. Для этого будем использовать третье значение {{---}} если &amp;lt;tex&amp;gt;b = 0&amp;lt;/tex&amp;gt;, то будет двигаться по состояниям первого автомата, то есть &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; поменяется, &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; останется неизменной, &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; станет &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;b = 1&amp;lt;/tex&amp;gt;, то, соответственно, все наоборот. То есть в зависимости от четности третьего параметра будем использовать две функции перехода. Важно, что на каждом шаге мы инвертируем значение &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt;, что гарантирует чередование. Определим автомат &amp;lt;tex&amp;gt;D_{alt} = \langle \Sigma, Q', q_0', F', \delta' \rangle&amp;lt;/tex&amp;gt; следующим образом:&lt;br /&gt;
# &amp;lt;tex&amp;gt;Q' = Q_L \times Q_M \times \{ 0, 1 \}&amp;lt;/tex&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt;q_0' = (q_{0L}, q_{0M}, 0)&amp;lt;/tex&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt;F' = F_L \times F_M \times \{ 0 \}&amp;lt;/tex&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt;\delta'((p, q, 0), a) = (\delta_L(p, a), q, 1)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta'((p, q, 1), a) = (p, \delta_M(q, a), 0)&amp;lt;/tex&amp;gt;&lt;br /&gt;
Стартовая вершина имеет третий параметр &amp;lt;tex&amp;gt;b = 0&amp;lt;/tex&amp;gt;, так как первое значение должно быть получено из автомата &amp;lt;tex&amp;gt;D_L&amp;lt;/tex&amp;gt;. Аналогично все терминальные вершины должны иметь то же значение последнего параметра, так как количество переходов должно быть четным и последний переход должен был быть осуществлен по автомату &amp;lt;tex&amp;gt;D_M&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt; ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt; как множество &amp;lt;tex&amp;gt;\{ w \mid &amp;lt;/tex&amp;gt; цепочку &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; можно представить в виде &amp;lt;tex&amp;gt;w = xy&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;yx \in L \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ 01, 011 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;cycle(L) = \{ 01, 10, 011, 110, 101 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st5&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык. Тогда язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
[[Файл:Enfa_before.jpg|right|thumb|380px|Рис. 1. Разбиение автомата.]]&lt;br /&gt;
[[Файл:Enfa-after.jpg|right|thumb|380px|Рис. 2. Перестроение.]]&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык, то существует допускающий его ДКА &amp;lt;tex&amp;gt;M = \langle \Sigma , Q , q_0 , F , \delta \rangle &amp;lt;/tex&amp;gt;. Построим из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; недетерминированный автомат с &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходами следующим образом: рассмотрим состояние &amp;lt;tex&amp;gt;q \in Q&amp;lt;/tex&amp;gt;, из которого есть переходы в другие состояния (то есть начиная с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; можно построить непустое слово, заканчивающееся в терминальной вершине). Тогда если какое-то слово проходит через это состояние, оно может быть зациклено таким образом, что его суффикс, начинающийся с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, станет префиксом нового слова, а префикс, заканчивающийся в &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; {{---}} суффиксом. Разделим автомат на две части &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt; будет содержать все вершины, из которых достижима &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; {{---}} все вершины, которые достижимы из &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; (см. рис. 1). Заметим, что каждая вершина может содержаться в обеих частях одновременно, такое может случиться, если автомат &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; содержит циклы. Теперь перестроим автомат так, что он будет принимать слова &amp;quot;зацикленные&amp;quot; вокруг &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, то есть начинающиеся с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; и после достижения терминальной вершины продолжающиеся с &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; (см. рис. 2). Для этого стартовой вершиной сделаем &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; и построим от нее часть &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt;. Теперь добавим состояние &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; и соединим с ним все терминальные состояния из &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; с помощью &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходов. Далее построим от &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; часть &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt;. Добавим вершину &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt;, эквивалентную &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, и сделаем ее терминальной. Данный автомат принимает слова, зацикленные вокруг выбранной вершины &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. Мы хотим, чтобы автомат принимал слова, зацикленные вокруг любой такой &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. Для этого создадим новую стартовую вершину &amp;lt;tex&amp;gt;q_0'&amp;lt;/tex&amp;gt; и свяжем ее &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходами со всеми перестроенными автоматами (зацикленными вокруг всех подходящих &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;), в том числе и с изначальным автоматом. Построенный автомат допускает язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt;, следовательно, данный язык является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Ex_1_before.jpg|left|thumb|260px|Рис. 3. Автомат, принимающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
[[Файл:Ex_1_after.jpg|right|thumb|380px|Рис. 4. Автомат, принимающий язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
Для лучшего понимания алгоритма перестроения автомата рассмотрим пример.&amp;lt;br&amp;gt;&lt;br /&gt;
На рис. 3 представлен автомат, допускающий язык &amp;lt;tex&amp;gt;L = \{ ab, abb, ac \}&amp;lt;/tex&amp;gt;. На рис. 4 показано, как этот автомат был перестроен. Были добавлены части, зацикленные  относительно вершин &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;. Появилась новая стартовая вершина &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, которая связана &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходами с изначальным автоматом и его измененными версиями. Данный автомат распознает язык &amp;lt;tex&amp;gt;cycle(L) = \{ ab, abb, ac, ba, bba, ca, bab \}&amp;lt;/tex&amp;gt;: первые три слова распознает первая часть, которая совпадает с изначальным автоматом; следующие три {{---}} вторая, перестроенная относительно вершины &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;; последнее слово распознает третья часть, зацикленная относительно вершины &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=57877</id>
		<title>Обсуждение участницы:Анна</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=57877"/>
				<updated>2016-12-15T08:32:10Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Примеры доказательств ==&lt;br /&gt;
=== Язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt; ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt; как множество первых половин цепочек языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть множество &amp;lt;tex&amp;gt;\{ w \mid &amp;lt;/tex&amp;gt; существует &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, для которой &amp;lt;tex&amp;gt;wx \in L&amp;lt;/tex&amp;gt;, причем &amp;lt;tex&amp;gt;|w| = |x| \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ \varepsilon, 0010, 011, 010110 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;half(L) = \{ \varepsilon, 00, 010 \}&amp;lt;/tex&amp;gt;. Заметим, что цепочки нечетной длины не влияют на &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st3&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык. Тогда язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык, то существует ДКА &amp;lt;tex&amp;gt;M = \langle \Sigma , Q , q_0 , F , \delta \rangle &amp;lt;/tex&amp;gt;, допускающий его. Рассмотрим строку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Для того, чтобы проверить, что &amp;lt;tex&amp;gt;x \in half(L)&amp;lt;/tex&amp;gt;, нам надо убедиться, что существует строка &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; такой же длины, что и &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, которая, будучи сконкатенированной с &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, даст строку из &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть если на вход автомату подать &amp;lt;tex&amp;gt;xy&amp;lt;/tex&amp;gt;, то в конце обработки мы окажемся в терминальном состоянии. Предположим, что автомат, закончив обработку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, находится в состоянии &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_0, x) = q_i&amp;lt;/tex&amp;gt;. Мы должны проверить, что существует строка &amp;lt;tex&amp;gt;y, |y| = |x|,&amp;lt;/tex&amp;gt; которая ведет из состояния &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt; до какого-нибудь терминального состояния &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_i, y) \in F&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Предположим, что мы прошли &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин автомата, то есть &amp;lt;tex&amp;gt;|x| = n&amp;lt;/tex&amp;gt;. Обозначим за &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; множество всех состояний, с которых можно попасть в терминальные за &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; шагов. Тогда &amp;lt;tex&amp;gt;q_i \in S_n \Leftrightarrow x \in half(L)&amp;lt;/tex&amp;gt;. Если мы сможем отслеживать &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то сможем определять, верно ли, что &amp;lt;tex&amp;gt;x \in half(L)&amp;lt;/tex&amp;gt;. Заметим, что &amp;lt;tex&amp;gt;S_0 \equiv F&amp;lt;/tex&amp;gt;. Очевидно мы можем построить &amp;lt;tex&amp;gt;S_{n+1}&amp;lt;/tex&amp;gt; зная &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S_{n+1} = prev(S_n) = \{ q \in Q \mid \exists a \in \Sigma, q' \in S_n, \delta(q, a) = q' \}&amp;lt;/tex&amp;gt; {{---}} множество состояний, из которых есть переход в какое-либо состояние из &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; (по единственному символу). Теперь надо найти способ отслеживать и обновлять &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Построим ДКА &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt;, который будет хранить эту информацию в своих состояниях. Определим &amp;lt;tex&amp;gt;Q' = Q \times 2^Q&amp;lt;/tex&amp;gt;, то есть каждое состояние &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; {{---}} это пара из одиночного состояния из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; и множества состояний из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;. Функцию перехода &amp;lt;tex&amp;gt;\delta'&amp;lt;/tex&amp;gt; автомата &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; определим так, чтобы если по какой-то строке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; длины &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; в автомате &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; мы перешли в состояние &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то по этой же строке в автомате &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; мы перейдем в состояние &amp;lt;tex&amp;gt;(q_i, S_n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; {{---}} множество состояний из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, определенное выше. Вспомним приведенную выше функцию &amp;lt;tex&amp;gt;prev(S_n) = S_{n+1}&amp;lt;/tex&amp;gt;. С ее помощью мы можем определить функцию перехода следующим образом: &amp;lt;tex&amp;gt;\delta'((q, S), a) = (\delta(q, a), prev(S))&amp;lt;/tex&amp;gt;. Начальное состояние &amp;lt;tex&amp;gt;q_0' = (q_0, S_0) = (q_0, F)&amp;lt;/tex&amp;gt;. Множество терминальных состояний {{---}} &amp;lt;tex&amp;gt;F' = \{ (q, S) \mid q \in S, S \in 2^Q \}&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь по индукции не сложно доказать, что &amp;lt;tex&amp;gt;\delta'(q_0', x) = (\delta(q_0, x), S_n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;|x| = n&amp;lt;/tex&amp;gt;. По определению множества терминальных вершин, автомат &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; допускает строку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; тогда и только тогда, когда &amp;lt;tex&amp;gt;\delta(q_0, x) \in S_n&amp;lt;/tex&amp;gt;. Следовательно, автомат &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; допускает язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;.Таким образом, мы построили ДКА, который допускает язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;. Следовательно, данный язык является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
=== Язык &amp;lt;tex&amp;gt;alt(L, M)&amp;lt;/tex&amp;gt; ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Пусть &amp;lt;tex&amp;gt;w = w_1 w_2 \dots w_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;x = x_1 x_2 \dots x_n&amp;lt;/tex&amp;gt;. Определим &amp;lt;tex&amp;gt;alt(w, x) = w_1 x_1 w_2 x_2 \dots w_n x_n&amp;lt;/tex&amp;gt;. Распространим это определение на языки следующим образом: пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; {{---}} два языка над одним алфавитом &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;alt(L, M) = \{ alt(w, x) \mid |w| = |x|, w \in L, x \in M \}&amp;lt;/tex&amp;gt;.}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st4&lt;br /&gt;
|statement = Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; {{---}} регулярные языки. Тогда &amp;lt;tex&amp;gt;alt(L, M)&amp;lt;/tex&amp;gt; также является регулярным.&lt;br /&gt;
|proof = Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; {{---}} регулярные языки, то существуют ДКА &amp;lt;tex&amp;gt;D_L = \langle \Sigma , Q_L , q_{0L} , F_L , \delta_L \rangle &amp;lt;/tex&amp;gt;, распознающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;D_M = \langle \Sigma , Q_M , q_{0M} , F_M , \delta_M \rangle &amp;lt;/tex&amp;gt;, распознающий &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
=== Язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt; ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt; как множество &amp;lt;tex&amp;gt;\{ w \mid &amp;lt;/tex&amp;gt; цепочку &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; можно представить в виде &amp;lt;tex&amp;gt;w = xy&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;yx \in L \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ 01, 011 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;cycle(L) = \{ 01, 10, 011, 110, 101 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st5&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык. Тогда язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
[[Файл:Enfa_before.jpg|right|thumb|380px|Рис. 1. Разбиение автомата.]]&lt;br /&gt;
[[Файл:Enfa-after.jpg|right|thumb|380px|Рис. 2. Перестроение.]]&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык, то существует допускающий его ДКА &amp;lt;tex&amp;gt;M = \langle \Sigma , Q , q_0 , F , \delta \rangle &amp;lt;/tex&amp;gt;. Построим из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; недетерминированный автомат с &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходами следующим образом: рассмотрим состояние &amp;lt;tex&amp;gt;q \in Q&amp;lt;/tex&amp;gt;, из которого есть переходы в другие состояния (то есть начиная с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; можно построить непустое слово, заканчивающееся в терминальной вершине). Тогда если какое-то слово проходит через это состояние, оно может быть зациклено таким образом, что его суффикс, начинающийся с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, станет префиксом нового слова, а префикс, заканчивающийся в &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; {{---}} суффиксом. Разделим автомат на две части &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt; будет содержать все вершины, из которых достижима &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; {{---}} все вершины, которые достижимы из &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; (см. рис. 1). Заметим, что каждая вершина может содержаться в обеих частях одновременно, такое может случиться, если автомат &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; содержит циклы. Теперь перестроим автомат так, что он будет принимать слова &amp;quot;зацикленные&amp;quot; вокруг &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, то есть начинающиеся с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; и после достижения терминальной вершины продолжающиеся с &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; (см. рис. 2). Для этого стартовой вершиной сделаем &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; и построим от нее часть &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt;. Теперь добавим состояние &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; и соединим с ним все терминальные состояния из &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; с помощью &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходов. Далее построим от &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; часть &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt;. Добавим вершину &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt;, эквивалентную &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, и сделаем ее терминальной. Данный автомат принимает слова, зацикленные вокруг выбранной вершины &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. Мы хотим, чтобы автомат принимал слова, зацикленные вокруг любой такой &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. Для этого создадим новую стартовую вершину &amp;lt;tex&amp;gt;q_0'&amp;lt;/tex&amp;gt; и свяжем ее &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходами со всеми перестроенными автоматами (зацикленными вокруг всех подходящих &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;), в том числе и с изначальным автоматом. Построенный автомат допускает язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt;, следовательно, данный язык является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Ex_1_before.jpg|left|thumb|260px|Рис. 3. Автомат, принимающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
[[Файл:Ex_1_after.jpg|right|thumb|380px|Рис. 4. Автомат, принимающий язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
Для лучшего понимания алгоритма перестроения автомата рассмотрим пример.&amp;lt;br&amp;gt;&lt;br /&gt;
На рис. 3 представлен автомат, допускающий язык &amp;lt;tex&amp;gt;L = \{ ab, abb, ac \}&amp;lt;/tex&amp;gt;. На рис. 4 показано, как этот автомат был перестроен. Были добавлены части, зацикленные  относительно вершин &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;. Появилась новая стартовая вершина &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, которая связана &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходами с изначальным автоматом и его измененными версиями. Данный автомат распознает язык &amp;lt;tex&amp;gt;cycle(L) = \{ ab, abb, ac, ba, bba, ca, bab \}&amp;lt;/tex&amp;gt;: первые три слова распознает первая часть, которая совпадает с изначальным автоматом; следующие три {{---}} вторая, перестроенная относительно вершины &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;; последнее слово распознает третья часть, зацикленная относительно вершины &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Enfa-after.jpg&amp;diff=57876</id>
		<title>Файл:Enfa-after.jpg</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Enfa-after.jpg&amp;diff=57876"/>
				<updated>2016-12-15T08:22:31Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: загружена новая версия «Файл:Enfa-after.jpg»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Enfa_before.jpg&amp;diff=57875</id>
		<title>Файл:Enfa before.jpg</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Enfa_before.jpg&amp;diff=57875"/>
				<updated>2016-12-15T08:19:03Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: загружена новая версия «Файл:Enfa before.jpg»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Ex_1_after.jpg&amp;diff=57874</id>
		<title>Файл:Ex 1 after.jpg</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Ex_1_after.jpg&amp;diff=57874"/>
				<updated>2016-12-15T08:15:24Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: загружена новая версия «Файл:Ex 1 after.jpg»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Ex_1_before.jpg&amp;diff=57873</id>
		<title>Файл:Ex 1 before.jpg</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Ex_1_before.jpg&amp;diff=57873"/>
				<updated>2016-12-15T08:12:09Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: загружена новая версия «Файл:Ex 1 before.jpg»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=57860</id>
		<title>Обсуждение участницы:Анна</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=57860"/>
				<updated>2016-12-14T21:04:29Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt; как множество первых половин цепочек языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть множество &amp;lt;tex&amp;gt;\{ w \mid &amp;lt;/tex&amp;gt; существует &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, для которой &amp;lt;tex&amp;gt;wx \in L&amp;lt;/tex&amp;gt;, причем &amp;lt;tex&amp;gt;|w| = |x| \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ \varepsilon, 0010, 011, 010110 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;half(L) = \{ \varepsilon, 00, 010 \}&amp;lt;/tex&amp;gt;. Заметим, что цепочки нечетной длины не влияют на &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt; как множество &amp;lt;tex&amp;gt;\{ w \mid &amp;lt;/tex&amp;gt; цепочку &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; можно представить в виде &amp;lt;tex&amp;gt;w = xy&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;yx \in L \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ 01, 011 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;cycle(L) = \{ 01, 10, 011, 110, 101 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st3&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык. Тогда язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык, то существует ДКА &amp;lt;tex&amp;gt;M = \langle \Sigma , Q , q_0 , F , \delta \rangle &amp;lt;/tex&amp;gt;, допускающий его. Рассмотрим строку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Для того, чтобы проверить, что &amp;lt;tex&amp;gt;x \in half(L)&amp;lt;/tex&amp;gt;, нам надо убедиться, что существует строка &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; такой же длины, что и &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, которая, будучи сконкатенированной с &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, даст строку из &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть если на вход автомату подать &amp;lt;tex&amp;gt;xy&amp;lt;/tex&amp;gt;, то в конце обработки мы окажемся в терминальном состоянии. Предположим, что автомат, закончив обработку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, находится в состоянии &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_0, x) = q_i&amp;lt;/tex&amp;gt;. Мы должны проверить, что существует строка &amp;lt;tex&amp;gt;y, |y| = |x|,&amp;lt;/tex&amp;gt; которая ведет из состояния &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt; до какого-нибудь терминального состояния &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_i, y) \in F&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Предположим, что мы прошли &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин автомата, то есть &amp;lt;tex&amp;gt;|x| = n&amp;lt;/tex&amp;gt;. Обозначим за &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; множество всех состояний, с которых можно попасть в терминальные за &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; шагов. Тогда &amp;lt;tex&amp;gt;q_i \in S_n \Leftrightarrow x \in half(L)&amp;lt;/tex&amp;gt;. Если мы сможем отслеживать &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то сможем определять, верно ли, что &amp;lt;tex&amp;gt;x \in half(L)&amp;lt;/tex&amp;gt;. Заметим, что &amp;lt;tex&amp;gt;S_0 \equiv F&amp;lt;/tex&amp;gt;. Очевидно мы можем построить &amp;lt;tex&amp;gt;S_{n+1}&amp;lt;/tex&amp;gt; зная &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S_{n+1} = prev(S_n) = \{ q \in Q \mid \exists a \in \Sigma, q' \in S_n, \delta(q, a) = q' \}&amp;lt;/tex&amp;gt; {{---}} множество состояний, из которых есть переход в какое-либо состояние из &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; (по единственному символу). Теперь надо найти способ отслеживать и обновлять &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Построим ДКА &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt;, который будет хранить эту информацию в своих состояниях. Определим &amp;lt;tex&amp;gt;Q' = Q \times 2^Q&amp;lt;/tex&amp;gt;, то есть каждое состояние &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; {{---}} это пара из одиночного состояния из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; и множества состояний из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;. Функцию перехода &amp;lt;tex&amp;gt;\delta'&amp;lt;/tex&amp;gt; автомата &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; определим так, чтобы если по какой-то строке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; длины &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; в автомате &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; мы перешли в состояние &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то по этой же строке в автомате &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; мы перейдем в состояние &amp;lt;tex&amp;gt;(q_i, S_n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; {{---}} множество состояний из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, определенное выше. Вспомним приведенную выше функцию &amp;lt;tex&amp;gt;prev(S_n) = S_{n+1}&amp;lt;/tex&amp;gt;. С ее помощью мы можем определить функцию перехода следующим образом: &amp;lt;tex&amp;gt;\delta'((q, S), a) = (\delta(q, a), prev(S))&amp;lt;/tex&amp;gt;. Начальное состояние &amp;lt;tex&amp;gt;q_0' = (q_0, S_0) = (q_0, F)&amp;lt;/tex&amp;gt;. Множество терминальных состояний {{---}} &amp;lt;tex&amp;gt;F' = \{ (q, S) \mid q \in S, S \in 2^Q \}&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь по индукции не сложно доказать, что &amp;lt;tex&amp;gt;\delta'(q_0', x) = (\delta(q_0, x), S_n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;|x| = n&amp;lt;/tex&amp;gt;. По определению множества терминальных вершин, автомат &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; допускает строку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; тогда и только тогда, когда &amp;lt;tex&amp;gt;\delta(q_0, x) \in S_n&amp;lt;/tex&amp;gt;. Следовательно, автомат &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; допускает язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;.Таким образом, мы построили ДКА, который допускает язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;. Следовательно, данный язык является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st4&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык. Тогда язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
[[Файл:Enfa_before.jpg|left|thumb|240px|Рис. 1. Разбиение автомата.]]&lt;br /&gt;
[[Файл:Enfa-after.jpg|right|thumb|240px|Рис. 2. Перестроение.]]&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык, то существует допускающий его ДКА &amp;lt;tex&amp;gt;M = \langle \Sigma , Q , q_0 , F , \delta \rangle &amp;lt;/tex&amp;gt;. Построим из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; недетерминированный автомат с &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходами следующим образом: рассмотрим состояние &amp;lt;tex&amp;gt;q \in Q&amp;lt;/tex&amp;gt;, из которого есть переходы в другие состояния (то есть начиная с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; можно построить непустое слово, заканчивающееся в терминальной вершине). Тогда если какое-то слово проходит через это состояние, оно может быть зациклено таким образом, что его суффикс, начинающийся с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, станет префиксом нового слова, а префикс, заканчивающийся в &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; {{---}} суффиксом. Разделим автомат на две части &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt; будет содержать все вершины, из которых достижима &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; {{---}} все вершины, которые достижимы из &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; (см. рис. 1). Заметим, что каждая вершина может содержаться в обеих частях одновременно, такое может случиться, если автомат &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; содержит циклы. Теперь перестроим автомат так, что он будет принимать слова &amp;quot;зацикленные&amp;quot; вокруг &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, то есть начинающиеся с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; и после достижения терминальной вершины продолжающиеся с &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; (см. рис. 2). Для этого стартовой вершиной сделаем &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; и построим от нее часть &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt;. Теперь добавим состояние &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; и соединим с ним все терминальные состояния из &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; с помощью &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходов. Далее построим от &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; часть &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt;. Добавим вершину &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt;, эквивалентную &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, и сделаем ее терминальной. Данный автомат принимает слова, зацикленные вокруг выбранной вершины &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. Мы хотим, чтобы автомат принимал слова, зацикленные вокруг любой такой &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. Для этого создадим новую стартовую вершину &amp;lt;tex&amp;gt;q_0'&amp;lt;/tex&amp;gt; и свяжем ее &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходами со всеми перестроенными автоматами (зацикленными вокруг всех подходящих &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;), в том числе и с изначальным автоматом. Построенный автомат допускает язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt;, следовательно, данный язык является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Ex_1_before.jpg|left|thumb|240px|Рис. 3. Автомат, принимающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
[[Файл:Ex_1_after.jpg|right|thumb|300px|Рис. 4. Автомат, принимающий язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
Для лучшего понимания алгоритма перестроения автомата рассмотрим пример.&amp;lt;br&amp;gt;&lt;br /&gt;
На рис. 3 представлен автомат, допускающий язык &amp;lt;tex&amp;gt;L = \{ ab, abb, ac \}&amp;lt;/tex&amp;gt;. На рис. 4 показано, как этот автомат был перестроен. Были добавлены части, зацикленные  относительно вершин &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;. Появилась новая стартовая вершина &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, которая связана &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходами с изначальным автоматом и его измененными версиями. Данный автомат распознает язык &amp;lt;tex&amp;gt;cycle(L) = \{ ab, abb, ac, ba, bba, ca, bab \}&amp;lt;/tex&amp;gt;: первые три слова распознает первая часть, которая совпадает с изначальным автоматом; следующие три {{---}} вторая, перестроенная относительно вершины &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;; последнее слово распознает третья часть, зацикленная относительно вершины &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=57859</id>
		<title>Обсуждение участницы:Анна</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=57859"/>
				<updated>2016-12-14T21:01:42Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt; как множество первых половин цепочек языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть множество &amp;lt;tex&amp;gt;\{ w \mid &amp;lt;/tex&amp;gt; существует &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, для которой &amp;lt;tex&amp;gt;wx \in L&amp;lt;/tex&amp;gt;, причем &amp;lt;tex&amp;gt;|w| = |x| \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ \varepsilon, 0010, 011, 010110 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;half(L) = \{ \varepsilon, 00, 010 \}&amp;lt;/tex&amp;gt;. Заметим, что цепочки нечетной длины не влияют на &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt; как множество &amp;lt;tex&amp;gt;\{ w \mid &amp;lt;/tex&amp;gt; цепочку &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; можно представить в виде &amp;lt;tex&amp;gt;w = xy&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;yx \in L \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ 01, 011 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;cycle(L) = \{ 01, 10, 011, 110, 101 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st3&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык. Тогда язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык, то существует ДКА &amp;lt;tex&amp;gt;M = \langle \Sigma , Q , q_0 , F , \delta \rangle &amp;lt;/tex&amp;gt;, допускающий его. Рассмотрим строку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Для того, чтобы проверить, что &amp;lt;tex&amp;gt;x \in half(L)&amp;lt;/tex&amp;gt;, нам надо убедиться, что существует строка &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; такой же длины, что и &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, которая, будучи сконкатенированной с &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, даст строку из &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть если на вход автомату подать &amp;lt;tex&amp;gt;xy&amp;lt;/tex&amp;gt;, то в конце обработки мы окажемся в терминальном состоянии. Предположим, что автомат, закончив обработку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, находится в состоянии &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_0, x) = q_i&amp;lt;/tex&amp;gt;. Мы должны проверить, что существует строка &amp;lt;tex&amp;gt;y, |y| = |x|,&amp;lt;/tex&amp;gt; которая ведет из состояния &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt; до какого-нибудь терминального состояния &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_i, y) \in F&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Предположим, что мы прошли &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин автомата, то есть &amp;lt;tex&amp;gt;|x| = n&amp;lt;/tex&amp;gt;. Обозначим за &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; множество всех состояний, с которых можно попасть в терминальные за &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; шагов. Тогда &amp;lt;tex&amp;gt;q_i \in S_n \Leftrightarrow x \in half(L)&amp;lt;/tex&amp;gt;. Если мы сможем отслеживать &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то сможем определять, верно ли, что &amp;lt;tex&amp;gt;x \in half(L)&amp;lt;/tex&amp;gt;. Заметим, что &amp;lt;tex&amp;gt;S_0 \equiv F&amp;lt;/tex&amp;gt;. Очевидно мы можем построить &amp;lt;tex&amp;gt;S_{n+1}&amp;lt;/tex&amp;gt; зная &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S_{n+1} = prev(S_n) = \{ q \in Q \mid \exists a \in \Sigma, q' \in S_n, \delta(q, a) = q' \}&amp;lt;/tex&amp;gt; {{---}} множество состояний, из которых есть переход в какое-либо состояние из &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; (по единственному символу). Теперь надо найти способ отслеживать и обновлять &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Построим ДКА &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt;, который будет хранить эту информацию в своих состояниях. Определим &amp;lt;tex&amp;gt;Q' = Q \times 2^Q&amp;lt;/tex&amp;gt;, то есть каждое состояние &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; {{---}} это пара из одиночного состояния из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; и множества состояний из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;. Функцию перехода &amp;lt;tex&amp;gt;\delta'&amp;lt;/tex&amp;gt; автомата &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; определим так, чтобы если по какой-то строке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; длины &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; в автомате &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; мы перешли в состояние &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то по этой же строке в автомате &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; мы перейдем в состояние &amp;lt;tex&amp;gt;(q_i, S_n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; {{---}} множество состояний из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, определенное выше. Вспомним приведенную выше функцию &amp;lt;tex&amp;gt;prev(S_n) = S_{n+1}&amp;lt;/tex&amp;gt;. С ее помощью мы можем определить функцию перехода следующим образом: &amp;lt;tex&amp;gt;\delta'((q, S), a) = (\delta(q, a), prev(S))&amp;lt;/tex&amp;gt;. Начальное состояние &amp;lt;tex&amp;gt;q_0' = (q_0, S_0) = (q_0, F)&amp;lt;/tex&amp;gt;. Множество терминальных состояний {{---}} &amp;lt;tex&amp;gt;F' = \{ (q, S) \mid q \in S, S \in 2^Q \}&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь по индукции не сложно доказать, что &amp;lt;tex&amp;gt;\delta'(q_0', x) = (\delta(q_0, x), S_n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;|x| = n&amp;lt;/tex&amp;gt;. По определению множества терминальных вершин, автомат &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; допускает строку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; тогда и только тогда, когда &amp;lt;tex&amp;gt;\delta(q_0, x) \in S_n&amp;lt;/tex&amp;gt;. Следовательно, автомат &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; допускает язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;.Таким образом, мы построили ДКА, который допускает язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;. Следовательно, данный язык является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st4&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык. Тогда язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
[[Файл:Enfa_before.jpg|left|thumb|240px|Рис. 1. Разбиение автомата.]]&lt;br /&gt;
[[Файл:Enfa-after.jpg|right|thumb|240px|Рис. 2. Перестроение.]]&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык, то существует допускающий его ДКА &amp;lt;tex&amp;gt;M = \langle \Sigma , Q , q_0 , F , \delta \rangle &amp;lt;/tex&amp;gt;. Построим из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; недетерминированный автомат с &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходами следующим образом: рассмотрим состояние &amp;lt;tex&amp;gt;q \in Q&amp;lt;/tex&amp;gt;, из которого есть переходы в другие состояния (то есть начиная с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; можно построить непустое слово, заканчивающееся в терминальной вершине). Тогда если какое-то слово проходит через это состояние, оно может быть зациклено таким образом, что его суффикс, начинающийся с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, станет префиксом нового слова, а префикс, заканчивающийся в &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; {{---}} суффиксом. Разделим автомат на две части &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt; будет содержать все вершины, из которых достижима &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; {{---}} все вершины, которые достижимы из &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; (см. рис. 1). Заметим, что каждая вершина может содержаться в обеих частях одновременно, такое может случиться, если автомат &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; содержит циклы. Теперь перестроим автомат так, что он будет принимать слова, &amp;quot;зацикленные&amp;quot; вокруг &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, то есть начинающиеся с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; и после достижения терминальной вершины продолжающиеся с &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; (см. рис. 2). Для этого стартовой вершиной сделаем &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; и построим от нее часть &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt;. Теперь добавим состояние &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; и соединим с ним все терминальные состояния из &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; с помощью &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходов. Далее построим от &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; часть &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt;. Добавим вершину &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt;, эквивалентную &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, и сделаем ее терминальной. Данный автомат принимает слова, зацикленные вокруг выбранной вершины &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. Мы хотим, чтобы автомат принимал слова, зацикленные вокруг любой такой &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. Для этого создадим новую стартовую вершину &amp;lt;tex&amp;gt;q_0'&amp;lt;/tex&amp;gt; и свяжем ее &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходами со всеми перестроенными автоматами (зацикленными вокруг всех подходящих &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;), в том числе и с изначальным автоматом. Построенный автомат допускает язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt;, следовательно, данный язык является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Ex_1_before.jpg|left|thumb|240px|Рис. 3. Автомат, принимающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
[[Файл:Ex_1_after.jpg|right|thumb|300px|Рис. 4. Автомат, принимающий язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
Для лучшего понимания алгоритма перестроения автомата рассмотрим пример.&amp;lt;br&amp;gt;&lt;br /&gt;
На рис. 3 представлен автомат, допускающий язык &amp;lt;tex&amp;gt;L = \{ ab, abb, ac \}&amp;lt;/tex&amp;gt;. На рис. 4 показано, как этот автомат был перестроен. Были добавлены части, зацикленные  относительно вершин &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;. Появилась новая стартовая вершина &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, которая связана &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходами с изначальным автоматом и его измененными версиями. Данный автомат распознает язык &amp;lt;tex&amp;gt;cycle(L) = \{ ab, abb, ac, ba, bba, ca, bab \}&amp;lt;/tex&amp;gt;: первые три слова распознает первая часть, которая совпадает с изначальным автоматом; следующие три {{---}} вторая, перестроенная относительно вершины &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;; последнее слово распознает третья часть, зацикленная относительно вершины &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Ex_2_before.jpg&amp;diff=57857</id>
		<title>Файл:Ex 2 before.jpg</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Ex_2_before.jpg&amp;diff=57857"/>
				<updated>2016-12-14T20:51:04Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Ex_1_after.jpg&amp;diff=57846</id>
		<title>Файл:Ex 1 after.jpg</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Ex_1_after.jpg&amp;diff=57846"/>
				<updated>2016-12-14T20:25:27Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Ex_1_before.jpg&amp;diff=57845</id>
		<title>Файл:Ex 1 before.jpg</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Ex_1_before.jpg&amp;diff=57845"/>
				<updated>2016-12-14T20:21:30Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=57833</id>
		<title>Обсуждение участницы:Анна</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=57833"/>
				<updated>2016-12-14T18:45:59Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt; как множество первых половин цепочек языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть множество &amp;lt;tex&amp;gt;\{ w \mid &amp;lt;/tex&amp;gt; существует &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, для которой &amp;lt;tex&amp;gt;wx \in L&amp;lt;/tex&amp;gt;, причем &amp;lt;tex&amp;gt;|w| = |x| \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ \varepsilon, 0010, 011, 010110 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;half(L) = \{ \varepsilon, 00, 010 \}&amp;lt;/tex&amp;gt;. Заметим, что цепочки нечетной длины не влияют на &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt; как множество &amp;lt;tex&amp;gt;\{ w \mid &amp;lt;/tex&amp;gt; цепочку &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; можно представить в виде &amp;lt;tex&amp;gt;w = xy&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;yx \in L \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ 01, 011 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;cycle(L) = \{ 01, 10, 011, 110, 101 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st3&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык. Тогда язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык, то существует ДКА &amp;lt;tex&amp;gt;M = \langle \Sigma , Q , q_0 , F , \delta \rangle &amp;lt;/tex&amp;gt;, допускающий его. Рассмотрим строку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Для того, чтобы проверить, что &amp;lt;tex&amp;gt;x \in half(L)&amp;lt;/tex&amp;gt;, нам надо убедиться, что существует строка &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; такой же длины, что и &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, которая, будучи сконкатенированной с &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, даст строку из &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть если на вход автомату подать &amp;lt;tex&amp;gt;xy&amp;lt;/tex&amp;gt;, то в конце обработки мы окажемся в терминальном состоянии. Предположим, что автомат, закончив обработку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, находится в состоянии &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_0, x) = q_i&amp;lt;/tex&amp;gt;. Мы должны проверить, что существует строка &amp;lt;tex&amp;gt;y, |y| = |x|,&amp;lt;/tex&amp;gt; которая ведет из состояния &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt; до какого-нибудь терминального состояния &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_i, y) \in F&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Предположим, что мы прошли &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин автомата, то есть &amp;lt;tex&amp;gt;|x| = n&amp;lt;/tex&amp;gt;. Обозначим за &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; множество всех состояний, с которых можно попасть в терминальные за &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; шагов. Тогда &amp;lt;tex&amp;gt;q_i \in S_n \Leftrightarrow x \in half(L)&amp;lt;/tex&amp;gt;. Если мы сможем отслеживать &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то сможем определять, верно ли, что &amp;lt;tex&amp;gt;x \in half(L)&amp;lt;/tex&amp;gt;. Заметим, что &amp;lt;tex&amp;gt;S_0 \equiv F&amp;lt;/tex&amp;gt;. Очевидно мы можем построить &amp;lt;tex&amp;gt;S_{n+1}&amp;lt;/tex&amp;gt; зная &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S_{n+1} = prev(S_n) = \{ q \in Q \mid \exists a \in \Sigma, q' \in S_n, \delta(q, a) = q' \}&amp;lt;/tex&amp;gt; {{---}} множество состояний, из которых есть переход в какое-либо состояние из &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; (по единственному символу). Теперь надо найти способ отслеживать и обновлять &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Построим ДКА &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt;, который будет хранить эту информацию в своих состояниях. Определим &amp;lt;tex&amp;gt;Q' = Q \times 2^Q&amp;lt;/tex&amp;gt;, то есть каждое состояние &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; {{---}} это пара из одиночного состояния из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; и множества состояний из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;. Функцию перехода &amp;lt;tex&amp;gt;\delta'&amp;lt;/tex&amp;gt; автомата &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; определим так, чтобы если по какой-то строке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; длины &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; в автомате &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; мы перешли в состояние &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то по этой же строке в автомате &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; мы перейдем в состояние &amp;lt;tex&amp;gt;(q_i, S_n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; {{---}} множество состояний из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, определенное выше. Вспомним приведенную выше функцию &amp;lt;tex&amp;gt;prev(S_n) = S_{n+1}&amp;lt;/tex&amp;gt;. С ее помощью мы можем определить функцию перехода следующим образом: &amp;lt;tex&amp;gt;\delta'((q, S), a) = (\delta(q, a), prev(S))&amp;lt;/tex&amp;gt;. Начальное состояние &amp;lt;tex&amp;gt;q_0' = (q_0, S_0) = (q_0, F)&amp;lt;/tex&amp;gt;. Множество терминальных состояний {{---}} &amp;lt;tex&amp;gt;F' = \{ (q, S) \mid q \in S, S \in 2^Q \}&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь по индукции не сложно доказать, что &amp;lt;tex&amp;gt;\delta'(q_0', x) = (\delta(q_0, x), S_n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;|x| = n&amp;lt;/tex&amp;gt;. По определению множества терминальных вершин, автомат &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; допускает строку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; тогда и только тогда, когда &amp;lt;tex&amp;gt;\delta(q_0, x) \in S_n&amp;lt;/tex&amp;gt;. Следовательно, автомат &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; допускает язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;.Таким образом, мы построили ДКА, который допускает язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;. Следовательно, данный язык является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st4&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык. Тогда язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
[[Файл:Enfa_before.jpg|left|thumb|240px|Рис. 1. Разбиение автомата.]]&lt;br /&gt;
[[Файл:Enfa-after.jpg|right|thumb|240px|Рис. 2. Перестроение.]]&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык, то существует допускающий его ДКА &amp;lt;tex&amp;gt;M = \langle \Sigma , Q , q_0 , F , \delta \rangle &amp;lt;/tex&amp;gt;. Построим из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; недетерминированный автомат с &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходами следующим образом: рассмотрим состояние &amp;lt;tex&amp;gt;q \in Q&amp;lt;/tex&amp;gt;, из которого есть переходы в другие состояния (то есть начиная с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; можно построить непустое слово, заканчивающееся в терминальной вершине). Тогда если какое-то слово проходит через это состояние, оно может быть зациклено таким образом, что его суффикс, начинающийся с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, станет префиксом нового слова, а префикс, заканчивающийся в &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; {{---}} суффиксом. Разделим автомат на две части &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt; будет содержать все вершины, из которых достижима &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; {{---}} все вершины, которые достижимы из &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; (см. рис. 1). Заметим, что каждая вершина может содержаться в обеих частях одновременно, такое может случиться, если автомат &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; содержит циклы. Теперь перестроим автомат так, что он будет принимать слова, &amp;quot;зацикленные&amp;quot; вокруг &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, то есть начинающиеся с &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; и после достижения терминальной вершины продолжающиеся с &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt;(см. рис. 2). Для этого стартовой вершиной сделаем &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; и построим от нее часть &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt;. Теперь добавим состояние &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; и соединим с ним все терминальные состояния из &amp;lt;tex&amp;gt;A_2&amp;lt;/tex&amp;gt; с помощью &amp;lt;tex&amp;gt;\varepsilon-&amp;lt;/tex&amp;gt;переходов. Далее построим от &amp;lt;tex&amp;gt;q_0&amp;lt;/tex&amp;gt; часть &amp;lt;tex&amp;gt;A_1&amp;lt;/tex&amp;gt;. Добавим вершину &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt;, эквивалентную &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, и сделаем ее терминальной. Данный автомат принимает слова, зацикленные вокруг выбранной вершины &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. Мы хотим, чтобы автомат принимал слова, зацикленные вокруг любой такой &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. Для этого создадим новую стартовую вершину &amp;lt;tex&amp;gt;q_0'&amp;lt;/tex&amp;gt; и свяжем ее со всеми перестроенными автоматами (зацикленными вокруг всех подходящих &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;), в том числе и с изначальным автоматом. Построенный автомат допускает язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt;, следовательно, данный язык является регулярным.&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Enfa-after.jpg&amp;diff=57830</id>
		<title>Файл:Enfa-after.jpg</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Enfa-after.jpg&amp;diff=57830"/>
				<updated>2016-12-14T18:33:21Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Enfa_before.jpg&amp;diff=57827</id>
		<title>Файл:Enfa before.jpg</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Enfa_before.jpg&amp;diff=57827"/>
				<updated>2016-12-14T18:08:43Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=57740</id>
		<title>Обсуждение участницы:Анна</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=57740"/>
				<updated>2016-12-12T19:32:15Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt; как множество первых половин цепочек языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть множество &amp;lt;tex&amp;gt;\{ w \mid &amp;lt;/tex&amp;gt; существует &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, для которой &amp;lt;tex&amp;gt;wx \in L&amp;lt;/tex&amp;gt;, причем &amp;lt;tex&amp;gt;|w| = |x| \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ \varepsilon, 0010, 011, 010110 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;half(L) = \{ \varepsilon, 00, 010 \}&amp;lt;/tex&amp;gt;. Заметим, что цепочки нечетной длины не влияют на &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt; как множество &amp;lt;tex&amp;gt;\{ w \mid &amp;lt;/tex&amp;gt; цепочку &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; можно представить в виде &amp;lt;tex&amp;gt;w = xy&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;yx \in L \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ 01, 011 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;cycle(L) = \{ 01, 10, 011, 110, 101 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st3&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык. Тогда язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык, то существует ДКА &amp;lt;tex&amp;gt;M = \langle \Sigma , Q , q_0 , F , \delta \rangle &amp;lt;/tex&amp;gt;, допускающий его. Рассмотрим строку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Для того, чтобы проверить, что &amp;lt;tex&amp;gt;x \in half(L)&amp;lt;/tex&amp;gt;, нам надо убедиться, что существует строка &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; такой же длины, что и &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, которая, будучи сконкатенированной с &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, даст строку из &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть если на вход автомату подать &amp;lt;tex&amp;gt;xy&amp;lt;/tex&amp;gt;, то в конце обработки мы окажемся в терминальном состоянии. Предположим, что автомат, закончив обработку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, находится в состоянии &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_0, x) = q_i&amp;lt;/tex&amp;gt;. Мы должны проверить, что существует строка &amp;lt;tex&amp;gt;y, |y| = |x|,&amp;lt;/tex&amp;gt; которая ведет из состояния &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt; до какого-нибудь терминального состояния &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_i, y) \in F&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Предположим, что мы прошли &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин автомата, то есть &amp;lt;tex&amp;gt;|x| = n&amp;lt;/tex&amp;gt;. Обозначим за &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; множество всех состояний, с которых можно попасть в терминальные за &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; шагов. Тогда &amp;lt;tex&amp;gt;q_i \in S_n \Leftrightarrow x \in half(L)&amp;lt;/tex&amp;gt;. Если мы сможем отслеживать &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то сможем определять, верно ли, что &amp;lt;tex&amp;gt;x \in half(L)&amp;lt;/tex&amp;gt;. Заметим, что &amp;lt;tex&amp;gt;S_0 \equiv F&amp;lt;/tex&amp;gt;. Очевидно мы можем построить &amp;lt;tex&amp;gt;S_{n+1}&amp;lt;/tex&amp;gt; зная &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S_{n+1} = prev(S_n) = \{ q \in Q \mid \exists a \in \Sigma, q' \in S_n, \delta(q, a) = q' \}&amp;lt;/tex&amp;gt; {{---}} множество состояний, из которых есть переход в какое-либо состояние из &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; (по единственному символу). Теперь надо найти способ отслеживать и обновлять &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Построим ДКА &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt;, который будет хранить эту информацию в своих состояниях. Определим &amp;lt;tex&amp;gt;Q' = Q \times 2^Q&amp;lt;/tex&amp;gt;, то есть каждое состояние &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; {{---}} это пара из одиночного состояния из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; и множества состояний из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;. Функцию перехода &amp;lt;tex&amp;gt;\delta'&amp;lt;/tex&amp;gt; автомата &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; определим так, чтобы если по какой-то строке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; длины &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; в автомате &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; мы перешли в состояние &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то по этой же строке в автомате &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; мы перейдем в состояние &amp;lt;tex&amp;gt;(q_i, S_n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; {{---}} множество состояний из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, определенное выше. Вспомним приведенную выше функцию &amp;lt;tex&amp;gt;prev(S_n) = S_{n+1}&amp;lt;/tex&amp;gt;. С ее помощью мы можем определить функцию перехода следующим образом: &amp;lt;tex&amp;gt;\delta'((q, S), a) = (\delta(q, a), prev(S))&amp;lt;/tex&amp;gt;. Начальное состояние &amp;lt;tex&amp;gt;q_0' = (q_0, S_0) = (q_0, F)&amp;lt;/tex&amp;gt;. Множество терминальных состояний {{---}} &amp;lt;tex&amp;gt;F' = \{ (q, S) \mid q \in S, S \in 2^Q \}&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь по индукции не сложно доказать, что &amp;lt;tex&amp;gt;\delta'(q_0', x) = (\delta(q_0, x), S_n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;|x| = n&amp;lt;/tex&amp;gt;. По определению множества терминальных вершин, автомат &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; допускает строку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; тогда и только тогда, когда &amp;lt;tex&amp;gt;\delta(q_0, x) \in S_n&amp;lt;/tex&amp;gt;. Следовательно, автомат &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; допускает язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;.Таким образом, мы построили ДКА, который допускает язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;. Следовательно, данный язык является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st4&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык. Тогда язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык, то существует допускающий его ДКА &amp;lt;tex&amp;gt;M = \langle \Sigma , Q , q_0 , F , \delta \rangle &amp;lt;/tex&amp;gt;. &lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=57708</id>
		<title>Обсуждение участницы:Анна</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=57708"/>
				<updated>2016-12-12T17:45:44Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt; как множество первых половин цепочек языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть множество &amp;lt;tex&amp;gt;\{ w \mid &amp;lt;/tex&amp;gt; существует &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, для которой &amp;lt;tex&amp;gt;wx \in L&amp;lt;/tex&amp;gt;, причем &amp;lt;tex&amp;gt;|w| = |x| \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ \varepsilon, 0010, 011, 010110 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;half(L) = \{ \varepsilon, 00, 010 \}&amp;lt;/tex&amp;gt;. Заметим, что цепочки нечетной длины не влияют на &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt; как множество &amp;lt;tex&amp;gt;\{ w \mid &amp;lt;/tex&amp;gt; цепочку &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; можно представить в виде &amp;lt;tex&amp;gt;w = xy&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;yx \in L \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ 01, 011 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;cycle(L) = \{ 01, 10, 011, 110, 101 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st3&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык. Тогда язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык, то существует допускающий его ДКА и порождающее его регулярное выражение. Оба эти факта могут быть использованы для доказательства утверждения. Мы выберем первый.&amp;lt;br&amp;gt;&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;M = \langle \Sigma , Q , q_0 , F , \delta \rangle &amp;lt;/tex&amp;gt; {{---}} ДКА, допускающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Рассмотрим строку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Для того, чтобы проверить, что &amp;lt;tex&amp;gt;x \in half(L)&amp;lt;/tex&amp;gt;, нам надо убедиться, что существует строка &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; такой же длины, что и &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, которая, будучи сконкатенированной с &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, даст строку из &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть если на вход автомату подать &amp;lt;tex&amp;gt;xy&amp;lt;/tex&amp;gt;, то в конце обработки мы окажемся в терминальном состоянии. Предположим, что автомат, закончив обработку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, находится в состоянии &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_0, x) = q_i&amp;lt;/tex&amp;gt;. Мы должны проверить, что существует строка &amp;lt;tex&amp;gt;y, |y| = |x|,&amp;lt;/tex&amp;gt; которая ведет из состояния &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt; до какого-нибудь терминального состояния &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_i, y) \in F&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Предположим, что мы прошли &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин автомата, то есть &amp;lt;tex&amp;gt;|x| = n&amp;lt;/tex&amp;gt;. Обозначим за &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; множество всех состояний, с которых можно попасть в терминальные за &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; шагов. Тогда &amp;lt;tex&amp;gt;q_i \in S_n \Leftrightarrow x \in half(L)&amp;lt;/tex&amp;gt;. Если мы сможем отслеживать &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то сможем определять, верно ли, что &amp;lt;tex&amp;gt;x \in half(L)&amp;lt;/tex&amp;gt;. Заметим, что &amp;lt;tex&amp;gt;S_0 \equiv F&amp;lt;/tex&amp;gt;. Очевидно мы можем построить &amp;lt;tex&amp;gt;S_{n+1}&amp;lt;/tex&amp;gt; зная &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S_{n+1} = prev(S_n) = \{ q \in Q \mid \exists a \in \Sigma, q' \in S_n, \delta(q, a) = q' \}&amp;lt;/tex&amp;gt; {{---}} множество состояний, из которых есть переход в какое-либо состояние из &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; (по единственному символу). Теперь надо найти способ отслеживать и обновлять &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Построим ДКА &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt;, который будет хранить эту информацию в своих состояниях. Определим &amp;lt;tex&amp;gt;Q' = Q \times 2^Q&amp;lt;/tex&amp;gt;, то есть каждое состояние &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; {{---}} это пара из одиночного состояния из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; и множества состояний из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;. Функцию перехода &amp;lt;tex&amp;gt;\delta'&amp;lt;/tex&amp;gt; автомата &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; определим так, чтобы если по какой-то строке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; длины &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; в автомате &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt; мы перешли в состояние &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то по этой же строке в автомате &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; мы перейдем в состояние &amp;lt;tex&amp;gt;(q_i, S_n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; {{---}} множество состояний из &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, определенное выше. Вспомним приведенную выше функцию &amp;lt;tex&amp;gt;prev(S_n) = S_{n+1}&amp;lt;/tex&amp;gt;. С ее помощью мы можем определить функцию перехода следующим образом: &amp;lt;tex&amp;gt;\delta'((q, S), a) = (\delta(q, a), prev(S))&amp;lt;/tex&amp;gt;. Начальное состояние &amp;lt;tex&amp;gt;q_0' = (q_0, S_0) = (q_0, F)&amp;lt;/tex&amp;gt;. Множество терминальных состояний {{---}} &amp;lt;tex&amp;gt;F' = \{ (q, S) \mid q \in S, S \in 2^Q \}&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь по индукции не сложно доказать, что &amp;lt;tex&amp;gt;\delta'(q_0', x) = (\delta(q_0, x), S_n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;|x| = n&amp;lt;/tex&amp;gt;. По определению множества терминальных вершин, автомат &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; допускает строку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; тогда и только тогда, когда &amp;lt;tex&amp;gt;\delta(q_0, x) \in S_n&amp;lt;/tex&amp;gt;. Следовательно, автомат &amp;lt;tex&amp;gt;M'&amp;lt;/tex&amp;gt; допускает язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;.Таким образом, мы построили ДКА, который допускает язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;. Следовательно, данный язык является регулярным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st4&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык. Тогда язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=57644</id>
		<title>Обсуждение участницы:Анна</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BD%D0%BD%D0%B0&amp;diff=57644"/>
				<updated>2016-12-12T11:25:10Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt; как множество первых половин цепочек языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть множество &amp;lt;tex&amp;gt;\{ w \mid &amp;lt;/tex&amp;gt; существует &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, для которой &amp;lt;tex&amp;gt;wx \in L&amp;lt;/tex&amp;gt;, причем &amp;lt;tex&amp;gt;|w| = |x| \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ \varepsilon, 0010, 011, 010110 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;half(L) = \{ \varepsilon, 00, 010 \}&amp;lt;/tex&amp;gt;. Заметим, что цепочки нечетной длины не влияют на &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = Определим &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt; как множество &amp;lt;tex&amp;gt;\{ w \mid &amp;lt;/tex&amp;gt; цепочку &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; можно представить в виде &amp;lt;tex&amp;gt;w = xy&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;yx \in L \}&amp;lt;/tex&amp;gt;. }}&lt;br /&gt;
Например, если &amp;lt;tex&amp;gt;L = \{ 01, 011 \}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;cycle(L) = \{ 01, 10, 011, 110, 101 \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st3&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык. Тогда язык &amp;lt;tex&amp;gt;half(L)&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык, то существует допускающий его ДКА и порождающее его регулярное выражение. Оба эти факта могут быть использованы для доказательства утверждения. Мы выберем первый.&amp;lt;br&amp;gt;&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;M = \langle \Sigma , Q , q_0 , F , \delta \rangle &amp;lt;/tex&amp;gt; {{---}} ДКА, допускающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Рассмотрим строку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Для того, чтобы проверить, что &amp;lt;tex&amp;gt;x \in half(L)&amp;lt;/tex&amp;gt;, нам надо убедиться, что существует строка &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; такой же длины, что и &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, которая, будучи сконкатенированной с &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, даст строку из &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то есть если на вход автомату подать &amp;lt;tex&amp;gt;xy&amp;lt;/tex&amp;gt;, то в конце обработки мы окажемся в терминальном состоянии. Предположим, что автомат, закончив обработку &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, находится в состоянии &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_0, x) = q_i&amp;lt;/tex&amp;gt;. Мы должны проверить, что существует строка &amp;lt;tex&amp;gt;y, |y| = |x|,&amp;lt;/tex&amp;gt;, которая ведет из состояния &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt; до какого-нибудь терминального состояния &amp;lt;tex&amp;gt;M&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\delta(q_i, y) \in F&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Предположим, что мы прошли &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин автомата, то есть &amp;lt;tex&amp;gt;|x| = n&amp;lt;/tex&amp;gt;. Обозначим за &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; множество всех состояний, с которых можно попасть в терминальные за &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; шагов. Тогда &amp;lt;tex&amp;gt;q_i \in S_n \Leftrightarrow x \in half(L)&amp;lt;/tex&amp;gt;. Если мы сможем отслеживать &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;q_i&amp;lt;/tex&amp;gt;, то сможем определять, верно ли, что &amp;lt;tex&amp;gt;x \in half(L)&amp;lt;/tex&amp;gt;. Заметим, что &amp;lt;tex&amp;gt;S_0 \equiv F&amp;lt;/tex&amp;gt;. Очевидно мы можем построить &amp;lt;tex&amp;gt;S_{n+1}&amp;lt;/tex&amp;gt; зная &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S_{n+1} = \{ q_j \mid \delta(q_j, q_k) \in Q, q_k \in S_n \}&amp;lt;/tex&amp;gt; {{---}} множество состояний, из которых есть переход в какое-либо состояние из &amp;lt;tex&amp;gt;S_n&amp;lt;/tex&amp;gt; (по единственному символу).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|id = st4&lt;br /&gt;
|statement =&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} регулярный язык. Тогда язык &amp;lt;tex&amp;gt;cycle(L)&amp;lt;/tex&amp;gt; также регулярен.&lt;br /&gt;
|proof =&lt;br /&gt;
&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Opij1SumTi&amp;diff=55014</id>
		<title>Opij1SumTi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Opij1SumTi&amp;diff=55014"/>
				<updated>2016-06-08T20:04:02Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: /* Асимптотика */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; O \mid p_{i,j} = 1 \mid \sum T_{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; одинаковых станков, которые работают параллельно, и &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ, которые необходимо выполнить в произвольном порядке на всех станках. Любая работа на любом станке выполняется единицу времени. Для каждой работы есть время окончания &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; {{---}} время, до которого она должна быть выполнена. Необходимо минимизировать суммарную [[Классификация_задач#Критерий оптимизации|медлительность]].&lt;br /&gt;
}} &lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Будем полагать, что работы заданы в порядке неубывания их дедлайнов, то есть &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;. &lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть есть работы &amp;lt;tex&amp;gt;1 \ldots n&amp;lt;/tex&amp;gt; с дедлайнами &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;. Тогда существует оптимальное расписание, в котором времена завершения работ идут в том же порядке, то есть &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим две работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из какого-либо оптимального расписания такие, что &amp;lt;tex&amp;gt;C_i &amp;gt; C_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d_i &amp;lt; d_j&amp;lt;/tex&amp;gt;. Поменяем эти работы в расписании местами, то есть &amp;lt;tex&amp;gt;C'_i = C_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C'_j = C_i&amp;lt;/tex&amp;gt;. Если они обе успевали выполниться вовремя, то это свойство сохранится, так как &amp;lt;tex&amp;gt;d_i &amp;lt; d_j&amp;lt;/tex&amp;gt;, значит по-прежнему &amp;lt;tex&amp;gt;T_i = 0&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T_j = 0&amp;lt;/tex&amp;gt;, то есть значение целевой функции мы не ухудшили и расписание осталось оптимальным. Если обе работы не успевали выполниться вовремя, то когда мы поменяем их местами ничего не изменится, то есть значение целевой функции останется прежним, так как мы не меняли значения времен окончаний, а только поменяли их местами. Если работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; успевала выполниться, а  &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; {{---}} нет, то мы снова не ухудшим значение целевой функции. Покажем это. До того, как мы поменяли работы местами, было &amp;lt;tex&amp;gt;T_i + T_j = C_i - d_i&amp;lt;/tex&amp;gt;, так как &amp;lt;tex&amp;gt;T_j = 0&amp;lt;/tex&amp;gt;. После того, как мы поменяли работы местами, &amp;lt;tex&amp;gt;T_i + T_j = C'_i - d_i + C'_j - d_j =  C_j - d_i + C_i - d_j = C_i - d_i + (C_j - d_j)&amp;lt;/tex&amp;gt;. Но так как работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; успевает выполниться до дедлайна, то &amp;lt;tex&amp;gt;C_j - d_j \leqslant 0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
Далее будем рассматривать только оптимальное расписание со свойством &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Всегда существует оптимально расписание такое, что в нем &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для любого &amp;lt;tex&amp;gt;i = 1 \ldots n&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; {{---}} количество станков.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим оптимальное расписание &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;, в котором для любого &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt; выполняется &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt;, но &amp;lt;tex&amp;gt;C_k &amp;gt; m + k - 1&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; максимально среди всех возможных. Для начала покажем, что &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; не меньше &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;. Пусть есть оптимальное расписание, у которого &amp;lt;tex&amp;gt;C_1 &amp;gt; m&amp;lt;/tex&amp;gt;. Это значит, что есть период времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; такой, что первая работа выполняется в момент &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; и не выполняется в &amp;lt;tex&amp;gt;t - 1&amp;lt;/tex&amp;gt;. Поменяем эти периоды времени местами. То есть все работы, которые выполнялись в момент &amp;lt;tex&amp;gt;t - 1&amp;lt;/tex&amp;gt;, будут выполняться на тех же станках, но в момент &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, и наоборот. Значение &amp;lt;tex&amp;gt;C_i&amp;lt;/tex&amp;gt; для каждой работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; не увеличится, так как &amp;lt;tex&amp;gt;C_1&amp;lt;/tex&amp;gt; было минимальным из них, а значит ни одна работа не могла быть закончена раньше периода времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Будем продолжать этот процесс, пока не будет выполнено равенство &amp;lt;tex&amp;gt;C_1 = m&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь пусть &amp;lt;tex&amp;gt;C_k = m + k + t&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;t \geqslant 0&amp;lt;/tex&amp;gt;. Будем называть ''итерацией обработки'' работы обработку на одной машине. Разобьем все работы на три множества:&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; будет содержать все итерации обработки работ &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; {{---}} все итерации, запланированные в расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt; строго после момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; {{---}} итерации обработки работ &amp;lt;tex&amp;gt;i = k + 1 \ldots n&amp;lt;/tex&amp;gt;, которые в &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt; запланированы на время &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; и раньше&lt;br /&gt;
Таким образом, мы имеем три непересекающихся множества, которые вместе с работой &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; покрывают все итерации всех работ.&amp;lt;br&amp;gt;&lt;br /&gt;
Построим новое расписание &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;. Для начала расставим все работы из множества &amp;lt;tex&amp;gt;A \cup B&amp;lt;/tex&amp;gt; так же, как они были запланированы в расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt;, ни одна итерация обработки в множестве &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; не поставлена раньше момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; и к моменту времени &amp;lt;tex&amp;gt;C_k = m + k + t&amp;lt;/tex&amp;gt; выполнено &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ, то это значит, что между моментами времени &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k + m - 1&amp;lt;/tex&amp;gt; на каждой машине есть &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; различных простоев, то есть моментов, когда на ней ничего не обрабатывается. Значит, мы всегда сможем поставить на эти простои итерации обработки работы &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, даже если эти простои пересекаются. Таким образом, &amp;lt;tex&amp;gt;C_k \leqslant m + k - 1&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь назначим машины для операций из множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. До момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; сейчас распланировано ровно &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ, так как по определению работы из множества &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; запланированы на время строго большее &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;. Значит, между моментами времени &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; есть &amp;lt;tex&amp;gt;k + m + t - k = m + t&amp;lt;/tex&amp;gt; различных простоев на каждой машине. Исходя из определения множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; и того, что к моменту &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; распланировано &amp;lt;tex&amp;gt;km&amp;lt;/tex&amp;gt; итераций обработок, приходим к неравенству &amp;lt;tex&amp;gt;|C| \leqslant (k + m + t)m - km = (m + t)m&amp;lt;/tex&amp;gt;. Значит, мы можем распланировать итерации из множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; не позднее момента &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;. Таим образом, мы снова построили расписание для задачи open shop, которое так же является оптимальным, так как для множеств &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; все осталось как в оптимальном расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;, работу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; мы научились выполнять быстрее, а для множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; ответ был не ухудшен. Любая работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, итерации обработки которой принадлежат множеству &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, имела время окончания &amp;lt;tex&amp;gt;C_j \geqslant m + k + t&amp;lt;/tex&amp;gt;. Однако это противоречит тому, что мы выбрали максимальное &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;. &lt;br /&gt;
}}&lt;br /&gt;
Отсортируем работы в порядке неуменьшения дедлайнов. Для текущей работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; вычислим ''лимит'' &amp;lt;tex&amp;gt;T_i&amp;lt;/tex&amp;gt; {{---}} время, до которого закончится обработка данной работы, то есть &amp;lt;tex&amp;gt;1 \leqslant t_1 &amp;lt; t_2 &amp;lt; \ldots &amp;lt; t_m \leqslant T_i &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;t_j&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;j = 1 \ldots m&amp;lt;/tex&amp;gt; {{---}} периоды обработки работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Будем выбирать эти периоды среди моментов времени, в которые выполняется наименьшее число работ.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Определим ''вектор частот'' &amp;lt;tex&amp;gt;h[t]&amp;lt;/tex&amp;gt; {{---}} количество работ во временном интервале &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Работы отсортированы в порядке &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
   '''function''' scheduler():&lt;br /&gt;
      '''int''' &amp;lt;tex&amp;gt;h[m + n - 1]&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''vector&amp;lt;int&amp;gt;''' &amp;lt;tex&amp;gt;s[n]&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''fill'''(&amp;lt;tex&amp;gt;h,\ 0&amp;lt;/tex&amp;gt;)&lt;br /&gt;
      '''fill'''(&amp;lt;tex&amp;gt;s,\ \varnothing&amp;lt;/tex&amp;gt;)  &lt;br /&gt;
      '''for''' &amp;lt;tex&amp;gt;i = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''if''' &amp;lt;tex&amp;gt;d_i &amp;lt; m + i - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
            вычислим &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; {{---}} количество временных интервалов &amp;lt;tex&amp;gt;t = 1 \ldots d_i&amp;lt;/tex&amp;gt;, таких, что &amp;lt;tex&amp;gt;h[t] &amp;lt; m&amp;lt;/tex&amp;gt;&lt;br /&gt;
            '''if''' &amp;lt;tex&amp;gt;z \geqslant m&amp;lt;/tex&amp;gt;&lt;br /&gt;
               &amp;lt;tex&amp;gt;T_i = d_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
            '''else''' &lt;br /&gt;
               &amp;lt;tex&amp;gt;T_i = d_i + m - z&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''else'''&lt;br /&gt;
            &amp;lt;tex&amp;gt;T_i = m + i - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
         вычислим &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; периодов &amp;lt;tex&amp;gt;1 \leqslant t_1 &amp;lt; t_2 &amp;lt; \ldots &amp;lt; t_m \leqslant T_i &amp;lt;/tex&amp;gt; с минимальными значениями &amp;lt;tex&amp;gt;h[t_j]&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''for''' &amp;lt;tex&amp;gt;j = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;&lt;br /&gt;
            &amp;lt;tex&amp;gt;s[i] =  s[i] \cup \{t_j - 1\}&amp;lt;/tex&amp;gt;         &amp;lt;font color=green&amp;gt;// ставим работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; на время &amp;lt;tex&amp;gt;[t_j - 1, t_j]&amp;lt;/tex&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
            &amp;lt;tex&amp;gt;h[t_j] = h[t_j] + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''return''' &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Асимптотика ===&lt;br /&gt;
Алгоритм может работать за &amp;lt;tex&amp;gt;O(nm)&amp;lt;/tex&amp;gt;. Чтобы получить алгоритм с такой сложностью, мы распределяем работы так, чтобы после каждого шага &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; сохранялся инвариант &amp;lt;tex&amp;gt;l_1 \geqslant l_2 \geqslant \ldots \geqslant l_m &amp;lt;/tex&amp;gt; при &amp;lt;tex&amp;gt;l_1 \geqslant T_i&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;l_j&amp;lt;/tex&amp;gt; такое, что на станке &amp;lt;tex&amp;gt;M_j&amp;lt;/tex&amp;gt; все временные промежутки &amp;lt;tex&amp;gt;1 \ldots l_j&amp;lt;/tex&amp;gt; заняты.&lt;br /&gt;
На первом шаге алгоритма &amp;lt;tex&amp;gt; l_1 = l_2 = \ldots = l_m = 0 &amp;lt;/tex&amp;gt;. Предположим, что инвариант сохранился после шага &amp;lt;tex&amp;gt; i - 1 &amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt; T_{i-1} \leqslant T_i &amp;lt;/tex&amp;gt; и, для сохранения инварианта, распределим работу в следующем порядке:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;l_1 + 1 \ldots T_i&amp;lt;/tex&amp;gt; на станке &amp;lt;tex&amp;gt; M_1 &amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;l_2 + 1 \ldots l_1&amp;lt;/tex&amp;gt; на станке &amp;lt;tex&amp;gt; M_2 &amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; \vdots &amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;l_m + 1 \ldots l_{m-1}&amp;lt;/tex&amp;gt; на станке &amp;lt;tex&amp;gt; M_1 &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Таким образом, мы получаем распределение одной работы по &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; станкам для &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ. Итоговая асимптотика {{---}} &amp;lt;tex&amp;gt;O(nm)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=Алгоритм строит оптимальное расписание для задачи &amp;lt;tex&amp;gt; O \mid p_{i,j} = 1 \mid \sum T_{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
|proof= Воспользуемся для доказательства леммой и теоремой из предыдущего пункта. Из них мы знаем, что существует оптимальное расписание, для которого выполняются свойства &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для любого &amp;lt;tex&amp;gt;i = 1 \ldots n&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; {{---}} число станков. Пусть &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; {{---}} оптимальное расписание, которое удовлетворяет свойству, по которому работы &amp;lt;tex&amp;gt;1 \ldots k - 1 &amp;lt;/tex&amp;gt; поставлены в те же временные промежутки, в которых они оказались следуя нашему расписанию &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Более того, предположим, что &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; было выбрано так, что &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; максимально.&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;C_k &amp;gt; T_k&amp;lt;/tex&amp;gt;. С того момента, как работа &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; поставлена в расписании &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; перед &amp;lt;tex&amp;gt;T_k&amp;lt;/tex&amp;gt;, определим временной промежуток &amp;lt;tex&amp;gt;t \leqslant T_k &amp;lt;/tex&amp;gt; в месте, где работа &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; не выполняется в &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt;. Тогда в самом расписании &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; этот промежуток либо так же пустой, либо он занят работой &amp;lt;tex&amp;gt;r &amp;gt; k&amp;lt;/tex&amp;gt;. &lt;br /&gt;
* Если он пустой, мы перемещаем операцию &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, которая была распределена в промежуток &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;, в этот промежуток. &lt;br /&gt;
* Если работа &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; стоит во время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, но не во время &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;, то мы меняем между собой операции работ &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Если работа &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; поставлена во время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;, то либо тут есть пустое место в &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt;, либо там должна быть работа, назовем ее &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;, которая поставлена на время &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt;, но не поставлена в &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Работа &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; точно там есть, потому что &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; поставлены на время &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;, но не поставлены на время &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt;. Если свободный промежуток есть, тогда переставим работу &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; со времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; на время &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt; и работу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; со времени &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Иначе мы можем переместить работу &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; с времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; на время &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; c &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; с &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt; должно уменьшиться как минимум на один, а &amp;lt;tex&amp;gt;C_r&amp;lt;/tex&amp;gt; увеличится не больше, чем на один.&lt;br /&gt;
Если мы продолжим так действовать, мы получим оптимальное расписание &amp;lt;tex&amp;gt;B'&amp;lt;/tex&amp;gt; с &amp;lt;tex&amp;gt;C_k \leqslant T_k&amp;lt;/tex&amp;gt;, в котором работы &amp;lt;tex&amp;gt;1 \ldots k-1&amp;lt;/tex&amp;gt; расположены так же, как в расписании &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;h&amp;lt;/tex&amp;gt; {{---}} вектор частот для части расписания из работ от &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;k - 1&amp;lt;/tex&amp;gt;. Предположим, что &amp;lt;tex&amp;gt;h(t') &amp;lt; h(t)&amp;lt;/tex&amp;gt; и работа &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; выполняется во временной промежуток &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, но не выполняется в &amp;lt;tex&amp;gt;t'&amp;lt;/tex&amp;gt; в расписании &amp;lt;tex&amp;gt;B'&amp;lt;/tex&amp;gt;. Если в &amp;lt;tex&amp;gt;B'&amp;lt;/tex&amp;gt; станок простаивает во время &amp;lt;tex&amp;gt;t'&amp;lt;/tex&amp;gt;, мы можем переместить работу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;t'&amp;lt;/tex&amp;gt;. Иначе работа &amp;lt;tex&amp;gt;r &amp;gt; k&amp;lt;/tex&amp;gt; находится в расписании в промежутке &amp;lt;tex&amp;gt;t'&amp;lt;/tex&amp;gt;, но ее нет в &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Мы можем передвинуть &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;t'&amp;lt;/tex&amp;gt; без увеличения целевой функции, потому что &amp;lt;tex&amp;gt;C_k \leqslant C_r&amp;lt;/tex&amp;gt;. Продолжая действовать таким образом, мы достигнем оптимального расписания, в котором работы &amp;lt;tex&amp;gt;1 \ldots k&amp;lt;/tex&amp;gt; расположены таким же образом, как и в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Мы получили противоречие, так как выбранный &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; оказался не максимальным. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[O2Cmax|&amp;lt;tex&amp;gt;O2 \mid \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opi1sumu|&amp;lt;tex&amp;gt;O \mid p_{ij} = 1 \mid \sum U_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1di|&amp;lt;tex&amp;gt; O \mid p_{i, j} = 1, d_i \mid - &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1sumwu|&amp;lt;tex&amp;gt; O \mid p_{i, j} = 1 \mid - \sum w_{i} U_{i}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* Peter Brucker «Scheduling Algorithms», fifth edition, Springer {{---}} с. 171-174 ISBN 978-3-540-69515-8&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Opij1SumTi&amp;diff=55013</id>
		<title>Opij1SumTi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Opij1SumTi&amp;diff=55013"/>
				<updated>2016-06-08T20:00:32Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: /* Доказательство корректности */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; O \mid p_{i,j} = 1 \mid \sum T_{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; одинаковых станков, которые работают параллельно, и &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ, которые необходимо выполнить в произвольном порядке на всех станках. Любая работа на любом станке выполняется единицу времени. Для каждой работы есть время окончания &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; {{---}} время, до которого она должна быть выполнена. Необходимо минимизировать суммарную [[Классификация_задач#Критерий оптимизации|медлительность]].&lt;br /&gt;
}} &lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Будем полагать, что работы заданы в порядке неубывания их дедлайнов, то есть &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;. &lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть есть работы &amp;lt;tex&amp;gt;1 \ldots n&amp;lt;/tex&amp;gt; с дедлайнами &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;. Тогда существует оптимальное расписание, в котором времена завершения работ идут в том же порядке, то есть &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим две работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из какого-либо оптимального расписания такие, что &amp;lt;tex&amp;gt;C_i &amp;gt; C_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d_i &amp;lt; d_j&amp;lt;/tex&amp;gt;. Поменяем эти работы в расписании местами, то есть &amp;lt;tex&amp;gt;C'_i = C_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C'_j = C_i&amp;lt;/tex&amp;gt;. Если они обе успевали выполниться вовремя, то это свойство сохранится, так как &amp;lt;tex&amp;gt;d_i &amp;lt; d_j&amp;lt;/tex&amp;gt;, значит по-прежнему &amp;lt;tex&amp;gt;T_i = 0&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T_j = 0&amp;lt;/tex&amp;gt;, то есть значение целевой функции мы не ухудшили и расписание осталось оптимальным. Если обе работы не успевали выполниться вовремя, то когда мы поменяем их местами ничего не изменится, то есть значение целевой функции останется прежним, так как мы не меняли значения времен окончаний, а только поменяли их местами. Если работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; успевала выполниться, а  &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; {{---}} нет, то мы снова не ухудшим значение целевой функции. Покажем это. До того, как мы поменяли работы местами, было &amp;lt;tex&amp;gt;T_i + T_j = C_i - d_i&amp;lt;/tex&amp;gt;, так как &amp;lt;tex&amp;gt;T_j = 0&amp;lt;/tex&amp;gt;. После того, как мы поменяли работы местами, &amp;lt;tex&amp;gt;T_i + T_j = C'_i - d_i + C'_j - d_j =  C_j - d_i + C_i - d_j = C_i - d_i + (C_j - d_j)&amp;lt;/tex&amp;gt;. Но так как работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; успевает выполниться до дедлайна, то &amp;lt;tex&amp;gt;C_j - d_j \leqslant 0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
Далее будем рассматривать только оптимальное расписание со свойством &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Всегда существует оптимально расписание такое, что в нем &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для любого &amp;lt;tex&amp;gt;i = 1 \ldots n&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; {{---}} количество станков.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим оптимальное расписание &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;, в котором для любого &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt; выполняется &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt;, но &amp;lt;tex&amp;gt;C_k &amp;gt; m + k - 1&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; максимально среди всех возможных. Для начала покажем, что &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; не меньше &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;. Пусть есть оптимальное расписание, у которого &amp;lt;tex&amp;gt;C_1 &amp;gt; m&amp;lt;/tex&amp;gt;. Это значит, что есть период времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; такой, что первая работа выполняется в момент &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; и не выполняется в &amp;lt;tex&amp;gt;t - 1&amp;lt;/tex&amp;gt;. Поменяем эти периоды времени местами. То есть все работы, которые выполнялись в момент &amp;lt;tex&amp;gt;t - 1&amp;lt;/tex&amp;gt;, будут выполняться на тех же станках, но в момент &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, и наоборот. Значение &amp;lt;tex&amp;gt;C_i&amp;lt;/tex&amp;gt; для каждой работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; не увеличится, так как &amp;lt;tex&amp;gt;C_1&amp;lt;/tex&amp;gt; было минимальным из них, а значит ни одна работа не могла быть закончена раньше периода времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Будем продолжать этот процесс, пока не будет выполнено равенство &amp;lt;tex&amp;gt;C_1 = m&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь пусть &amp;lt;tex&amp;gt;C_k = m + k + t&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;t \geqslant 0&amp;lt;/tex&amp;gt;. Будем называть ''итерацией обработки'' работы обработку на одной машине. Разобьем все работы на три множества:&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; будет содержать все итерации обработки работ &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; {{---}} все итерации, запланированные в расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt; строго после момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; {{---}} итерации обработки работ &amp;lt;tex&amp;gt;i = k + 1 \ldots n&amp;lt;/tex&amp;gt;, которые в &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt; запланированы на время &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; и раньше&lt;br /&gt;
Таким образом, мы имеем три непересекающихся множества, которые вместе с работой &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; покрывают все итерации всех работ.&amp;lt;br&amp;gt;&lt;br /&gt;
Построим новое расписание &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;. Для начала расставим все работы из множества &amp;lt;tex&amp;gt;A \cup B&amp;lt;/tex&amp;gt; так же, как они были запланированы в расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt;, ни одна итерация обработки в множестве &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; не поставлена раньше момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; и к моменту времени &amp;lt;tex&amp;gt;C_k = m + k + t&amp;lt;/tex&amp;gt; выполнено &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ, то это значит, что между моментами времени &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k + m - 1&amp;lt;/tex&amp;gt; на каждой машине есть &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; различных простоев, то есть моментов, когда на ней ничего не обрабатывается. Значит, мы всегда сможем поставить на эти простои итерации обработки работы &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, даже если эти простои пересекаются. Таким образом, &amp;lt;tex&amp;gt;C_k \leqslant m + k - 1&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь назначим машины для операций из множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. До момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; сейчас распланировано ровно &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ, так как по определению работы из множества &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; запланированы на время строго большее &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;. Значит, между моментами времени &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; есть &amp;lt;tex&amp;gt;k + m + t - k = m + t&amp;lt;/tex&amp;gt; различных простоев на каждой машине. Исходя из определения множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; и того, что к моменту &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; распланировано &amp;lt;tex&amp;gt;km&amp;lt;/tex&amp;gt; итераций обработок, приходим к неравенству &amp;lt;tex&amp;gt;|C| \leqslant (k + m + t)m - km = (m + t)m&amp;lt;/tex&amp;gt;. Значит, мы можем распланировать итерации из множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; не позднее момента &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;. Таим образом, мы снова построили расписание для задачи open shop, которое так же является оптимальным, так как для множеств &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; все осталось как в оптимальном расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;, работу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; мы научились выполнять быстрее, а для множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; ответ был не ухудшен. Любая работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, итерации обработки которой принадлежат множеству &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, имела время окончания &amp;lt;tex&amp;gt;C_j \geqslant m + k + t&amp;lt;/tex&amp;gt;. Однако это противоречит тому, что мы выбрали максимальное &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;. &lt;br /&gt;
}}&lt;br /&gt;
Отсортируем работы в порядке неуменьшения дедлайнов. Для текущей работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; вычислим ''лимит'' &amp;lt;tex&amp;gt;T_i&amp;lt;/tex&amp;gt; {{---}} время, до которого закончится обработка данной работы, то есть &amp;lt;tex&amp;gt;1 \leqslant t_1 &amp;lt; t_2 &amp;lt; \ldots &amp;lt; t_m \leqslant T_i &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;t_j&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;j = 1 \ldots m&amp;lt;/tex&amp;gt; {{---}} периоды обработки работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Будем выбирать эти периоды среди моментов времени, в которые выполняется наименьшее число работ.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Определим ''вектор частот'' &amp;lt;tex&amp;gt;h[t]&amp;lt;/tex&amp;gt; {{---}} количество работ во временном интервале &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Работы отсортированы в порядке &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
   '''function''' scheduler():&lt;br /&gt;
      '''int''' &amp;lt;tex&amp;gt;h[m + n - 1]&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''vector&amp;lt;int&amp;gt;''' &amp;lt;tex&amp;gt;s[n]&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''fill'''(&amp;lt;tex&amp;gt;h,\ 0&amp;lt;/tex&amp;gt;)&lt;br /&gt;
      '''fill'''(&amp;lt;tex&amp;gt;s,\ \varnothing&amp;lt;/tex&amp;gt;)  &lt;br /&gt;
      '''for''' &amp;lt;tex&amp;gt;i = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''if''' &amp;lt;tex&amp;gt;d_i &amp;lt; m + i - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
            вычислим &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; {{---}} количество временных интервалов &amp;lt;tex&amp;gt;t = 1 \ldots d_i&amp;lt;/tex&amp;gt;, таких, что &amp;lt;tex&amp;gt;h[t] &amp;lt; m&amp;lt;/tex&amp;gt;&lt;br /&gt;
            '''if''' &amp;lt;tex&amp;gt;z \geqslant m&amp;lt;/tex&amp;gt;&lt;br /&gt;
               &amp;lt;tex&amp;gt;T_i = d_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
            '''else''' &lt;br /&gt;
               &amp;lt;tex&amp;gt;T_i = d_i + m - z&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''else'''&lt;br /&gt;
            &amp;lt;tex&amp;gt;T_i = m + i - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
         вычислим &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; периодов &amp;lt;tex&amp;gt;1 \leqslant t_1 &amp;lt; t_2 &amp;lt; \ldots &amp;lt; t_m \leqslant T_i &amp;lt;/tex&amp;gt; с минимальными значениями &amp;lt;tex&amp;gt;h[t_j]&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''for''' &amp;lt;tex&amp;gt;j = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;&lt;br /&gt;
            &amp;lt;tex&amp;gt;s[i] =  s[i] \cup \{t_j - 1\}&amp;lt;/tex&amp;gt;         &amp;lt;font color=green&amp;gt;// ставим работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; на время &amp;lt;tex&amp;gt;[t_j - 1, t_j]&amp;lt;/tex&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
            &amp;lt;tex&amp;gt;h[t_j] = h[t_j] + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''return''' &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Асимптотика ===&lt;br /&gt;
Алгоритм может работать за &amp;lt;tex&amp;gt;O(nm)&amp;lt;/tex&amp;gt;. Чтобы получить алгоритм с такой сложностью, мы распределяем работы так, чтобы после каждого шага &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; сохранялся инвариант &amp;lt;tex&amp;gt;l_1 \geqslant l_2 \geqslant \ldots \geqslant l_m &amp;lt;/tex&amp;gt; при &amp;lt;tex&amp;gt;l_1 \geqslant T_i&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;l_j&amp;lt;/tex&amp;gt; это такое число, что на станке &amp;lt;tex&amp;gt;M_j&amp;lt;/tex&amp;gt; все временные промежутки &amp;lt;tex&amp;gt;1 \ldots l_j&amp;lt;/tex&amp;gt; заняты.&lt;br /&gt;
На первом шаге алгоритма &amp;lt;tex&amp;gt; l_1 = l_2 = \ldots = l_m = 0 &amp;lt;/tex&amp;gt;. Предположим, что инвариант сохранился после шага &amp;lt;tex&amp;gt; i - 1 &amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt; T_{i-1} \leqslant T_i &amp;lt;/tex&amp;gt; и, для сохранения инварианта, распределим работу в следующем порядке:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;l_1 + 1 \ldots T_i&amp;lt;/tex&amp;gt; на станке &amp;lt;tex&amp;gt; M_1 &amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;l_2 + 1 \ldots l_1&amp;lt;/tex&amp;gt; на станке &amp;lt;tex&amp;gt; M_2 &amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; \vdots &amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;l_m + 1 \ldots l_{m-1}&amp;lt;/tex&amp;gt; на станке &amp;lt;tex&amp;gt; M_1 &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Таким образом, мы получаем распределение одной работы по &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; станкам для &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ. Итоговая асимптотика {{---}} &amp;lt;tex&amp;gt;O(nm)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=Алгоритм строит оптимальное расписание для задачи &amp;lt;tex&amp;gt; O \mid p_{i,j} = 1 \mid \sum T_{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
|proof= Воспользуемся для доказательства леммой и теоремой из предыдущего пункта. Из них мы знаем, что существует оптимальное расписание, для которого выполняются свойства &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для любого &amp;lt;tex&amp;gt;i = 1 \ldots n&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; {{---}} число станков. Пусть &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; {{---}} оптимальное расписание, которое удовлетворяет свойству, по которому работы &amp;lt;tex&amp;gt;1 \ldots k - 1 &amp;lt;/tex&amp;gt; поставлены в те же временные промежутки, в которых они оказались следуя нашему расписанию &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Более того, предположим, что &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; было выбрано так, что &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; максимально.&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;C_k &amp;gt; T_k&amp;lt;/tex&amp;gt;. С того момента, как работа &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; поставлена в расписании &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; перед &amp;lt;tex&amp;gt;T_k&amp;lt;/tex&amp;gt;, определим временной промежуток &amp;lt;tex&amp;gt;t \leqslant T_k &amp;lt;/tex&amp;gt; в месте, где работа &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; не выполняется в &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt;. Тогда в самом расписании &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; этот промежуток либо так же пустой, либо он занят работой &amp;lt;tex&amp;gt;r &amp;gt; k&amp;lt;/tex&amp;gt;. &lt;br /&gt;
* Если он пустой, мы перемещаем операцию &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, которая была распределена в промежуток &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;, в этот промежуток. &lt;br /&gt;
* Если работа &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; стоит во время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, но не во время &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;, то мы меняем между собой операции работ &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Если работа &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; поставлена во время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;, то либо тут есть пустое место в &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt;, либо там должна быть работа, назовем ее &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;, которая поставлена на время &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt;, но не поставлена в &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Работа &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; точно там есть, потому что &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; поставлены на время &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;, но не поставлены на время &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt;. Если свободный промежуток есть, тогда переставим работу &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; со времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; на время &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt; и работу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; со времени &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Иначе мы можем переместить работу &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; с времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; на время &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; c &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; с &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt; должно уменьшиться как минимум на один, а &amp;lt;tex&amp;gt;C_r&amp;lt;/tex&amp;gt; увеличится не больше, чем на один.&lt;br /&gt;
Если мы продолжим так действовать, мы получим оптимальное расписание &amp;lt;tex&amp;gt;B'&amp;lt;/tex&amp;gt; с &amp;lt;tex&amp;gt;C_k \leqslant T_k&amp;lt;/tex&amp;gt;, в котором работы &amp;lt;tex&amp;gt;1 \ldots k-1&amp;lt;/tex&amp;gt; расположены так же, как в расписании &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;h&amp;lt;/tex&amp;gt; {{---}} вектор частот для части расписания из работ от &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;k - 1&amp;lt;/tex&amp;gt;. Предположим, что &amp;lt;tex&amp;gt;h(t') &amp;lt; h(t)&amp;lt;/tex&amp;gt; и работа &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; выполняется во временной промежуток &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, но не выполняется в &amp;lt;tex&amp;gt;t'&amp;lt;/tex&amp;gt; в расписании &amp;lt;tex&amp;gt;B'&amp;lt;/tex&amp;gt;. Если в &amp;lt;tex&amp;gt;B'&amp;lt;/tex&amp;gt; станок простаивает во время &amp;lt;tex&amp;gt;t'&amp;lt;/tex&amp;gt;, мы можем переместить работу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;t'&amp;lt;/tex&amp;gt;. Иначе работа &amp;lt;tex&amp;gt;r &amp;gt; k&amp;lt;/tex&amp;gt; находится в расписании в промежутке &amp;lt;tex&amp;gt;t'&amp;lt;/tex&amp;gt;, но ее нет в &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Мы можем передвинуть &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;t'&amp;lt;/tex&amp;gt; без увеличения целевой функции, потому что &amp;lt;tex&amp;gt;C_k \leqslant C_r&amp;lt;/tex&amp;gt;. Продолжая действовать таким образом, мы достигнем оптимального расписания, в котором работы &amp;lt;tex&amp;gt;1 \ldots k&amp;lt;/tex&amp;gt; расположены таким же образом, как и в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Мы получили противоречие, так как выбранный &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; оказался не максимальным. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[O2Cmax|&amp;lt;tex&amp;gt;O2 \mid \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opi1sumu|&amp;lt;tex&amp;gt;O \mid p_{ij} = 1 \mid \sum U_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1di|&amp;lt;tex&amp;gt; O \mid p_{i, j} = 1, d_i \mid - &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1sumwu|&amp;lt;tex&amp;gt; O \mid p_{i, j} = 1 \mid - \sum w_{i} U_{i}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* Peter Brucker «Scheduling Algorithms», fifth edition, Springer {{---}} с. 171-174 ISBN 978-3-540-69515-8&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Opij1SumTi&amp;diff=55005</id>
		<title>Opij1SumTi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Opij1SumTi&amp;diff=55005"/>
				<updated>2016-06-08T19:48:17Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: /* Доказательство корректности */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; O \mid p_{i,j} = 1 \mid \sum T_{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; одинаковых станков, которые работают параллельно, и &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ, которые необходимо выполнить в произвольном порядке на всех станках. Любая работа на любом станке выполняется единицу времени. Для каждой работы есть время окончания &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; {{---}} время, до которого она должна быть выполнена. Необходимо минимизировать суммарную [[Классификация_задач#Критерий оптимизации|медлительность]].&lt;br /&gt;
}} &lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Будем полагать, что работы заданы в порядке неубывания их дедлайнов, то есть &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;. &lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть есть работы &amp;lt;tex&amp;gt;1 \ldots n&amp;lt;/tex&amp;gt; с дедлайнами &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;. Тогда существует оптимальное расписание, в котором времена завершения работ идут в том же порядке, то есть &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим две работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из какого-либо оптимального расписания такие, что &amp;lt;tex&amp;gt;C_i &amp;gt; C_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d_i &amp;lt; d_j&amp;lt;/tex&amp;gt;. Поменяем эти работы в расписании местами, то есть &amp;lt;tex&amp;gt;C'_i = C_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C'_j = C_i&amp;lt;/tex&amp;gt;. Если они обе успевали выполниться вовремя, то это свойство сохранится, так как &amp;lt;tex&amp;gt;d_i &amp;lt; d_j&amp;lt;/tex&amp;gt;, значит по-прежнему &amp;lt;tex&amp;gt;T_i = 0&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T_j = 0&amp;lt;/tex&amp;gt;, то есть значение целевой функции мы не ухудшили и расписание осталось оптимальным. Если обе работы не успевали выполниться вовремя, то когда мы поменяем их местами ничего не изменится, то есть значение целевой функции останется прежним, так как мы не меняли значения времен окончаний, а только поменяли их местами. Если работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; успевала выполниться, а  &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; {{---}} нет, то мы снова не ухудшим значение целевой функции. Покажем это. До того, как мы поменяли работы местами, было &amp;lt;tex&amp;gt;T_i + T_j = C_i - d_i&amp;lt;/tex&amp;gt;, так как &amp;lt;tex&amp;gt;T_j = 0&amp;lt;/tex&amp;gt;. После того, как мы поменяли работы местами, &amp;lt;tex&amp;gt;T_i + T_j = C'_i - d_i + C'_j - d_j =  C_j - d_i + C_i - d_j = C_i - d_i + (C_j - d_j)&amp;lt;/tex&amp;gt;. Но так как работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; успевает выполниться до дедлайна, то &amp;lt;tex&amp;gt;C_j - d_j \leqslant 0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
Далее будем рассматривать только оптимальное расписание со свойством &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Всегда существует оптимально расписание такое, что в нем &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для любого &amp;lt;tex&amp;gt;i = 1 \ldots n&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; {{---}} количество станков.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим оптимальное расписание &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;, в котором для любого &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt; выполняется &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt;, но &amp;lt;tex&amp;gt;C_k &amp;gt; m + k - 1&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; максимально среди всех возможных. Для начала покажем, что &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; не меньше &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;. Пусть есть оптимальное расписание, у которого &amp;lt;tex&amp;gt;C_1 &amp;gt; m&amp;lt;/tex&amp;gt;. Это значит, что есть период времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; такой, что первая работа выполняется в момент &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; и не выполняется в &amp;lt;tex&amp;gt;t - 1&amp;lt;/tex&amp;gt;. Поменяем эти периоды времени местами. То есть все работы, которые выполнялись в момент &amp;lt;tex&amp;gt;t - 1&amp;lt;/tex&amp;gt;, будут выполняться на тех же станках, но в момент &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, и наоборот. Значение &amp;lt;tex&amp;gt;C_i&amp;lt;/tex&amp;gt; для каждой работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; не увеличится, так как &amp;lt;tex&amp;gt;C_1&amp;lt;/tex&amp;gt; было минимальным из них, а значит ни одна работа не могла быть закончена раньше периода времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Будем продолжать этот процесс, пока не будет выполнено равенство &amp;lt;tex&amp;gt;C_1 = m&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь пусть &amp;lt;tex&amp;gt;C_k = m + k + t&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;t \geqslant 0&amp;lt;/tex&amp;gt;. Будем называть ''итерацией обработки'' работы обработку на одной машине. Разобьем все работы на три множества:&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; будет содержать все итерации обработки работ &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; {{---}} все итерации, запланированные в расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt; строго после момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; {{---}} итерации обработки работ &amp;lt;tex&amp;gt;i = k + 1 \ldots n&amp;lt;/tex&amp;gt;, которые в &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt; запланированы на время &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; и раньше&lt;br /&gt;
Таким образом, мы имеем три непересекающихся множества, которые вместе с работой &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; покрывают все итерации всех работ.&amp;lt;br&amp;gt;&lt;br /&gt;
Построим новое расписание &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;. Для начала расставим все работы из множества &amp;lt;tex&amp;gt;A \cup B&amp;lt;/tex&amp;gt; так же, как они были запланированы в расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt;, ни одна итерация обработки в множестве &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; не поставлена раньше момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; и к моменту времени &amp;lt;tex&amp;gt;C_k = m + k + t&amp;lt;/tex&amp;gt; выполнено &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ, то это значит, что между моментами времени &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k + m - 1&amp;lt;/tex&amp;gt; на каждой машине есть &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; различных простоев, то есть моментов, когда на ней ничего не обрабатывается. Значит, мы всегда сможем поставить на эти простои итерации обработки работы &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, даже если эти простои пересекаются. Таким образом, &amp;lt;tex&amp;gt;C_k \leqslant m + k - 1&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь назначим машины для операций из множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. До момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; сейчас распланировано ровно &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ, так как по определению работы из множества &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; запланированы на время строго большее &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;. Значит, между моментами времени &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; есть &amp;lt;tex&amp;gt;k + m + t - k = m + t&amp;lt;/tex&amp;gt; различных простоев на каждой машине. Исходя из определения множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; и того, что к моменту &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; распланировано &amp;lt;tex&amp;gt;km&amp;lt;/tex&amp;gt; итераций обработок, приходим к неравенству &amp;lt;tex&amp;gt;|C| \leqslant (k + m + t)m - km = (m + t)m&amp;lt;/tex&amp;gt;. Значит, мы можем распланировать итерации из множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; не позднее момента &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;. Таим образом, мы снова построили расписание для задачи open shop, которое так же является оптимальным, так как для множеств &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; все осталось как в оптимальном расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;, работу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; мы научились выполнять быстрее, а для множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; ответ был не ухудшен. Любая работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, итерации обработки которой принадлежат множеству &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, имела время окончания &amp;lt;tex&amp;gt;C_j \geqslant m + k + t&amp;lt;/tex&amp;gt;. Однако это противоречит тому, что мы выбрали максимальное &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;. &lt;br /&gt;
}}&lt;br /&gt;
Отсортируем работы в порядке неуменьшения дедлайнов. Для текущей работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; вычислим ''лимит'' &amp;lt;tex&amp;gt;T_i&amp;lt;/tex&amp;gt; {{---}} время, до которого закончится обработка данной работы, то есть &amp;lt;tex&amp;gt;1 \leqslant t_1 &amp;lt; t_2 &amp;lt; \ldots &amp;lt; t_m \leqslant T_i &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;t_j&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;j = 1 \ldots m&amp;lt;/tex&amp;gt; {{---}} периоды обработки работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Будем выбирать эти периоды среди моментов времени, в которые выполняется наименьшее число работ.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Определим ''вектор частот'' &amp;lt;tex&amp;gt;h[t]&amp;lt;/tex&amp;gt; {{---}} количество работ во временном интервале &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Работы отсортированы в порядке &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
   '''function''' scheduler():&lt;br /&gt;
      '''int''' &amp;lt;tex&amp;gt;h[m + n - 1]&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''vector&amp;lt;int&amp;gt;''' &amp;lt;tex&amp;gt;s[n]&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''fill'''(&amp;lt;tex&amp;gt;h,\ 0&amp;lt;/tex&amp;gt;)&lt;br /&gt;
      '''fill'''(&amp;lt;tex&amp;gt;s,\ \varnothing&amp;lt;/tex&amp;gt;)  &lt;br /&gt;
      '''for''' &amp;lt;tex&amp;gt;i = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''if''' &amp;lt;tex&amp;gt;d_i &amp;lt; m + i - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
            вычислим &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; {{---}} количество временных интервалов &amp;lt;tex&amp;gt;t = 1 \ldots d_i&amp;lt;/tex&amp;gt;, таких, что &amp;lt;tex&amp;gt;h[t] &amp;lt; m&amp;lt;/tex&amp;gt;&lt;br /&gt;
            '''if''' &amp;lt;tex&amp;gt;z \geqslant m&amp;lt;/tex&amp;gt;&lt;br /&gt;
               &amp;lt;tex&amp;gt;T_i = d_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
            '''else''' &lt;br /&gt;
               &amp;lt;tex&amp;gt;T_i = d_i + m - z&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''else'''&lt;br /&gt;
            &amp;lt;tex&amp;gt;T_i = m + i - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
         вычислим &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; периодов &amp;lt;tex&amp;gt;1 \leqslant t_1 &amp;lt; t_2 &amp;lt; \ldots &amp;lt; t_m \leqslant T_i &amp;lt;/tex&amp;gt; с минимальными значениями &amp;lt;tex&amp;gt;h[t_j]&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''for''' &amp;lt;tex&amp;gt;j = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;&lt;br /&gt;
            &amp;lt;tex&amp;gt;s[i] =  s[i] \cup \{t_j - 1\}&amp;lt;/tex&amp;gt;         &amp;lt;font color=green&amp;gt;// ставим работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; на время &amp;lt;tex&amp;gt;[t_j - 1, t_j]&amp;lt;/tex&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
            &amp;lt;tex&amp;gt;h[t_j] = h[t_j] + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''return''' &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Асимптотика ===&lt;br /&gt;
Алгоритм может работать за &amp;lt;tex&amp;gt;O(nm)&amp;lt;/tex&amp;gt;. Чтобы получить алгоритм с такой сложностью, мы распределяем работы так, чтобы после каждого шага &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; сохранялся инвариант &amp;lt;tex&amp;gt;l_1 \geqslant l_2 \geqslant \ldots \geqslant l_m &amp;lt;/tex&amp;gt; при &amp;lt;tex&amp;gt;l_1 \geqslant T_i&amp;lt;/tex&amp;gt;, такой, что на станке &amp;lt;tex&amp;gt;M_j&amp;lt;/tex&amp;gt; все промежутки &amp;lt;tex&amp;gt;1 \ldots l_j&amp;lt;/tex&amp;gt; заняты.&lt;br /&gt;
На первом шаге алгоритма &amp;lt;tex&amp;gt; l_1 = l_2 = \ldots = l_m = 0 &amp;lt;/tex&amp;gt;. Предположим, что инвариант сохранился после шага &amp;lt;tex&amp;gt; i - 1 &amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt; T_{i-1} \leqslant T_i &amp;lt;/tex&amp;gt; и, для сохранения инварианта, распределим работу в следующем порядке:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;l_1 + 1 \ldots T_i&amp;lt;/tex&amp;gt; на станке &amp;lt;tex&amp;gt; M_1 &amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;l_2 + 1 \ldots l_1&amp;lt;/tex&amp;gt; на станке &amp;lt;tex&amp;gt; M_2 &amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; \vdots &amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;l_m + 1 \ldots l_{m-1}&amp;lt;/tex&amp;gt; на станке &amp;lt;tex&amp;gt; M_1 &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Таким образом, мы получаем распределение одной работы по &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; станкам для &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ. Итоговая асимптотика {{---}} &amp;lt;tex&amp;gt;O(nm)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=Алгоритм строит оптимальное расписание для задачи &amp;lt;tex&amp;gt; O \mid p_{i,j} = 1 \mid \sum T_{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
|proof= Воспользуемся для доказательства леммой и теоремой, которые были доказаны выше. Из них мы знаем, что существует оптимальное расписание, для которого выполняются свойства &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для любого &amp;lt;tex&amp;gt;i = 1 \ldots n&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; {{---}} число станков. Пусть &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; {{---}} оптимальное расписание, которое удовлетворяет свойству, по которому работы &amp;lt;tex&amp;gt;1 \ldots k - 1 &amp;lt;/tex&amp;gt; поставлены в те же временные промежутки, в которых они оказались следуя нашему расписанию &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Более того, предположим, что &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; было выбрано так, что &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; максимально.&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;C_k &amp;gt; T_k&amp;lt;/tex&amp;gt;. С того момента, как работа &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; поставлена в расписании &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; перед &amp;lt;tex&amp;gt;T_k&amp;lt;/tex&amp;gt;, определим временной промежуток &amp;lt;tex&amp;gt;t \leqslant T_k &amp;lt;/tex&amp;gt; в месте, где работа &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; не выполняется в &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt;. Тогда в самом расписании &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; этот промежуток либо так же пустой, либо он занят работой &amp;lt;tex&amp;gt;r &amp;gt; k&amp;lt;/tex&amp;gt;. &lt;br /&gt;
* Если он пустой, мы перемещаем операцию &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, которая была распределена в промежуток &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;, в этот промежуток. &lt;br /&gt;
* Если работа &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; стоит во время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, но не во время &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;, то мы меняем между собой операции работ &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Если работа &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; поставлена во время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;, то либо тут есть пустое место в &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt;, либо там должна быть работа, назовем ее &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;, которая поставлена на время &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt;, но не поставлена в &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Работа &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; точно там есть, потому что &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; поставлены на время &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;, но не поставлены на время &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt;. Если свободный промежуток есть, тогда переставим работу &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; со времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; на время &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt; и работу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; со времени &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Иначе мы можем переместить работу &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; с времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; на время &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; c &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; с &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt; должно уменьшиться как минимум на один, а &amp;lt;tex&amp;gt;C_r&amp;lt;/tex&amp;gt; увеличится не больше, чем на один.&lt;br /&gt;
Если мы продолжим так действовать, мы получим оптимальное расписание &amp;lt;tex&amp;gt;B'&amp;lt;/tex&amp;gt; с &amp;lt;tex&amp;gt;C_k \leqslant T_k&amp;lt;/tex&amp;gt;, в котором работы &amp;lt;tex&amp;gt;1 \ldots k-1&amp;lt;/tex&amp;gt; расположены так же, как в расписании &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;h&amp;lt;/tex&amp;gt; {{---}} вектор частот для части расписания из работ от &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;k - 1&amp;lt;/tex&amp;gt;. Предположим, что &amp;lt;tex&amp;gt;h(t') &amp;lt; h(t)&amp;lt;/tex&amp;gt; и работа &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; выполняется во временной промежуток &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, но не выполняется в &amp;lt;tex&amp;gt;t'&amp;lt;/tex&amp;gt; в расписании &amp;lt;tex&amp;gt;B'&amp;lt;/tex&amp;gt;. Если в &amp;lt;tex&amp;gt;B'&amp;lt;/tex&amp;gt; станок простаивает во время &amp;lt;tex&amp;gt;t'&amp;lt;/tex&amp;gt;, мы можем переместить работу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;t'&amp;lt;/tex&amp;gt;. Иначе работа &amp;lt;tex&amp;gt;r &amp;gt; k&amp;lt;/tex&amp;gt; находится в расписании в промежутке &amp;lt;tex&amp;gt;t'&amp;lt;/tex&amp;gt;, но ее нет в &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Мы можем передвинуть &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;t'&amp;lt;/tex&amp;gt; без увеличения целевой функции, потому что &amp;lt;tex&amp;gt;C_k \leqslant C_r&amp;lt;/tex&amp;gt;. Продолжая действовать таким образом, мы достигнем оптимального расписания, в котором работы &amp;lt;tex&amp;gt;1 \ldots k&amp;lt;/tex&amp;gt; расположены таким же образом, как и в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Мы получили противоречие, так как выбранный &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; оказался не максимальным. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[O2Cmax|&amp;lt;tex&amp;gt;O2 \mid \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opi1sumu|&amp;lt;tex&amp;gt;O \mid p_{ij} = 1 \mid \sum U_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1di|&amp;lt;tex&amp;gt; O \mid p_{i, j} = 1, d_i \mid - &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1sumwu|&amp;lt;tex&amp;gt; O \mid p_{i, j} = 1 \mid - \sum w_{i} U_{i}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* Peter Brucker «Scheduling Algorithms», fifth edition, Springer {{---}} с. 171-174 ISBN 978-3-540-69515-8&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Opij1SumTi&amp;diff=55004</id>
		<title>Opij1SumTi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Opij1SumTi&amp;diff=55004"/>
				<updated>2016-06-08T19:43:37Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: /* Доказательство корректности */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; O \mid p_{i,j} = 1 \mid \sum T_{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; одинаковых станков, которые работают параллельно, и &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ, которые необходимо выполнить в произвольном порядке на всех станках. Любая работа на любом станке выполняется единицу времени. Для каждой работы есть время окончания &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; {{---}} время, до которого она должна быть выполнена. Необходимо минимизировать суммарную [[Классификация_задач#Критерий оптимизации|медлительность]].&lt;br /&gt;
}} &lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Будем полагать, что работы заданы в порядке неубывания их дедлайнов, то есть &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;. &lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть есть работы &amp;lt;tex&amp;gt;1 \ldots n&amp;lt;/tex&amp;gt; с дедлайнами &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;. Тогда существует оптимальное расписание, в котором времена завершения работ идут в том же порядке, то есть &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим две работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из какого-либо оптимального расписания такие, что &amp;lt;tex&amp;gt;C_i &amp;gt; C_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d_i &amp;lt; d_j&amp;lt;/tex&amp;gt;. Поменяем эти работы в расписании местами, то есть &amp;lt;tex&amp;gt;C'_i = C_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C'_j = C_i&amp;lt;/tex&amp;gt;. Если они обе успевали выполниться вовремя, то это свойство сохранится, так как &amp;lt;tex&amp;gt;d_i &amp;lt; d_j&amp;lt;/tex&amp;gt;, значит по-прежнему &amp;lt;tex&amp;gt;T_i = 0&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T_j = 0&amp;lt;/tex&amp;gt;, то есть значение целевой функции мы не ухудшили и расписание осталось оптимальным. Если обе работы не успевали выполниться вовремя, то когда мы поменяем их местами ничего не изменится, то есть значение целевой функции останется прежним, так как мы не меняли значения времен окончаний, а только поменяли их местами. Если работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; успевала выполниться, а  &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; {{---}} нет, то мы снова не ухудшим значение целевой функции. Покажем это. До того, как мы поменяли работы местами, было &amp;lt;tex&amp;gt;T_i + T_j = C_i - d_i&amp;lt;/tex&amp;gt;, так как &amp;lt;tex&amp;gt;T_j = 0&amp;lt;/tex&amp;gt;. После того, как мы поменяли работы местами, &amp;lt;tex&amp;gt;T_i + T_j = C'_i - d_i + C'_j - d_j =  C_j - d_i + C_i - d_j = C_i - d_i + (C_j - d_j)&amp;lt;/tex&amp;gt;. Но так как работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; успевает выполниться до дедлайна, то &amp;lt;tex&amp;gt;C_j - d_j \leqslant 0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
Далее будем рассматривать только оптимальное расписание со свойством &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Всегда существует оптимально расписание такое, что в нем &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для любого &amp;lt;tex&amp;gt;i = 1 \ldots n&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; {{---}} количество станков.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим оптимальное расписание &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;, в котором для любого &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt; выполняется &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt;, но &amp;lt;tex&amp;gt;C_k &amp;gt; m + k - 1&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; максимально среди всех возможных. Для начала покажем, что &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; не меньше &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;. Пусть есть оптимальное расписание, у которого &amp;lt;tex&amp;gt;C_1 &amp;gt; m&amp;lt;/tex&amp;gt;. Это значит, что есть период времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; такой, что первая работа выполняется в момент &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; и не выполняется в &amp;lt;tex&amp;gt;t - 1&amp;lt;/tex&amp;gt;. Поменяем эти периоды времени местами. То есть все работы, которые выполнялись в момент &amp;lt;tex&amp;gt;t - 1&amp;lt;/tex&amp;gt;, будут выполняться на тех же станках, но в момент &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, и наоборот. Значение &amp;lt;tex&amp;gt;C_i&amp;lt;/tex&amp;gt; для каждой работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; не увеличится, так как &amp;lt;tex&amp;gt;C_1&amp;lt;/tex&amp;gt; было минимальным из них, а значит ни одна работа не могла быть закончена раньше периода времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Будем продолжать этот процесс, пока не будет выполнено равенство &amp;lt;tex&amp;gt;C_1 = m&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь пусть &amp;lt;tex&amp;gt;C_k = m + k + t&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;t \geqslant 0&amp;lt;/tex&amp;gt;. Будем называть ''итерацией обработки'' работы обработку на одной машине. Разобьем все работы на три множества:&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; будет содержать все итерации обработки работ &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; {{---}} все итерации, запланированные в расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt; строго после момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; {{---}} итерации обработки работ &amp;lt;tex&amp;gt;i = k + 1 \ldots n&amp;lt;/tex&amp;gt;, которые в &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt; запланированы на время &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; и раньше&lt;br /&gt;
Таким образом, мы имеем три непересекающихся множества, которые вместе с работой &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; покрывают все итерации всех работ.&amp;lt;br&amp;gt;&lt;br /&gt;
Построим новое расписание &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;. Для начала расставим все работы из множества &amp;lt;tex&amp;gt;A \cup B&amp;lt;/tex&amp;gt; так же, как они были запланированы в расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt;, ни одна итерация обработки в множестве &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; не поставлена раньше момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; и к моменту времени &amp;lt;tex&amp;gt;C_k = m + k + t&amp;lt;/tex&amp;gt; выполнено &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ, то это значит, что между моментами времени &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k + m - 1&amp;lt;/tex&amp;gt; на каждой машине есть &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; различных простоев, то есть моментов, когда на ней ничего не обрабатывается. Значит, мы всегда сможем поставить на эти простои итерации обработки работы &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, даже если эти простои пересекаются. Таким образом, &amp;lt;tex&amp;gt;C_k \leqslant m + k - 1&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь назначим машины для операций из множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. До момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; сейчас распланировано ровно &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ, так как по определению работы из множества &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; запланированы на время строго большее &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;. Значит, между моментами времени &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; есть &amp;lt;tex&amp;gt;k + m + t - k = m + t&amp;lt;/tex&amp;gt; различных простоев на каждой машине. Исходя из определения множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; и того, что к моменту &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; распланировано &amp;lt;tex&amp;gt;km&amp;lt;/tex&amp;gt; итераций обработок, приходим к неравенству &amp;lt;tex&amp;gt;|C| \leqslant (k + m + t)m - km = (m + t)m&amp;lt;/tex&amp;gt;. Значит, мы можем распланировать итерации из множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; не позднее момента &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;. Таим образом, мы снова построили расписание для задачи open shop, которое так же является оптимальным, так как для множеств &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; все осталось как в оптимальном расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;, работу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; мы научились выполнять быстрее, а для множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; ответ был не ухудшен. Любая работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, итерации обработки которой принадлежат множеству &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, имела время окончания &amp;lt;tex&amp;gt;C_j \geqslant m + k + t&amp;lt;/tex&amp;gt;. Однако это противоречит тому, что мы выбрали максимальное &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;. &lt;br /&gt;
}}&lt;br /&gt;
Отсортируем работы в порядке неуменьшения дедлайнов. Для текущей работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; вычислим ''лимит'' &amp;lt;tex&amp;gt;T_i&amp;lt;/tex&amp;gt; {{---}} время, до которого закончится обработка данной работы, то есть &amp;lt;tex&amp;gt;1 \leqslant t_1 &amp;lt; t_2 &amp;lt; \ldots &amp;lt; t_m \leqslant T_i &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;t_j&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;j = 1 \ldots m&amp;lt;/tex&amp;gt; {{---}} периоды обработки работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Будем выбирать эти периоды среди моментов времени, в которые выполняется наименьшее число работ.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Определим ''вектор частот'' &amp;lt;tex&amp;gt;h[t]&amp;lt;/tex&amp;gt; {{---}} количество работ во временном интервале &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Работы отсортированы в порядке &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
   '''function''' scheduler():&lt;br /&gt;
      '''int''' &amp;lt;tex&amp;gt;h[m + n - 1]&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''vector&amp;lt;int&amp;gt;''' &amp;lt;tex&amp;gt;s[n]&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''fill'''(&amp;lt;tex&amp;gt;h,\ 0&amp;lt;/tex&amp;gt;)&lt;br /&gt;
      '''fill'''(&amp;lt;tex&amp;gt;s,\ \varnothing&amp;lt;/tex&amp;gt;)  &lt;br /&gt;
      '''for''' &amp;lt;tex&amp;gt;i = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''if''' &amp;lt;tex&amp;gt;d_i &amp;lt; m + i - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
            вычислим &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; {{---}} количество временных интервалов &amp;lt;tex&amp;gt;t = 1 \ldots d_i&amp;lt;/tex&amp;gt;, таких, что &amp;lt;tex&amp;gt;h[t] &amp;lt; m&amp;lt;/tex&amp;gt;&lt;br /&gt;
            '''if''' &amp;lt;tex&amp;gt;z \geqslant m&amp;lt;/tex&amp;gt;&lt;br /&gt;
               &amp;lt;tex&amp;gt;T_i = d_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
            '''else''' &lt;br /&gt;
               &amp;lt;tex&amp;gt;T_i = d_i + m - z&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''else'''&lt;br /&gt;
            &amp;lt;tex&amp;gt;T_i = m + i - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
         вычислим &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; периодов &amp;lt;tex&amp;gt;1 \leqslant t_1 &amp;lt; t_2 &amp;lt; \ldots &amp;lt; t_m \leqslant T_i &amp;lt;/tex&amp;gt; с минимальными значениями &amp;lt;tex&amp;gt;h[t_j]&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''for''' &amp;lt;tex&amp;gt;j = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;&lt;br /&gt;
            &amp;lt;tex&amp;gt;s[i] =  s[i] \cup \{t_j - 1\}&amp;lt;/tex&amp;gt;         &amp;lt;font color=green&amp;gt;// ставим работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; на время &amp;lt;tex&amp;gt;[t_j - 1, t_j]&amp;lt;/tex&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
            &amp;lt;tex&amp;gt;h[t_j] = h[t_j] + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''return''' &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Асимптотика ===&lt;br /&gt;
Алгоритм может работать за &amp;lt;tex&amp;gt;O(nm)&amp;lt;/tex&amp;gt;. Чтобы получить алгоритм с такой сложностью, мы распределяем работы так, чтобы после каждого шага &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; сохранялся инвариант &amp;lt;tex&amp;gt;l_1 \geqslant l_2 \geqslant \ldots \geqslant l_m &amp;lt;/tex&amp;gt; при &amp;lt;tex&amp;gt;l_1 \geqslant T_i&amp;lt;/tex&amp;gt;, такой, что на станке &amp;lt;tex&amp;gt;M_j&amp;lt;/tex&amp;gt; все промежутки &amp;lt;tex&amp;gt;1 \ldots l_j&amp;lt;/tex&amp;gt; заняты.&lt;br /&gt;
На первом шаге алгоритма &amp;lt;tex&amp;gt; l_1 = l_2 = \ldots = l_m = 0 &amp;lt;/tex&amp;gt;. Предположим, что инвариант сохранился после шага &amp;lt;tex&amp;gt; i - 1 &amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt; T_{i-1} \leqslant T_i &amp;lt;/tex&amp;gt; и, для сохранения инварианта, распределим работу в следующем порядке:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;l_1 + 1 \ldots T_i&amp;lt;/tex&amp;gt; на станке &amp;lt;tex&amp;gt; M_1 &amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;l_2 + 1 \ldots l_1&amp;lt;/tex&amp;gt; на станке &amp;lt;tex&amp;gt; M_2 &amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; \vdots &amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;l_m + 1 \ldots l_{m-1}&amp;lt;/tex&amp;gt; на станке &amp;lt;tex&amp;gt; M_1 &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Таким образом, мы получаем распределение одной работы по &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; станкам для &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ. Итоговая асимптотика {{---}} &amp;lt;tex&amp;gt;O(nm)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=Алгоритм строит оптимальное расписание для задачи &amp;lt;tex&amp;gt; O \mid p_{i,j} = 1 \mid \sum T_{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
|proof= Воспользуемся для доказательства леммой и теоремой, которые были доказаны выше. Из них мы знаем, что существует оптимальное расписание, для которого выполняются свойства &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для любого &amp;lt;tex&amp;gt;i = 1 \ldots n&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; {{---}} число станков. Пусть &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; {{---}} оптимальное расписание, которое удовлетворяет свойству, по которому работы &amp;lt;tex&amp;gt;1 \ldots k - 1 &amp;lt;/tex&amp;gt; поставлены в те же временные промежутки, в которых они оказались следуя нашему расписанию &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Более того, предположим, что &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; было выбрано так, что &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; максимально.&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;C_k &amp;gt; T_k&amp;lt;/tex&amp;gt;. С того момента, как работа &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; поставлена в расписании &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; перед &amp;lt;tex&amp;gt;T_k&amp;lt;/tex&amp;gt;, определим временной промежуток &amp;lt;tex&amp;gt;t \leqslant T_k &amp;lt;/tex&amp;gt; в месте, где работа &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; не выполняется в &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt;. Тогда в самом расписании &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; этот промежуток либо так же пустой, либо он занят работой &amp;lt;tex&amp;gt;r &amp;gt; k&amp;lt;/tex&amp;gt;. &lt;br /&gt;
* Если он пустой, мы перемещаем операцию &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, которая была распределена в промежуток &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;, в этот промежуток. &lt;br /&gt;
* Если работа &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; стоит во время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, но не во время &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;, то мы меняем между собой операции работ &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Если работа &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; поставлена во время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;, то либо тут есть пустое место в &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt;, либо там должна быть работа, назовем ее &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;, которая поставлена на время &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt;, но не поставлена в &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Работа &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; точно там есть, потому что &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; поставлены на время &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;, но не поставлены на время &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt;. Если свободный промежуток есть, тогда переставим работу &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; со времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; на время &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt; и работу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; со времени &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Иначе мы можем переместить работу &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; с времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; на время &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; c &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; с &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt; должно уменьшиться как минимум на один, а &amp;lt;tex&amp;gt;C_r&amp;lt;/tex&amp;gt; увеличится не больше чем на один.&lt;br /&gt;
Если мы продолжим так действовать, мы получим оптимальное расписание &amp;lt;tex&amp;gt;B'&amp;lt;/tex&amp;gt; с &amp;lt;tex&amp;gt;C_k \leqslant T_k&amp;lt;/tex&amp;gt;, в котором работы &amp;lt;tex&amp;gt;1 \ldots k-1&amp;lt;/tex&amp;gt; расположены так же, как в расписании &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;h&amp;lt;/tex&amp;gt; {{---}} вектор частот для части расписания из работ от &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;k - 1&amp;lt;/tex&amp;gt;. Предположим, что &amp;lt;tex&amp;gt;h(t') &amp;lt; h(t)&amp;lt;/tex&amp;gt; и работа &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; выполняется во временной промежуток &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, но не выполняется в &amp;lt;tex&amp;gt;t'&amp;lt;/tex&amp;gt; в расписании &amp;lt;tex&amp;gt;B'&amp;lt;/tex&amp;gt;. Если в &amp;lt;tex&amp;gt;B'&amp;lt;/tex&amp;gt; станок простаивает во время &amp;lt;tex&amp;gt;t'&amp;lt;/tex&amp;gt;, мы можем переместить работу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;t'&amp;lt;/tex&amp;gt;. Иначе работа &amp;lt;tex&amp;gt;r &amp;gt; k&amp;lt;/tex&amp;gt; находится в расписании в промежутке &amp;lt;tex&amp;gt;t'&amp;lt;/tex&amp;gt;, но ее нет в &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Мы можем передвинуть &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;t'&amp;lt;/tex&amp;gt; без увеличения целевой функции, потому что &amp;lt;tex&amp;gt;C_k \leqslant C_r&amp;lt;/tex&amp;gt;. Продолжая действовать таким образом, мы достигнем оптимального расписания, в котором работы &amp;lt;tex&amp;gt;1 \ldots k&amp;lt;/tex&amp;gt; расположены таким же образом, как и в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Мы получили противоречие, так как выбранный &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; оказался не максимальным. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[O2Cmax|&amp;lt;tex&amp;gt;O2 \mid \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opi1sumu|&amp;lt;tex&amp;gt;O \mid p_{ij} = 1 \mid \sum U_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1di|&amp;lt;tex&amp;gt; O \mid p_{i, j} = 1, d_i \mid - &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1sumwu|&amp;lt;tex&amp;gt; O \mid p_{i, j} = 1 \mid - \sum w_{i} U_{i}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* Peter Brucker «Scheduling Algorithms», fifth edition, Springer {{---}} с. 171-174 ISBN 978-3-540-69515-8&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Opij1SumTi&amp;diff=55000</id>
		<title>Opij1SumTi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Opij1SumTi&amp;diff=55000"/>
				<updated>2016-06-08T19:30:54Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: /* Асимптотика */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; O \mid p_{i,j} = 1 \mid \sum T_{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; одинаковых станков, которые работают параллельно, и &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ, которые необходимо выполнить в произвольном порядке на всех станках. Любая работа на любом станке выполняется единицу времени. Для каждой работы есть время окончания &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; {{---}} время, до которого она должна быть выполнена. Необходимо минимизировать суммарную [[Классификация_задач#Критерий оптимизации|медлительность]].&lt;br /&gt;
}} &lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Будем полагать, что работы заданы в порядке неубывания их дедлайнов, то есть &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;. &lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть есть работы &amp;lt;tex&amp;gt;1 \ldots n&amp;lt;/tex&amp;gt; с дедлайнами &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;. Тогда существует оптимальное расписание, в котором времена завершения работ идут в том же порядке, то есть &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим две работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из какого-либо оптимального расписания такие, что &amp;lt;tex&amp;gt;C_i &amp;gt; C_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d_i &amp;lt; d_j&amp;lt;/tex&amp;gt;. Поменяем эти работы в расписании местами, то есть &amp;lt;tex&amp;gt;C'_i = C_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C'_j = C_i&amp;lt;/tex&amp;gt;. Если они обе успевали выполниться вовремя, то это свойство сохранится, так как &amp;lt;tex&amp;gt;d_i &amp;lt; d_j&amp;lt;/tex&amp;gt;, значит по-прежнему &amp;lt;tex&amp;gt;T_i = 0&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T_j = 0&amp;lt;/tex&amp;gt;, то есть значение целевой функции мы не ухудшили и расписание осталось оптимальным. Если обе работы не успевали выполниться вовремя, то когда мы поменяем их местами ничего не изменится, то есть значение целевой функции останется прежним, так как мы не меняли значения времен окончаний, а только поменяли их местами. Если работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; успевала выполниться, а  &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; {{---}} нет, то мы снова не ухудшим значение целевой функции. Покажем это. До того, как мы поменяли работы местами, было &amp;lt;tex&amp;gt;T_i + T_j = C_i - d_i&amp;lt;/tex&amp;gt;, так как &amp;lt;tex&amp;gt;T_j = 0&amp;lt;/tex&amp;gt;. После того, как мы поменяли работы местами, &amp;lt;tex&amp;gt;T_i + T_j = C'_i - d_i + C'_j - d_j =  C_j - d_i + C_i - d_j = C_i - d_i + (C_j - d_j)&amp;lt;/tex&amp;gt;. Но так как работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; успевает выполниться до дедлайна, то &amp;lt;tex&amp;gt;C_j - d_j \leqslant 0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
Далее будем рассматривать только оптимальное расписание со свойством &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Всегда существует оптимально расписание такое, что в нем &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для любого &amp;lt;tex&amp;gt;i = 1 \ldots n&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; {{---}} количество станков.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим оптимальное расписание &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;, в котором для любого &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt; выполняется &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt;, но &amp;lt;tex&amp;gt;C_k &amp;gt; m + k - 1&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; максимально среди всех возможных. Для начала покажем, что &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; не меньше &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;. Пусть есть оптимальное расписание, у которого &amp;lt;tex&amp;gt;C_1 &amp;gt; m&amp;lt;/tex&amp;gt;. Это значит, что есть период времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; такой, что первая работа выполняется в момент &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; и не выполняется в &amp;lt;tex&amp;gt;t - 1&amp;lt;/tex&amp;gt;. Поменяем эти периоды времени местами. То есть все работы, которые выполнялись в момент &amp;lt;tex&amp;gt;t - 1&amp;lt;/tex&amp;gt;, будут выполняться на тех же станках, но в момент &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, и наоборот. Значение &amp;lt;tex&amp;gt;C_i&amp;lt;/tex&amp;gt; для каждой работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; не увеличится, так как &amp;lt;tex&amp;gt;C_1&amp;lt;/tex&amp;gt; было минимальным из них, а значит ни одна работа не могла быть закончена раньше периода времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Будем продолжать этот процесс, пока не будет выполнено равенство &amp;lt;tex&amp;gt;C_1 = m&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь пусть &amp;lt;tex&amp;gt;C_k = m + k + t&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;t \geqslant 0&amp;lt;/tex&amp;gt;. Будем называть ''итерацией обработки'' работы обработку на одной машине. Разобьем все работы на три множества:&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; будет содержать все итерации обработки работ &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; {{---}} все итерации, запланированные в расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt; строго после момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; {{---}} итерации обработки работ &amp;lt;tex&amp;gt;i = k + 1 \ldots n&amp;lt;/tex&amp;gt;, которые в &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt; запланированы на время &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; и раньше&lt;br /&gt;
Таким образом, мы имеем три непересекающихся множества, которые вместе с работой &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; покрывают все итерации всех работ.&amp;lt;br&amp;gt;&lt;br /&gt;
Построим новое расписание &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;. Для начала расставим все работы из множества &amp;lt;tex&amp;gt;A \cup B&amp;lt;/tex&amp;gt; так же, как они были запланированы в расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt;, ни одна итерация обработки в множестве &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; не поставлена раньше момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; и к моменту времени &amp;lt;tex&amp;gt;C_k = m + k + t&amp;lt;/tex&amp;gt; выполнено &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ, то это значит, что между моментами времени &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k + m - 1&amp;lt;/tex&amp;gt; на каждой машине есть &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; различных простоев, то есть моментов, когда на ней ничего не обрабатывается. Значит, мы всегда сможем поставить на эти простои итерации обработки работы &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, даже если эти простои пересекаются. Таким образом, &amp;lt;tex&amp;gt;C_k \leqslant m + k - 1&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь назначим машины для операций из множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. До момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; сейчас распланировано ровно &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ, так как по определению работы из множества &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; запланированы на время строго большее &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;. Значит, между моментами времени &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; есть &amp;lt;tex&amp;gt;k + m + t - k = m + t&amp;lt;/tex&amp;gt; различных простоев на каждой машине. Исходя из определения множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; и того, что к моменту &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; распланировано &amp;lt;tex&amp;gt;km&amp;lt;/tex&amp;gt; итераций обработок, приходим к неравенству &amp;lt;tex&amp;gt;|C| \leqslant (k + m + t)m - km = (m + t)m&amp;lt;/tex&amp;gt;. Значит, мы можем распланировать итерации из множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; не позднее момента &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;. Таим образом, мы снова построили расписание для задачи open shop, которое так же является оптимальным, так как для множеств &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; все осталось как в оптимальном расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;, работу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; мы научились выполнять быстрее, а для множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; ответ был не ухудшен. Любая работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, итерации обработки которой принадлежат множеству &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, имела время окончания &amp;lt;tex&amp;gt;C_j \geqslant m + k + t&amp;lt;/tex&amp;gt;. Однако это противоречит тому, что мы выбрали максимальное &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;. &lt;br /&gt;
}}&lt;br /&gt;
Отсортируем работы в порядке неуменьшения дедлайнов. Для текущей работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; вычислим ''лимит'' &amp;lt;tex&amp;gt;T_i&amp;lt;/tex&amp;gt; {{---}} время, до которого закончится обработка данной работы, то есть &amp;lt;tex&amp;gt;1 \leqslant t_1 &amp;lt; t_2 &amp;lt; \ldots &amp;lt; t_m \leqslant T_i &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;t_j&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;j = 1 \ldots m&amp;lt;/tex&amp;gt; {{---}} периоды обработки работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Будем выбирать эти периоды среди моментов времени, в которые выполняется наименьшее число работ.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Определим ''вектор частот'' &amp;lt;tex&amp;gt;h[t]&amp;lt;/tex&amp;gt; {{---}} количество работ во временном интервале &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Работы отсортированы в порядке &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
   '''function''' scheduler():&lt;br /&gt;
      '''int''' &amp;lt;tex&amp;gt;h[m + n - 1]&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''vector&amp;lt;int&amp;gt;''' &amp;lt;tex&amp;gt;s[n]&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''fill'''(&amp;lt;tex&amp;gt;h,\ 0&amp;lt;/tex&amp;gt;)&lt;br /&gt;
      '''fill'''(&amp;lt;tex&amp;gt;s,\ \varnothing&amp;lt;/tex&amp;gt;)  &lt;br /&gt;
      '''for''' &amp;lt;tex&amp;gt;i = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''if''' &amp;lt;tex&amp;gt;d_i &amp;lt; m + i - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
            вычислим &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; {{---}} количество временных интервалов &amp;lt;tex&amp;gt;t = 1 \ldots d_i&amp;lt;/tex&amp;gt;, таких, что &amp;lt;tex&amp;gt;h[t] &amp;lt; m&amp;lt;/tex&amp;gt;&lt;br /&gt;
            '''if''' &amp;lt;tex&amp;gt;z \geqslant m&amp;lt;/tex&amp;gt;&lt;br /&gt;
               &amp;lt;tex&amp;gt;T_i = d_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
            '''else''' &lt;br /&gt;
               &amp;lt;tex&amp;gt;T_i = d_i + m - z&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''else'''&lt;br /&gt;
            &amp;lt;tex&amp;gt;T_i = m + i - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
         вычислим &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; периодов &amp;lt;tex&amp;gt;1 \leqslant t_1 &amp;lt; t_2 &amp;lt; \ldots &amp;lt; t_m \leqslant T_i &amp;lt;/tex&amp;gt; с минимальными значениями &amp;lt;tex&amp;gt;h[t_j]&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''for''' &amp;lt;tex&amp;gt;j = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;&lt;br /&gt;
            &amp;lt;tex&amp;gt;s[i] =  s[i] \cup \{t_j - 1\}&amp;lt;/tex&amp;gt;         &amp;lt;font color=green&amp;gt;// ставим работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; на время &amp;lt;tex&amp;gt;[t_j - 1, t_j]&amp;lt;/tex&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
            &amp;lt;tex&amp;gt;h[t_j] = h[t_j] + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''return''' &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Асимптотика ===&lt;br /&gt;
Алгоритм может работать за &amp;lt;tex&amp;gt;O(nm)&amp;lt;/tex&amp;gt;. Чтобы получить алгоритм с такой сложностью, мы распределяем работы так, чтобы после каждого шага &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; сохранялся инвариант &amp;lt;tex&amp;gt;l_1 \geqslant l_2 \geqslant \ldots \geqslant l_m &amp;lt;/tex&amp;gt; при &amp;lt;tex&amp;gt;l_1 \geqslant T_i&amp;lt;/tex&amp;gt;, такой, что на станке &amp;lt;tex&amp;gt;M_j&amp;lt;/tex&amp;gt; все промежутки &amp;lt;tex&amp;gt;1 \ldots l_j&amp;lt;/tex&amp;gt; заняты.&lt;br /&gt;
На первом шаге алгоритма &amp;lt;tex&amp;gt; l_1 = l_2 = \ldots = l_m = 0 &amp;lt;/tex&amp;gt;. Предположим, что инвариант сохранился после шага &amp;lt;tex&amp;gt; i - 1 &amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt; T_{i-1} \leqslant T_i &amp;lt;/tex&amp;gt; и, для сохранения инварианта, распределим работу в следующем порядке:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;l_1 + 1 \ldots T_i&amp;lt;/tex&amp;gt; на станке &amp;lt;tex&amp;gt; M_1 &amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;l_2 + 1 \ldots l_1&amp;lt;/tex&amp;gt; на станке &amp;lt;tex&amp;gt; M_2 &amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; \vdots &amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;l_m + 1 \ldots l_{m-1}&amp;lt;/tex&amp;gt; на станке &amp;lt;tex&amp;gt; M_1 &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Таким образом, мы получаем распределение одной работы по &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; станкам для &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ. Итоговая асимптотика {{---}} &amp;lt;tex&amp;gt;O(nm)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=Алгоритм строит оптимальное расписание для задачи &amp;lt;tex&amp;gt; O \mid p_{i,j} = 1 \mid \sum T_{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
|proof= Воспользуемся для доказательства леммой и теоремой, которые доказаны выше. Из них мы знаем, что существует оптимальное расписание, для которого выполняются свойства &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для любого &amp;lt;tex&amp;gt;i = 1 \ldots n&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; {{---}} число станков. Пусть &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; оптимальное расписание, которое удовлетворяет свойству, по которому работы &amp;lt;tex&amp;gt;1 \ldots k - 1 &amp;lt;/tex&amp;gt; поставлены в те же временные промежутки, в которых они оказались следуя нашему расписанию &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Более того, предположим, что &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; было выбрано так, что &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; максимально.&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;C_k &amp;gt; T_k&amp;lt;/tex&amp;gt;. С того момента, как работа &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; поставлена в расписании &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; перед &amp;lt;tex&amp;gt;T_k&amp;lt;/tex&amp;gt;, определим временной промежуток &amp;lt;tex&amp;gt;t \leqslant T_k &amp;lt;/tex&amp;gt; в месте, где работа &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; не выполняется в &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt;. Тогда в самом расписании &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; этот промежуток или также пустой или он занят работой &amp;lt;tex&amp;gt;r &amp;gt; k&amp;lt;/tex&amp;gt;. &lt;br /&gt;
* Если он пустой, мы перемещаем операцию &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, которая была распределена в промежуток &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;, в этот промежуток. &lt;br /&gt;
* Если работа &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; стоит во время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, но не во время &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;, то мы меняем между собой операции работ &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Если работа &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; поставлена во время &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;, то, либо тут есть пустое место в &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt;, либо там должна быть работа, назовем ее &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;, которая поставлена на время &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt;, но не поставлена в &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Работа &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; точно там есть, потому что &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; поставлены на время &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;, но не поставлены на время &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt;. Если свободный промежуток есть, тогда переставим работу &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; со времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; на время &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt; и работу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; со времени &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Иначе мы можем переместить работу &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; с времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; на время &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; c &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; с &amp;lt;tex&amp;gt;C_r + 1&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;C_k&amp;lt;/tex&amp;gt; должно уменьшиться как минимум на один, а &amp;lt;tex&amp;gt;C_r&amp;lt;/tex&amp;gt; увеличится не больше чем на один.&lt;br /&gt;
Если мы продолжим так действовать, мы получим оптимальное расписание &amp;lt;tex&amp;gt;B'&amp;lt;/tex&amp;gt; с &amp;lt;tex&amp;gt;C_k \leqslant T_k&amp;lt;/tex&amp;gt;, в котором работы &amp;lt;tex&amp;gt;1 \ldots k-1&amp;lt;/tex&amp;gt; расположены так же, как в расписании &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;h&amp;lt;/tex&amp;gt; {{---}} вектор частот для части расписания из работ от &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;k - 1&amp;lt;/tex&amp;gt;. Предположим, что &amp;lt;tex&amp;gt;h(t') &amp;lt; h(t)&amp;lt;/tex&amp;gt; и работа &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; выполняется во временной промежуток &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, но не выполняется в &amp;lt;tex&amp;gt;t'&amp;lt;/tex&amp;gt; в расписании &amp;lt;tex&amp;gt;B'&amp;lt;/tex&amp;gt;. Если в &amp;lt;tex&amp;gt;B'&amp;lt;/tex&amp;gt; станок простаивает во время &amp;lt;tex&amp;gt;t'&amp;lt;/tex&amp;gt;, мы можем переместить работу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;t'&amp;lt;/tex&amp;gt;. Иначе работа &amp;lt;tex&amp;gt;r &amp;gt; k&amp;lt;/tex&amp;gt; находится в расписании в промежутке &amp;lt;tex&amp;gt;t'&amp;lt;/tex&amp;gt;, но ее нет в &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Мы можем передвинуть &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;t'&amp;lt;/tex&amp;gt; без увеличения целевой функции, потому что &amp;lt;tex&amp;gt;C_k \leqslant C_r&amp;lt;/tex&amp;gt;. Продолжая действовать таким образом, мы достигнем оптимального расписания, в котором работы &amp;lt;tex&amp;gt;1 \ldots k&amp;lt;/tex&amp;gt; расположены таким же образом, как и в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Мы получили противоречие, так как выбранный &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; оказался не максимальным. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[O2Cmax|&amp;lt;tex&amp;gt;O2 \mid \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opi1sumu|&amp;lt;tex&amp;gt;O \mid p_{ij} = 1 \mid \sum U_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1di|&amp;lt;tex&amp;gt; O \mid p_{i, j} = 1, d_i \mid - &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1sumwu|&amp;lt;tex&amp;gt; O \mid p_{i, j} = 1 \mid - \sum w_{i} U_{i}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* Peter Brucker «Scheduling Algorithms», fifth edition, Springer {{---}} с. 171-174 ISBN 978-3-540-69515-8&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Opij1SumTi&amp;diff=54578</id>
		<title>Opij1SumTi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Opij1SumTi&amp;diff=54578"/>
				<updated>2016-06-05T11:38:05Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: /* Псевдокод */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; O \mid p_{i,j} = 1 \mid \sum T_{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; одинаковых станков, которые работают параллельно, и &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ, которые необходимо выполнить в произвольном порядке на всех станках. Любая работа на любом станке выполняется единицу времени. Для каждой работы есть время окончания &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; {{---}} время, до которого она должна быть выполнена. Необходимо минимизировать суммарную [[Классификация_задач#Критерий оптимизации|медлительность]].&lt;br /&gt;
}} &lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Будем полагать, что работы заданы в порядке неубывания их дедлайнов, то есть &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;. &lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть есть работы &amp;lt;tex&amp;gt;1 \ldots n&amp;lt;/tex&amp;gt; с дедлайнами &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;. Тогда существует оптимальное расписание, в котором времена завершения работ идут в том же порядке, то есть &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим две работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из какого-либо оптимального расписания такие, что &amp;lt;tex&amp;gt;C_i &amp;gt; C_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d_i &amp;lt; d_j&amp;lt;/tex&amp;gt;. Поменяем эти работы в расписании местами, то есть &amp;lt;tex&amp;gt;C'_i = C_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C'_j = C_i&amp;lt;/tex&amp;gt;. Если они обе успевали выполниться вовремя, то это свойство сохранится, так как &amp;lt;tex&amp;gt;d_i &amp;lt; d_j&amp;lt;/tex&amp;gt;, значит по-прежнему &amp;lt;tex&amp;gt;T_i = 0&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T_j = 0&amp;lt;/tex&amp;gt;, то есть значение целевой функции мы не ухудшили и расписание осталось оптимальным. Если обе работы не успевали выполниться вовремя, то когда мы поменяем их местами ничего не изменится, то есть значение целевой функции останется прежним, так как мы не меняли значения времен окончаний, а только поменяли их местами. Если работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; успевала выполниться, а  &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; {{---}} нет, то мы снова не ухудшим значение целевой функции. Покажем это. До того, как мы поменяли работы местами, было &amp;lt;tex&amp;gt;T_i + T_j = C_i - d_i&amp;lt;/tex&amp;gt;, так как &amp;lt;tex&amp;gt;T_j = 0&amp;lt;/tex&amp;gt;. После того, как мы поменяли работы местами, &amp;lt;tex&amp;gt;T_i + T_j = C'_i - d_i + C'_j - d_j =  C_j - d_i + C_i - d_j = C_i - d_i + (C_j - d_j)&amp;lt;/tex&amp;gt;. Но так как работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; успевает выполниться до дедлайна, то &amp;lt;tex&amp;gt;C_j - d_j \leqslant 0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
Далее будем рассматривать только оптимальное расписание со свойством &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Всегда существует оптимально расписание такое, что в нем &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для любого &amp;lt;tex&amp;gt;i = 1 \ldots n&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; {{---}} количество станков.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим оптимальное расписание &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;, в котором для любого &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt; выполняется &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt;, но &amp;lt;tex&amp;gt;C_k &amp;gt; m + k - 1&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; максимально среди всех возможных. Для начала покажем, что &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; не меньше &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;. Пусть есть оптимальное расписание, у которого &amp;lt;tex&amp;gt;C_1 &amp;gt; m&amp;lt;/tex&amp;gt;. Это значит, что есть период времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; такой, что первая работа выполняется в момент &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; и не выполняется в &amp;lt;tex&amp;gt;t - 1&amp;lt;/tex&amp;gt;. Поменяем эти периоды времени местами. То есть все работы, которые выполнялись в момент &amp;lt;tex&amp;gt;t - 1&amp;lt;/tex&amp;gt;, будут выполняться на тех же станках, но в момент &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, и наоборот. Значение &amp;lt;tex&amp;gt;C_i&amp;lt;/tex&amp;gt; для каждой работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; не увеличится, так как &amp;lt;tex&amp;gt;C_1&amp;lt;/tex&amp;gt; было минимальным из них, а значит ни одна работа не могла быть закончена раньше периода времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Будем продолжать этот процесс, пока не будет выполнено равенство &amp;lt;tex&amp;gt;C_1 = m&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь пусть &amp;lt;tex&amp;gt;C_k = m + k + t&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;t \geqslant 0&amp;lt;/tex&amp;gt;. Будем называть ''итерацией обработки'' работы обработку на одной машине. Разобьем все работы на три множества:&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; будет содержать все итерации обработки работ &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; {{---}} все итерации, запланированные в расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt; строго после момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; {{---}} итерации обработки работ &amp;lt;tex&amp;gt;i = k + 1 \ldots n&amp;lt;/tex&amp;gt;, которые в &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt; запланированы на время &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; и раньше&lt;br /&gt;
Таким образом, мы имеем три непересекающихся множества, которые вместе с работой &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; покрывают все итерации всех работ.&amp;lt;br&amp;gt;&lt;br /&gt;
Построим новое расписание &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;. Для начала расставим все работы из множества &amp;lt;tex&amp;gt;A \cup B&amp;lt;/tex&amp;gt; так же, как они были запланированы в расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt;, ни одна итерация обработки в множестве &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; не поставлена раньше момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; и к моменту времени &amp;lt;tex&amp;gt;C_k = m + k + t&amp;lt;/tex&amp;gt; выполнено &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ, то это значит, что между моментами времени &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k + m - 1&amp;lt;/tex&amp;gt; на каждой машине есть &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; различных простоев, то есть моментов, когда на ней ничего не обрабатывается. Значит, мы всегда сможем поставить на эти простои итерации обработки работы &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, даже если эти простои пересекаются. Таким образом, &amp;lt;tex&amp;gt;C_k \leqslant m + k - 1&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь назначим машины для операций из множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. До момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; сейчас распланировано ровно &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ, так как по определению работы из множества &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; запланированы на время строго большее &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;. Значит, между моментами времени &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; есть &amp;lt;tex&amp;gt;k + m + t - k = m + t&amp;lt;/tex&amp;gt; различных простоев на каждой машине. Исходя из определения множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; и того, что к моменту &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; распланировано &amp;lt;tex&amp;gt;km&amp;lt;/tex&amp;gt; итераций обработок, приходим к неравенству &amp;lt;tex&amp;gt;|C| \leqslant (k + m + t)m - km = (m + t)m&amp;lt;/tex&amp;gt;. Значит, мы можем распланировать итерации из множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; не позднее момента &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;. Таим образом, мы снова построили расписание для задачи open shop, которое так же является оптимальным, так как для множеств &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; все осталось как в оптимальном расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;, работу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; мы научились выполнять быстрее, а для множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; ответ был не ухудшен. Любая работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, итерации обработки которой принадлежат множеству &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, имела время окончания &amp;lt;tex&amp;gt;C_j \geqslant m + k + t&amp;lt;/tex&amp;gt;. Однако это противоречит тому, что мы выбрали максимальное &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;. &lt;br /&gt;
}}&lt;br /&gt;
Отсортируем работы в порядке неуменьшения дедлайнов. Для текущей работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; вычислим ''лимит'' &amp;lt;tex&amp;gt;T_i&amp;lt;/tex&amp;gt; {{---}} время, до которого закончится обработка данной работы, то есть &amp;lt;tex&amp;gt;1 \leqslant t_1 &amp;lt; t_2 &amp;lt; \ldots &amp;lt; t_m \leqslant T_i &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;t_j&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;j = 1 \ldots m&amp;lt;/tex&amp;gt; {{---}} периоды обработки работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Будем выбирать эти периоды среди моментов времени, в которые выполняется наименьшее число работ.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Определим ''вектор частот'' &amp;lt;tex&amp;gt;h[t]&amp;lt;/tex&amp;gt; {{---}} количество работ во временном интервале &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Работы отсортированы в порядке &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
   '''function''' scheduler():&lt;br /&gt;
      '''int''' &amp;lt;tex&amp;gt;h[m + n - 1]&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''vector&amp;lt;int&amp;gt;''' &amp;lt;tex&amp;gt;s[n]&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''for''' &amp;lt;tex&amp;gt;t = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt;s[t] = \varnothing&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''fill'''(h, 0)&lt;br /&gt;
      '''for''' &amp;lt;tex&amp;gt;i = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''if''' &amp;lt;tex&amp;gt;d_i &amp;lt; m + i - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
            вычислим &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; {{---}} количество временных интервалов &amp;lt;tex&amp;gt;t = 1 \ldots d_i&amp;lt;/tex&amp;gt;, таких, что &amp;lt;tex&amp;gt;h[t] &amp;lt; m&amp;lt;/tex&amp;gt;&lt;br /&gt;
            '''if''' &amp;lt;tex&amp;gt;z \geqslant m&amp;lt;/tex&amp;gt;&lt;br /&gt;
               &amp;lt;tex&amp;gt;T_i = d_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
            '''else''' &lt;br /&gt;
               &amp;lt;tex&amp;gt;T_i = d_i + m - z&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''else'''&lt;br /&gt;
            &amp;lt;tex&amp;gt;T_i = m + i - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
         вычислим &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; периодов &amp;lt;tex&amp;gt;1 \leqslant t_1 &amp;lt; t_2 &amp;lt; \ldots &amp;lt; t_m \leqslant T_i &amp;lt;/tex&amp;gt; с минимальными значениями &amp;lt;tex&amp;gt;h[t_j]&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''for''' &amp;lt;tex&amp;gt;j = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;&lt;br /&gt;
            &amp;lt;tex&amp;gt;s[i] =  s[i] \cup \{t_j - 1\}&amp;lt;/tex&amp;gt;         &amp;lt;font color=green&amp;gt;// ставим работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; на время &amp;lt;tex&amp;gt;[t_j - 1, t_j]&amp;lt;/tex&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
            &amp;lt;tex&amp;gt;h[t_j] = h[t_j] + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''return''' &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Асимптотика ===&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[O2Cmax|&amp;lt;tex&amp;gt;O2 \mid \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opi1sumu|&amp;lt;tex&amp;gt;O \mid p_{ij} = 1 \mid \sum U_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1di|&amp;lt;tex&amp;gt; O \mid p_{i, j} = 1, d_i \mid - &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1sumwu|&amp;lt;tex&amp;gt; O \mid p_{i, j} = 1 \mid - \sum w_{i} U_{i}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* Peter Brucker «Scheduling Algorithms», fifth edition, Springer {{---}} с. 171-174 ISBN 978-3-540-69515-8&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Opij1SumTi&amp;diff=54577</id>
		<title>Opij1SumTi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Opij1SumTi&amp;diff=54577"/>
				<updated>2016-06-05T11:30:10Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: /* Псевдокод */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; O \mid p_{i,j} = 1 \mid \sum T_{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; одинаковых станков, которые работают параллельно, и &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ, которые необходимо выполнить в произвольном порядке на всех станках. Любая работа на любом станке выполняется единицу времени. Для каждой работы есть время окончания &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; {{---}} время, до которого она должна быть выполнена. Необходимо минимизировать суммарную [[Классификация_задач#Критерий оптимизации|медлительность]].&lt;br /&gt;
}} &lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Будем полагать, что работы заданы в порядке неубывания их дедлайнов, то есть &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;. &lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть есть работы &amp;lt;tex&amp;gt;1 \ldots n&amp;lt;/tex&amp;gt; с дедлайнами &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;. Тогда существует оптимальное расписание, в котором времена завершения работ идут в том же порядке, то есть &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим две работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из какого-либо оптимального расписания такие, что &amp;lt;tex&amp;gt;C_i &amp;gt; C_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d_i &amp;lt; d_j&amp;lt;/tex&amp;gt;. Поменяем эти работы в расписании местами, то есть &amp;lt;tex&amp;gt;C'_i = C_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C'_j = C_i&amp;lt;/tex&amp;gt;. Если они обе успевали выполниться вовремя, то это свойство сохранится, так как &amp;lt;tex&amp;gt;d_i &amp;lt; d_j&amp;lt;/tex&amp;gt;, значит по-прежнему &amp;lt;tex&amp;gt;T_i = 0&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T_j = 0&amp;lt;/tex&amp;gt;, то есть значение целевой функции мы не ухудшили и расписание осталось оптимальным. Если обе работы не успевали выполниться вовремя, то когда мы поменяем их местами ничего не изменится, то есть значение целевой функции останется прежним, так как мы не меняли значения времен окончаний, а только поменяли их местами. Если работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; успевала выполниться, а  &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; {{---}} нет, то мы снова не ухудшим значение целевой функции. Покажем это. До того, как мы поменяли работы местами, было &amp;lt;tex&amp;gt;T_i + T_j = C_i - d_i&amp;lt;/tex&amp;gt;, так как &amp;lt;tex&amp;gt;T_j = 0&amp;lt;/tex&amp;gt;. После того, как мы поменяли работы местами, &amp;lt;tex&amp;gt;T_i + T_j = C'_i - d_i + C'_j - d_j =  C_j - d_i + C_i - d_j = C_i - d_i + (C_j - d_j)&amp;lt;/tex&amp;gt;. Но так как работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; успевает выполниться до дедлайна, то &amp;lt;tex&amp;gt;C_j - d_j \leqslant 0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
Далее будем рассматривать только оптимальное расписание со свойством &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Всегда существует оптимально расписание такое, что в нем &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для любого &amp;lt;tex&amp;gt;i = 1 \ldots n&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; {{---}} количество станков.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим оптимальное расписание &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;, в котором для любого &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt; выполняется &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt;, но &amp;lt;tex&amp;gt;C_k &amp;gt; m + k - 1&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; максимально среди всех возможных. Для начала покажем, что &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; не меньше &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;. Пусть есть оптимальное расписание, у которого &amp;lt;tex&amp;gt;C_1 &amp;gt; m&amp;lt;/tex&amp;gt;. Это значит, что есть период времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; такой, что первая работа выполняется в момент &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; и не выполняется в &amp;lt;tex&amp;gt;t - 1&amp;lt;/tex&amp;gt;. Поменяем эти периоды времени местами. То есть все работы, которые выполнялись в момент &amp;lt;tex&amp;gt;t - 1&amp;lt;/tex&amp;gt;, будут выполняться на тех же станках, но в момент &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, и наоборот. Значение &amp;lt;tex&amp;gt;C_i&amp;lt;/tex&amp;gt; для каждой работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; не увеличится, так как &amp;lt;tex&amp;gt;C_1&amp;lt;/tex&amp;gt; было минимальным из них, а значит ни одна работа не могла быть закончена раньше периода времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Будем продолжать этот процесс, пока не будет выполнено равенство &amp;lt;tex&amp;gt;C_1 = m&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь пусть &amp;lt;tex&amp;gt;C_k = m + k + t&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;t \geqslant 0&amp;lt;/tex&amp;gt;. Будем называть ''итерацией обработки'' работы обработку на одной машине. Разобьем все работы на три множества:&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; будет содержать все итерации обработки работ &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; {{---}} все итерации, запланированные в расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt; строго после момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; {{---}} итерации обработки работ &amp;lt;tex&amp;gt;i = k + 1 \ldots n&amp;lt;/tex&amp;gt;, которые в &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt; запланированы на время &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; и раньше&lt;br /&gt;
Таким образом, мы имеем три непересекающихся множества, которые вместе с работой &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; покрывают все итерации всех работ.&amp;lt;br&amp;gt;&lt;br /&gt;
Построим новое расписание &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;. Для начала расставим все работы из множества &amp;lt;tex&amp;gt;A \cup B&amp;lt;/tex&amp;gt; так же, как они были запланированы в расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt;, ни одна итерация обработки в множестве &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; не поставлена раньше момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; и к моменту времени &amp;lt;tex&amp;gt;C_k = m + k + t&amp;lt;/tex&amp;gt; выполнено &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ, то это значит, что между моментами времени &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k + m - 1&amp;lt;/tex&amp;gt; на каждой машине есть &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; различных простоев, то есть моментов, когда на ней ничего не обрабатывается. Значит, мы всегда сможем поставить на эти простои итерации обработки работы &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, даже если эти простои пересекаются. Таким образом, &amp;lt;tex&amp;gt;C_k \leqslant m + k - 1&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь назначим машины для операций из множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. До момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; сейчас распланировано ровно &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ, так как по определению работы из множества &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; запланированы на время строго большее &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;. Значит, между моментами времени &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; есть &amp;lt;tex&amp;gt;k + m + t - k = m + t&amp;lt;/tex&amp;gt; различных простоев на каждой машине. Исходя из определения множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; и того, что к моменту &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; распланировано &amp;lt;tex&amp;gt;km&amp;lt;/tex&amp;gt; итераций обработок, приходим к неравенству &amp;lt;tex&amp;gt;|C| \leqslant (k + m + t)m - km = (m + t)m&amp;lt;/tex&amp;gt;. Значит, мы можем распланировать итерации из множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; не позднее момента &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;. Таим образом, мы снова построили расписание для задачи open shop, которое так же является оптимальным, так как для множеств &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; все осталось как в оптимальном расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;, работу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; мы научились выполнять быстрее, а для множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; ответ был не ухудшен. Любая работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, итерации обработки которой принадлежат множеству &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, имела время окончания &amp;lt;tex&amp;gt;C_j \geqslant m + k + t&amp;lt;/tex&amp;gt;. Однако это противоречит тому, что мы выбрали максимальное &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;. &lt;br /&gt;
}}&lt;br /&gt;
Отсортируем работы в порядке неуменьшения дедлайнов. Для текущей работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; вычислим ''лимит'' &amp;lt;tex&amp;gt;T_i&amp;lt;/tex&amp;gt; {{---}} время, до которого закончится обработка данной работы, то есть &amp;lt;tex&amp;gt;1 \leqslant t_1 &amp;lt; t_2 &amp;lt; \ldots &amp;lt; t_m \leqslant T_i &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;t_j&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;j = 1 \ldots m&amp;lt;/tex&amp;gt; {{---}} периоды обработки работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Будем выбирать эти периоды среди моментов времени, в которые выполняется наименьшее число работ.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Определим ''вектор частот'' &amp;lt;tex&amp;gt;h[t]&amp;lt;/tex&amp;gt; {{---}} количество работ во временном интервале &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Работы отсортированы в порядке &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
   '''function''' scheduler():&lt;br /&gt;
      '''int''' &amp;lt;tex&amp;gt;h[m + n - 1]&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''vector&amp;lt;int&amp;gt;''' &amp;lt;tex&amp;gt;s[n]&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''for''' &amp;lt;tex&amp;gt;t = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt;s[t] = \varnothing&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''for''' &amp;lt;tex&amp;gt;t = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;m + n - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt;h[t] = 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''for''' &amp;lt;tex&amp;gt;i = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''if''' &amp;lt;tex&amp;gt;d_i &amp;lt; m + i - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
            вычислим &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; {{---}} количество временных интервалов &amp;lt;tex&amp;gt;t = 1 \ldots d_i&amp;lt;/tex&amp;gt;, таких, что &amp;lt;tex&amp;gt;h[t] &amp;lt; m&amp;lt;/tex&amp;gt;&lt;br /&gt;
            '''if''' &amp;lt;tex&amp;gt;z \geqslant m&amp;lt;/tex&amp;gt;&lt;br /&gt;
               &amp;lt;tex&amp;gt;T_i = d_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
            '''else''' &lt;br /&gt;
               &amp;lt;tex&amp;gt;T_i = d_i + m - z&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''else'''&lt;br /&gt;
            &amp;lt;tex&amp;gt;T_i = m + i - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
         вычислим &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; периодов &amp;lt;tex&amp;gt;1 \leqslant t_1 &amp;lt; t_2 &amp;lt; \ldots &amp;lt; t_m \leqslant T_i &amp;lt;/tex&amp;gt; с минимальными значениями &amp;lt;tex&amp;gt;h[t_j]&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''for''' &amp;lt;tex&amp;gt;j = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;&lt;br /&gt;
            &amp;lt;tex&amp;gt;s[i] =  s[i] \cup \{t_j - 1\}&amp;lt;/tex&amp;gt;         &amp;lt;font color=green&amp;gt;// ставим работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; на время &amp;lt;tex&amp;gt;[t_j - 1, t_j]&amp;lt;/tex&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
            &amp;lt;tex&amp;gt;h[t_j] = h[t_j] + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''return''' &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Асимптотика ===&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[O2Cmax|&amp;lt;tex&amp;gt;O2 \mid \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opi1sumu|&amp;lt;tex&amp;gt;O \mid p_{ij} = 1 \mid \sum U_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1di|&amp;lt;tex&amp;gt; O \mid p_{i, j} = 1, d_i \mid - &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1sumwu|&amp;lt;tex&amp;gt; O \mid p_{i, j} = 1 \mid - \sum w_{i} U_{i}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* Peter Brucker «Scheduling Algorithms», fifth edition, Springer {{---}} с. 171-174 ISBN 978-3-540-69515-8&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Opij1SumTi&amp;diff=54576</id>
		<title>Opij1SumTi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Opij1SumTi&amp;diff=54576"/>
				<updated>2016-06-05T11:26:00Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: /* Псевдокод */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; O \mid p_{i,j} = 1 \mid \sum T_{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; одинаковых станков, которые работают параллельно, и &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ, которые необходимо выполнить в произвольном порядке на всех станках. Любая работа на любом станке выполняется единицу времени. Для каждой работы есть время окончания &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; {{---}} время, до которого она должна быть выполнена. Необходимо минимизировать суммарную [[Классификация_задач#Критерий оптимизации|медлительность]].&lt;br /&gt;
}} &lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Будем полагать, что работы заданы в порядке неубывания их дедлайнов, то есть &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;. &lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть есть работы &amp;lt;tex&amp;gt;1 \ldots n&amp;lt;/tex&amp;gt; с дедлайнами &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;. Тогда существует оптимальное расписание, в котором времена завершения работ идут в том же порядке, то есть &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим две работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из какого-либо оптимального расписания такие, что &amp;lt;tex&amp;gt;C_i &amp;gt; C_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d_i &amp;lt; d_j&amp;lt;/tex&amp;gt;. Поменяем эти работы в расписании местами, то есть &amp;lt;tex&amp;gt;C'_i = C_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C'_j = C_i&amp;lt;/tex&amp;gt;. Если они обе успевали выполниться вовремя, то это свойство сохранится, так как &amp;lt;tex&amp;gt;d_i &amp;lt; d_j&amp;lt;/tex&amp;gt;, значит по-прежнему &amp;lt;tex&amp;gt;T_i = 0&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T_j = 0&amp;lt;/tex&amp;gt;, то есть значение целевой функции мы не ухудшили и расписание осталось оптимальным. Если обе работы не успевали выполниться вовремя, то когда мы поменяем их местами ничего не изменится, то есть значение целевой функции останется прежним, так как мы не меняли значения времен окончаний, а только поменяли их местами. Если работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; успевала выполниться, а  &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; {{---}} нет, то мы снова не ухудшим значение целевой функции. Покажем это. До того, как мы поменяли работы местами, было &amp;lt;tex&amp;gt;T_i + T_j = C_i - d_i&amp;lt;/tex&amp;gt;, так как &amp;lt;tex&amp;gt;T_j = 0&amp;lt;/tex&amp;gt;. После того, как мы поменяли работы местами, &amp;lt;tex&amp;gt;T_i + T_j = C'_i - d_i + C'_j - d_j =  C_j - d_i + C_i - d_j = C_i - d_i + (C_j - d_j)&amp;lt;/tex&amp;gt;. Но так как работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; успевает выполниться до дедлайна, то &amp;lt;tex&amp;gt;C_j - d_j \leqslant 0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
Далее будем рассматривать только оптимальное расписание со свойством &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Всегда существует оптимально расписание такое, что в нем &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для любого &amp;lt;tex&amp;gt;i = 1 \ldots n&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; {{---}} количество станков.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим оптимальное расписание &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;, в котором для любого &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt; выполняется &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt;, но &amp;lt;tex&amp;gt;C_k &amp;gt; m + k - 1&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; максимально среди всех возможных. Для начала покажем, что &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; не меньше &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;. Пусть есть оптимальное расписание, у которого &amp;lt;tex&amp;gt;C_1 &amp;gt; m&amp;lt;/tex&amp;gt;. Это значит, что есть период времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; такой, что первая работа выполняется в момент &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; и не выполняется в &amp;lt;tex&amp;gt;t - 1&amp;lt;/tex&amp;gt;. Поменяем эти периоды времени местами. То есть все работы, которые выполнялись в момент &amp;lt;tex&amp;gt;t - 1&amp;lt;/tex&amp;gt;, будут выполняться на тех же станках, но в момент &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, и наоборот. Значение &amp;lt;tex&amp;gt;C_i&amp;lt;/tex&amp;gt; для каждой работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; не увеличится, так как &amp;lt;tex&amp;gt;C_1&amp;lt;/tex&amp;gt; было минимальным из них, а значит ни одна работа не могла быть закончена раньше периода времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Будем продолжать этот процесс, пока не будет выполнено равенство &amp;lt;tex&amp;gt;C_1 = m&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь пусть &amp;lt;tex&amp;gt;C_k = m + k + t&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;t \geqslant 0&amp;lt;/tex&amp;gt;. Будем называть ''итерацией обработки'' работы обработку на одной машине. Разобьем все работы на три множества:&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; будет содержать все итерации обработки работ &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; {{---}} все итерации, запланированные в расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt; строго после момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; {{---}} итерации обработки работ &amp;lt;tex&amp;gt;i = k + 1 \ldots n&amp;lt;/tex&amp;gt;, которые в &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt; запланированы на время &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; и раньше&lt;br /&gt;
Таким образом, мы имеем три непересекающихся множества, которые вместе с работой &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; покрывают все итерации всех работ.&amp;lt;br&amp;gt;&lt;br /&gt;
Построим новое расписание &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;. Для начала расставим все работы из множества &amp;lt;tex&amp;gt;A \cup B&amp;lt;/tex&amp;gt; так же, как они были запланированы в расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt;, ни одна итерация обработки в множестве &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; не поставлена раньше момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; и к моменту времени &amp;lt;tex&amp;gt;C_k = m + k + t&amp;lt;/tex&amp;gt; выполнено &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ, то это значит, что между моментами времени &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k + m - 1&amp;lt;/tex&amp;gt; на каждой машине есть &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; различных простоев, то есть моментов, когда на ней ничего не обрабатывается. Значит, мы всегда сможем поставить на эти простои итерации обработки работы &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, даже если эти простои пересекаются. Таким образом, &amp;lt;tex&amp;gt;C_k \leqslant m + k - 1&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь назначим машины для операций из множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. До момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; сейчас распланировано ровно &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ, так как по определению работы из множества &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; запланированы на время строго большее &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;. Значит, между моментами времени &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; есть &amp;lt;tex&amp;gt;k + m + t - k = m + t&amp;lt;/tex&amp;gt; различных простоев на каждой машине. Исходя из определения множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; и того, что к моменту &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; распланировано &amp;lt;tex&amp;gt;km&amp;lt;/tex&amp;gt; итераций обработок, приходим к неравенству &amp;lt;tex&amp;gt;|C| \leqslant (k + m + t)m - km = (m + t)m&amp;lt;/tex&amp;gt;. Значит, мы можем распланировать итерации из множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; не позднее момента &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;. Таим образом, мы снова построили расписание для задачи open shop, которое так же является оптимальным, так как для множеств &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; все осталось как в оптимальном расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;, работу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; мы научились выполнять быстрее, а для множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; ответ был не ухудшен. Любая работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, итерации обработки которой принадлежат множеству &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, имела время окончания &amp;lt;tex&amp;gt;C_j \geqslant m + k + t&amp;lt;/tex&amp;gt;. Однако это противоречит тому, что мы выбрали максимальное &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;. &lt;br /&gt;
}}&lt;br /&gt;
Отсортируем работы в порядке неуменьшения дедлайнов. Для текущей работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; вычислим ''лимит'' &amp;lt;tex&amp;gt;T_i&amp;lt;/tex&amp;gt; {{---}} время, до которого закончится обработка данной работы, то есть &amp;lt;tex&amp;gt;1 \leqslant t_1 &amp;lt; t_2 &amp;lt; \ldots &amp;lt; t_m \leqslant T_i &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;t_j&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;j = 1 \ldots m&amp;lt;/tex&amp;gt; {{---}} периоды обработки работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Будем выбирать эти периоды среди моментов времени, в которые выполняется наименьшее число работ.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Определим ''вектор частот'' &amp;lt;tex&amp;gt;h[t]&amp;lt;/tex&amp;gt; {{---}} количество работ во временном интервале &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Работы отсортированы в порядке &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
   '''function''' scheduler():&lt;br /&gt;
      '''int''' &amp;lt;tex&amp;gt;h[m + n]&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''vector&amp;lt;int&amp;gt;''' &amp;lt;tex&amp;gt;s[n]&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''for''' &amp;lt;tex&amp;gt;t = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt;s[t] = \varnothing&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''for''' &amp;lt;tex&amp;gt;t = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;m + n - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt;h[t] = 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''for''' &amp;lt;tex&amp;gt;i = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''if''' &amp;lt;tex&amp;gt;d_i &amp;lt; m + i - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
            вычислим &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; {{---}} количество временных интервалов &amp;lt;tex&amp;gt;t = 1 \ldots d_i&amp;lt;/tex&amp;gt;, таких, что &amp;lt;tex&amp;gt;h[t] &amp;lt; m&amp;lt;/tex&amp;gt;&lt;br /&gt;
            '''if''' &amp;lt;tex&amp;gt;z \geqslant m&amp;lt;/tex&amp;gt;&lt;br /&gt;
               &amp;lt;tex&amp;gt;T_i = d_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
            '''else''' &lt;br /&gt;
               &amp;lt;tex&amp;gt;T_i = d_i + m - z&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''else'''&lt;br /&gt;
            &amp;lt;tex&amp;gt;T_i = m + i - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
         вычислим &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; периодов &amp;lt;tex&amp;gt;1 \leqslant t_1 &amp;lt; t_2 &amp;lt; \ldots &amp;lt; t_m \leqslant T_i &amp;lt;/tex&amp;gt; с минимальными значениями &amp;lt;tex&amp;gt;h[t_j]&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''for''' &amp;lt;tex&amp;gt;j = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;&lt;br /&gt;
            &amp;lt;tex&amp;gt;s[i] =  s[i] \cup \{t_j - 1\}&amp;lt;/tex&amp;gt;         &amp;lt;font color=green&amp;gt;// ставим работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; на время &amp;lt;tex&amp;gt;[t_j - 1, t_j]&amp;lt;/tex&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
            &amp;lt;tex&amp;gt;h[t_j] = h[t_j] + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''return''' &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Асимптотика ===&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[O2Cmax|&amp;lt;tex&amp;gt;O2 \mid \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opi1sumu|&amp;lt;tex&amp;gt;O \mid p_{ij} = 1 \mid \sum U_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1di|&amp;lt;tex&amp;gt; O \mid p_{i, j} = 1, d_i \mid - &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1sumwu|&amp;lt;tex&amp;gt; O \mid p_{i, j} = 1 \mid - \sum w_{i} U_{i}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* Peter Brucker «Scheduling Algorithms», fifth edition, Springer {{---}} с. 171-174 ISBN 978-3-540-69515-8&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Opij1SumTi&amp;diff=54575</id>
		<title>Opij1SumTi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Opij1SumTi&amp;diff=54575"/>
				<updated>2016-06-05T11:17:46Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: /* Псевдокод */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; O \mid p_{i,j} = 1 \mid \sum T_{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; одинаковых станков, которые работают параллельно, и &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ, которые необходимо выполнить в произвольном порядке на всех станках. Любая работа на любом станке выполняется единицу времени. Для каждой работы есть время окончания &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; {{---}} время, до которого она должна быть выполнена. Необходимо минимизировать суммарную [[Классификация_задач#Критерий оптимизации|медлительность]].&lt;br /&gt;
}} &lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Будем полагать, что работы заданы в порядке неубывания их дедлайнов, то есть &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;. &lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть есть работы &amp;lt;tex&amp;gt;1 \ldots n&amp;lt;/tex&amp;gt; с дедлайнами &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;. Тогда существует оптимальное расписание, в котором времена завершения работ идут в том же порядке, то есть &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим две работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из какого-либо оптимального расписания такие, что &amp;lt;tex&amp;gt;C_i &amp;gt; C_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d_i &amp;lt; d_j&amp;lt;/tex&amp;gt;. Поменяем эти работы в расписании местами, то есть &amp;lt;tex&amp;gt;C'_i = C_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C'_j = C_i&amp;lt;/tex&amp;gt;. Если они обе успевали выполниться вовремя, то это свойство сохранится, так как &amp;lt;tex&amp;gt;d_i &amp;lt; d_j&amp;lt;/tex&amp;gt;, значит по-прежнему &amp;lt;tex&amp;gt;T_i = 0&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T_j = 0&amp;lt;/tex&amp;gt;, то есть значение целевой функции мы не ухудшили и расписание осталось оптимальным. Если обе работы не успевали выполниться вовремя, то когда мы поменяем их местами ничего не изменится, то есть значение целевой функции останется прежним, так как мы не меняли значения времен окончаний, а только поменяли их местами. Если работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; успевала выполниться, а  &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; {{---}} нет, то мы снова не ухудшим значение целевой функции. Покажем это. До того, как мы поменяли работы местами, было &amp;lt;tex&amp;gt;T_i + T_j = C_i - d_i&amp;lt;/tex&amp;gt;, так как &amp;lt;tex&amp;gt;T_j = 0&amp;lt;/tex&amp;gt;. После того, как мы поменяли работы местами, &amp;lt;tex&amp;gt;T_i + T_j = C'_i - d_i + C'_j - d_j =  C_j - d_i + C_i - d_j = C_i - d_i + (C_j - d_j)&amp;lt;/tex&amp;gt;. Но так как работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; успевает выполниться до дедлайна, то &amp;lt;tex&amp;gt;C_j - d_j \leqslant 0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
Далее будем рассматривать только оптимальное расписание со свойством &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Всегда существует оптимально расписание такое, что в нем &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для любого &amp;lt;tex&amp;gt;i = 1 \ldots n&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; {{---}} количество станков.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим оптимальное расписание &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;, в котором для любого &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt; выполняется &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt;, но &amp;lt;tex&amp;gt;C_k &amp;gt; m + k - 1&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; максимально среди всех возможных. Для начала покажем, что &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; не меньше &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;. Пусть есть оптимальное расписание, у которого &amp;lt;tex&amp;gt;C_1 &amp;gt; m&amp;lt;/tex&amp;gt;. Это значит, что есть период времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; такой, что первая работа выполняется в момент &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; и не выполняется в &amp;lt;tex&amp;gt;t - 1&amp;lt;/tex&amp;gt;. Поменяем эти периоды времени местами. То есть все работы, которые выполнялись в момент &amp;lt;tex&amp;gt;t - 1&amp;lt;/tex&amp;gt;, будут выполняться на тех же станках, но в момент &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, и наоборот. Значение &amp;lt;tex&amp;gt;C_i&amp;lt;/tex&amp;gt; для каждой работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; не увеличится, так как &amp;lt;tex&amp;gt;C_1&amp;lt;/tex&amp;gt; было минимальным из них, а значит ни одна работа не могла быть закончена раньше периода времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Будем продолжать этот процесс, пока не будет выполнено равенство &amp;lt;tex&amp;gt;C_1 = m&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь пусть &amp;lt;tex&amp;gt;C_k = m + k + t&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;t \geqslant 0&amp;lt;/tex&amp;gt;. Будем называть ''итерацией обработки'' работы обработку на одной машине. Разобьем все работы на три множества:&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; будет содержать все итерации обработки работ &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; {{---}} все итерации, запланированные в расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt; строго после момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; {{---}} итерации обработки работ &amp;lt;tex&amp;gt;i = k + 1 \ldots n&amp;lt;/tex&amp;gt;, которые в &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt; запланированы на время &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; и раньше&lt;br /&gt;
Таким образом, мы имеем три непересекающихся множества, которые вместе с работой &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; покрывают все итерации всех работ.&amp;lt;br&amp;gt;&lt;br /&gt;
Построим новое расписание &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;. Для начала расставим все работы из множества &amp;lt;tex&amp;gt;A \cup B&amp;lt;/tex&amp;gt; так же, как они были запланированы в расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt;, ни одна итерация обработки в множестве &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; не поставлена раньше момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; и к моменту времени &amp;lt;tex&amp;gt;C_k = m + k + t&amp;lt;/tex&amp;gt; выполнено &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ, то это значит, что между моментами времени &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k + m - 1&amp;lt;/tex&amp;gt; на каждой машине есть &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; различных простоев, то есть моментов, когда на ней ничего не обрабатывается. Значит, мы всегда сможем поставить на эти простои итерации обработки работы &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, даже если эти простои пересекаются. Таким образом, &amp;lt;tex&amp;gt;C_k \leqslant m + k - 1&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь назначим машины для операций из множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. До момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; сейчас распланировано ровно &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ, так как по определению работы из множества &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; запланированы на время строго большее &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;. Значит, между моментами времени &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; есть &amp;lt;tex&amp;gt;k + m + t - k = m + t&amp;lt;/tex&amp;gt; различных простоев на каждой машине. Исходя из определения множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; и того, что к моменту &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; распланировано &amp;lt;tex&amp;gt;km&amp;lt;/tex&amp;gt; итераций обработок, приходим к неравенству &amp;lt;tex&amp;gt;|C| \leqslant (k + m + t)m - km = (m + t)m&amp;lt;/tex&amp;gt;. Значит, мы можем распланировать итерации из множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; не позднее момента &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;. Таим образом, мы снова построили расписание для задачи open shop, которое так же является оптимальным, так как для множеств &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; все осталось как в оптимальном расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;, работу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; мы научились выполнять быстрее, а для множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; ответ был не ухудшен. Любая работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, итерации обработки которой принадлежат множеству &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, имела время окончания &amp;lt;tex&amp;gt;C_j \geqslant m + k + t&amp;lt;/tex&amp;gt;. Однако это противоречит тому, что мы выбрали максимальное &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;. &lt;br /&gt;
}}&lt;br /&gt;
Отсортируем работы в порядке неуменьшения дедлайнов. Для текущей работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; вычислим ''лимит'' &amp;lt;tex&amp;gt;T_i&amp;lt;/tex&amp;gt; {{---}} время, до которого закончится обработка данной работы, то есть &amp;lt;tex&amp;gt;1 \leqslant t_1 &amp;lt; t_2 &amp;lt; \ldots &amp;lt; t_m \leqslant T_i &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;t_j&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;j = 1 \ldots m&amp;lt;/tex&amp;gt; {{---}} периоды обработки работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Будем выбирать эти периоды среди моментов времени, в которые выполняется наименьшее число работ.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Определим ''вектор частот'' &amp;lt;tex&amp;gt;h(t)&amp;lt;/tex&amp;gt; {{---}} количество работ во временном интервале &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Работы отсортированы в порядке &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
   '''function''' &amp;lt;tex&amp;gt;\mathrm{Scheduller}():&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''int''' &amp;lt;tex&amp;gt;h[]&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''vector&amp;lt;int&amp;gt;''' &amp;lt;tex&amp;gt;s[]&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''for''' &amp;lt;tex&amp;gt;t = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt;s[t] = \varnothing&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''for''' &amp;lt;tex&amp;gt;t = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;m + n - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt;h[t] = 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''for''' &amp;lt;tex&amp;gt;i = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''if''' &amp;lt;tex&amp;gt;d_i &amp;lt; m + i - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
            вычислим &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; {{---}} количество временных интервалов &amp;lt;tex&amp;gt;t = 1 \ldots d_i&amp;lt;/tex&amp;gt;, таких, что &amp;lt;tex&amp;gt;h[t] &amp;lt; m&amp;lt;/tex&amp;gt;&lt;br /&gt;
            '''if''' &amp;lt;tex&amp;gt;z \geqslant m&amp;lt;/tex&amp;gt;&lt;br /&gt;
               &amp;lt;tex&amp;gt;T_i = d_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
            '''else''' &lt;br /&gt;
               &amp;lt;tex&amp;gt;T_i = d_i + m - z&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''else'''&lt;br /&gt;
            &amp;lt;tex&amp;gt;T_i = m + i - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
         вычислим &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; периодов &amp;lt;tex&amp;gt;1 \leqslant t_1 &amp;lt; t_2 &amp;lt; \ldots &amp;lt; t_m \leqslant T_i &amp;lt;/tex&amp;gt; с минимальными значениями &amp;lt;tex&amp;gt;h[t_j]&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''for''' &amp;lt;tex&amp;gt;j = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;&lt;br /&gt;
            &amp;lt;tex&amp;gt;s[i] =  s[i] \cup \{t_j - 1\}&amp;lt;/tex&amp;gt;         &amp;lt;font color=green&amp;gt;// ставим работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; на время &amp;lt;tex&amp;gt;[t_j - 1, t_j]&amp;lt;/tex&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
            &amp;lt;tex&amp;gt;h[t_j] = h[t_j] + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''return''' &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Асимптотика ===&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[O2Cmax|&amp;lt;tex&amp;gt;O2 \mid \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opi1sumu|&amp;lt;tex&amp;gt;O \mid p_{ij} = 1 \mid \sum U_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1di|&amp;lt;tex&amp;gt; O \mid p_{i, j} = 1, d_i \mid - &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1sumwu|&amp;lt;tex&amp;gt; O \mid p_{i, j} = 1 \mid - \sum w_{i} U_{i}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* Peter Brucker «Scheduling Algorithms», fifth edition, Springer {{---}} с. 171-174 ISBN 978-3-540-69515-8&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Opij1SumTi&amp;diff=54574</id>
		<title>Opij1SumTi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Opij1SumTi&amp;diff=54574"/>
				<updated>2016-06-05T11:11:39Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: /* Псевдокод */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; O \mid p_{i,j} = 1 \mid \sum T_{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; одинаковых станков, которые работают параллельно, и &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ, которые необходимо выполнить в произвольном порядке на всех станках. Любая работа на любом станке выполняется единицу времени. Для каждой работы есть время окончания &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; {{---}} время, до которого она должна быть выполнена. Необходимо минимизировать суммарную [[Классификация_задач#Критерий оптимизации|медлительность]].&lt;br /&gt;
}} &lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Будем полагать, что работы заданы в порядке неубывания их дедлайнов, то есть &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;. &lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть есть работы &amp;lt;tex&amp;gt;1 \ldots n&amp;lt;/tex&amp;gt; с дедлайнами &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;. Тогда существует оптимальное расписание, в котором времена завершения работ идут в том же порядке, то есть &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим две работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из какого-либо оптимального расписания такие, что &amp;lt;tex&amp;gt;C_i &amp;gt; C_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d_i &amp;lt; d_j&amp;lt;/tex&amp;gt;. Поменяем эти работы в расписании местами, то есть &amp;lt;tex&amp;gt;C'_i = C_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C'_j = C_i&amp;lt;/tex&amp;gt;. Если они обе успевали выполниться вовремя, то это свойство сохранится, так как &amp;lt;tex&amp;gt;d_i &amp;lt; d_j&amp;lt;/tex&amp;gt;, значит по-прежнему &amp;lt;tex&amp;gt;T_i = 0&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T_j = 0&amp;lt;/tex&amp;gt;, то есть значение целевой функции мы не ухудшили и расписание осталось оптимальным. Если обе работы не успевали выполниться вовремя, то когда мы поменяем их местами ничего не изменится, то есть значение целевой функции останется прежним, так как мы не меняли значения времен окончаний, а только поменяли их местами. Если работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; успевала выполниться, а  &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; {{---}} нет, то мы снова не ухудшим значение целевой функции. Покажем это. До того, как мы поменяли работы местами, было &amp;lt;tex&amp;gt;T_i + T_j = C_i - d_i&amp;lt;/tex&amp;gt;, так как &amp;lt;tex&amp;gt;T_j = 0&amp;lt;/tex&amp;gt;. После того, как мы поменяли работы местами, &amp;lt;tex&amp;gt;T_i + T_j = C'_i - d_i + C'_j - d_j =  C_j - d_i + C_i - d_j = C_i - d_i + (C_j - d_j)&amp;lt;/tex&amp;gt;. Но так как работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; успевает выполниться до дедлайна, то &amp;lt;tex&amp;gt;C_j - d_j \leqslant 0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
Далее будем рассматривать только оптимальное расписание со свойством &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Всегда существует оптимально расписание такое, что в нем &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для любого &amp;lt;tex&amp;gt;i = 1 \ldots n&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; {{---}} количество станков.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим оптимальное расписание &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;, в котором для любого &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt; выполняется &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt;, но &amp;lt;tex&amp;gt;C_k &amp;gt; m + k - 1&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; максимально среди всех возможных. Для начала покажем, что &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; не меньше &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;. Пусть есть оптимальное расписание, у которого &amp;lt;tex&amp;gt;C_1 &amp;gt; m&amp;lt;/tex&amp;gt;. Это значит, что есть период времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; такой, что первая работа выполняется в момент &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; и не выполняется в &amp;lt;tex&amp;gt;t - 1&amp;lt;/tex&amp;gt;. Поменяем эти периоды времени местами. То есть все работы, которые выполнялись в момент &amp;lt;tex&amp;gt;t - 1&amp;lt;/tex&amp;gt;, будут выполняться на тех же станках, но в момент &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, и наоборот. Значение &amp;lt;tex&amp;gt;C_i&amp;lt;/tex&amp;gt; для каждой работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; не увеличится, так как &amp;lt;tex&amp;gt;C_1&amp;lt;/tex&amp;gt; было минимальным из них, а значит ни одна работа не могла быть закончена раньше периода времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Будем продолжать этот процесс, пока не будет выполнено равенство &amp;lt;tex&amp;gt;C_1 = m&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь пусть &amp;lt;tex&amp;gt;C_k = m + k + t&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;t \geqslant 0&amp;lt;/tex&amp;gt;. Будем называть ''итерацией обработки'' работы обработку на одной машине. Разобьем все работы на три множества:&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; будет содержать все итерации обработки работ &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; {{---}} все итерации, запланированные в расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt; строго после момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; {{---}} итерации обработки работ &amp;lt;tex&amp;gt;i = k + 1 \ldots n&amp;lt;/tex&amp;gt;, которые в &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt; запланированы на время &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; и раньше&lt;br /&gt;
Таким образом, мы имеем три непересекающихся множества, которые вместе с работой &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; покрывают все итерации всех работ.&amp;lt;br&amp;gt;&lt;br /&gt;
Построим новое расписание &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;. Для начала расставим все работы из множества &amp;lt;tex&amp;gt;A \cup B&amp;lt;/tex&amp;gt; так же, как они были запланированы в расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt;, ни одна итерация обработки в множестве &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; не поставлена раньше момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; и к моменту времени &amp;lt;tex&amp;gt;C_k = m + k + t&amp;lt;/tex&amp;gt; выполнено &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ, то это значит, что между моментами времени &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k + m - 1&amp;lt;/tex&amp;gt; на каждой машине есть &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; различных простоев, то есть моментов, когда на ней ничего не обрабатывается. Значит, мы всегда сможем поставить на эти простои итерации обработки работы &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, даже если эти простои пересекаются. Таким образом, &amp;lt;tex&amp;gt;C_k \leqslant m + k - 1&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь назначим машины для операций из множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. До момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; сейчас распланировано ровно &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ, так как по определению работы из множества &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; запланированы на время строго большее &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;. Значит, между моментами времени &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; есть &amp;lt;tex&amp;gt;k + m + t - k = m + t&amp;lt;/tex&amp;gt; различных простоев на каждой машине. Исходя из определения множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; и того, что к моменту &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; распланировано &amp;lt;tex&amp;gt;km&amp;lt;/tex&amp;gt; итераций обработок, приходим к неравенству &amp;lt;tex&amp;gt;|C| \leqslant (k + m + t)m - km = (m + t)m&amp;lt;/tex&amp;gt;. Значит, мы можем распланировать итерации из множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; не позднее момента &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;. Таим образом, мы снова построили расписание для задачи open shop, которое так же является оптимальным, так как для множеств &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; все осталось как в оптимальном расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;, работу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; мы научились выполнять быстрее, а для множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; ответ был не ухудшен. Любая работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, итерации обработки которой принадлежат множеству &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, имела время окончания &amp;lt;tex&amp;gt;C_j \geqslant m + k + t&amp;lt;/tex&amp;gt;. Однако это противоречит тому, что мы выбрали максимальное &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;. &lt;br /&gt;
}}&lt;br /&gt;
Отсортируем работы в порядке неуменьшения дедлайнов. Для текущей работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; вычислим ''лимит'' &amp;lt;tex&amp;gt;T_i&amp;lt;/tex&amp;gt; {{---}} время, до которого закончится обработка данной работы, то есть &amp;lt;tex&amp;gt;1 \leqslant t_1 &amp;lt; t_2 &amp;lt; \ldots &amp;lt; t_m \leqslant T_i &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;t_j&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;j = 1 \ldots m&amp;lt;/tex&amp;gt; {{---}} периоды обработки работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Будем выбирать эти периоды среди моментов времени, в которые выполняется наименьшее число работ.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Определим ''вектор частот'' &amp;lt;tex&amp;gt;h(t)&amp;lt;/tex&amp;gt; {{---}} количество работ во временном интервале &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Работы отсортированы в порядке &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
   '''function''' &amp;lt;tex&amp;gt;\mathrm{Scheduller}():&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''int''' &amp;lt;tex&amp;gt;h[]&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''vector&amp;lt;int&amp;gt;''' &amp;lt;tex&amp;gt;s[]&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for''' &amp;lt;tex&amp;gt;t = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt;s[t] = \varnothing&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for''' &amp;lt;tex&amp;gt;t = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;m + n - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt;h[t] = 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for''' &amp;lt;tex&amp;gt;i = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt;d_i &amp;lt; m + i - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
         вычислим &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; {{---}} количество временных интервалов &amp;lt;tex&amp;gt;t = 1 \ldots d_i&amp;lt;/tex&amp;gt;, таких, что &amp;lt;tex&amp;gt;h[t] &amp;lt; m&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''if''' &amp;lt;tex&amp;gt;z \geqslant m&amp;lt;/tex&amp;gt;&lt;br /&gt;
            &amp;lt;tex&amp;gt;T_i = d_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''else''' &lt;br /&gt;
            &amp;lt;tex&amp;gt;T_i = d_i + m - z&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''else'''&lt;br /&gt;
         &amp;lt;tex&amp;gt;T_i = m + i - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
      вычислим &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; периодов &amp;lt;tex&amp;gt;1 \leqslant t_1 &amp;lt; t_2 &amp;lt; \ldots &amp;lt; t_m \leqslant T_i &amp;lt;/tex&amp;gt; с минимальными значениями &amp;lt;tex&amp;gt;h[t_j]&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''for''' &amp;lt;tex&amp;gt;j = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt;s[i] =  s[i] \cup \{t_j - 1\}&amp;lt;/tex&amp;gt;         &amp;lt;font color=green&amp;gt;// ставим работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; на время &amp;lt;tex&amp;gt;[t_j - 1, t_j]&amp;lt;/tex&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt;h[t_j] = h[t_j] + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''return''' &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Асимптотика ===&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[O2Cmax|&amp;lt;tex&amp;gt;O2 \mid \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opi1sumu|&amp;lt;tex&amp;gt;O \mid p_{ij} = 1 \mid \sum U_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1di|&amp;lt;tex&amp;gt; O \mid p_{i, j} = 1, d_i \mid - &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1sumwu|&amp;lt;tex&amp;gt; O \mid p_{i, j} = 1 \mid - \sum w_{i} U_{i}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* Peter Brucker «Scheduling Algorithms», fifth edition, Springer {{---}} с. 171-174 ISBN 978-3-540-69515-8&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Opij1SumTi&amp;diff=54573</id>
		<title>Opij1SumTi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Opij1SumTi&amp;diff=54573"/>
				<updated>2016-06-05T11:10:51Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: /* Псевдокод */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; O \mid p_{i,j} = 1 \mid \sum T_{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; одинаковых станков, которые работают параллельно, и &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ, которые необходимо выполнить в произвольном порядке на всех станках. Любая работа на любом станке выполняется единицу времени. Для каждой работы есть время окончания &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; {{---}} время, до которого она должна быть выполнена. Необходимо минимизировать суммарную [[Классификация_задач#Критерий оптимизации|медлительность]].&lt;br /&gt;
}} &lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Будем полагать, что работы заданы в порядке неубывания их дедлайнов, то есть &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;. &lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть есть работы &amp;lt;tex&amp;gt;1 \ldots n&amp;lt;/tex&amp;gt; с дедлайнами &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;. Тогда существует оптимальное расписание, в котором времена завершения работ идут в том же порядке, то есть &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим две работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из какого-либо оптимального расписания такие, что &amp;lt;tex&amp;gt;C_i &amp;gt; C_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d_i &amp;lt; d_j&amp;lt;/tex&amp;gt;. Поменяем эти работы в расписании местами, то есть &amp;lt;tex&amp;gt;C'_i = C_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C'_j = C_i&amp;lt;/tex&amp;gt;. Если они обе успевали выполниться вовремя, то это свойство сохранится, так как &amp;lt;tex&amp;gt;d_i &amp;lt; d_j&amp;lt;/tex&amp;gt;, значит по-прежнему &amp;lt;tex&amp;gt;T_i = 0&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T_j = 0&amp;lt;/tex&amp;gt;, то есть значение целевой функции мы не ухудшили и расписание осталось оптимальным. Если обе работы не успевали выполниться вовремя, то когда мы поменяем их местами ничего не изменится, то есть значение целевой функции останется прежним, так как мы не меняли значения времен окончаний, а только поменяли их местами. Если работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; успевала выполниться, а  &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; {{---}} нет, то мы снова не ухудшим значение целевой функции. Покажем это. До того, как мы поменяли работы местами, было &amp;lt;tex&amp;gt;T_i + T_j = C_i - d_i&amp;lt;/tex&amp;gt;, так как &amp;lt;tex&amp;gt;T_j = 0&amp;lt;/tex&amp;gt;. После того, как мы поменяли работы местами, &amp;lt;tex&amp;gt;T_i + T_j = C'_i - d_i + C'_j - d_j =  C_j - d_i + C_i - d_j = C_i - d_i + (C_j - d_j)&amp;lt;/tex&amp;gt;. Но так как работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; успевает выполниться до дедлайна, то &amp;lt;tex&amp;gt;C_j - d_j \leqslant 0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
Далее будем рассматривать только оптимальное расписание со свойством &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Всегда существует оптимально расписание такое, что в нем &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для любого &amp;lt;tex&amp;gt;i = 1 \ldots n&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; {{---}} количество станков.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим оптимальное расписание &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;, в котором для любого &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt; выполняется &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt;, но &amp;lt;tex&amp;gt;C_k &amp;gt; m + k - 1&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; максимально среди всех возможных. Для начала покажем, что &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; не меньше &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;. Пусть есть оптимальное расписание, у которого &amp;lt;tex&amp;gt;C_1 &amp;gt; m&amp;lt;/tex&amp;gt;. Это значит, что есть период времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; такой, что первая работа выполняется в момент &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; и не выполняется в &amp;lt;tex&amp;gt;t - 1&amp;lt;/tex&amp;gt;. Поменяем эти периоды времени местами. То есть все работы, которые выполнялись в момент &amp;lt;tex&amp;gt;t - 1&amp;lt;/tex&amp;gt;, будут выполняться на тех же станках, но в момент &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, и наоборот. Значение &amp;lt;tex&amp;gt;C_i&amp;lt;/tex&amp;gt; для каждой работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; не увеличится, так как &amp;lt;tex&amp;gt;C_1&amp;lt;/tex&amp;gt; было минимальным из них, а значит ни одна работа не могла быть закончена раньше периода времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Будем продолжать этот процесс, пока не будет выполнено равенство &amp;lt;tex&amp;gt;C_1 = m&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь пусть &amp;lt;tex&amp;gt;C_k = m + k + t&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;t \geqslant 0&amp;lt;/tex&amp;gt;. Будем называть ''итерацией обработки'' работы обработку на одной машине. Разобьем все работы на три множества:&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; будет содержать все итерации обработки работ &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; {{---}} все итерации, запланированные в расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt; строго после момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; {{---}} итерации обработки работ &amp;lt;tex&amp;gt;i = k + 1 \ldots n&amp;lt;/tex&amp;gt;, которые в &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt; запланированы на время &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; и раньше&lt;br /&gt;
Таким образом, мы имеем три непересекающихся множества, которые вместе с работой &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; покрывают все итерации всех работ.&amp;lt;br&amp;gt;&lt;br /&gt;
Построим новое расписание &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;. Для начала расставим все работы из множества &amp;lt;tex&amp;gt;A \cup B&amp;lt;/tex&amp;gt; так же, как они были запланированы в расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt;, ни одна итерация обработки в множестве &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; не поставлена раньше момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; и к моменту времени &amp;lt;tex&amp;gt;C_k = m + k + t&amp;lt;/tex&amp;gt; выполнено &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ, то это значит, что между моментами времени &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k + m - 1&amp;lt;/tex&amp;gt; на каждой машине есть &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; различных простоев, то есть моментов, когда на ней ничего не обрабатывается. Значит, мы всегда сможем поставить на эти простои итерации обработки работы &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, даже если эти простои пересекаются. Таким образом, &amp;lt;tex&amp;gt;C_k \leqslant m + k - 1&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь назначим машины для операций из множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. До момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; сейчас распланировано ровно &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ, так как по определению работы из множества &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; запланированы на время строго большее &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;. Значит, между моментами времени &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; есть &amp;lt;tex&amp;gt;k + m + t - k = m + t&amp;lt;/tex&amp;gt; различных простоев на каждой машине. Исходя из определения множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; и того, что к моменту &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; распланировано &amp;lt;tex&amp;gt;km&amp;lt;/tex&amp;gt; итераций обработок, приходим к неравенству &amp;lt;tex&amp;gt;|C| \leqslant (k + m + t)m - km = (m + t)m&amp;lt;/tex&amp;gt;. Значит, мы можем распланировать итерации из множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; не позднее момента &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;. Таим образом, мы снова построили расписание для задачи open shop, которое так же является оптимальным, так как для множеств &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; все осталось как в оптимальном расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;, работу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; мы научились выполнять быстрее, а для множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; ответ был не ухудшен. Любая работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, итерации обработки которой принадлежат множеству &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, имела время окончания &amp;lt;tex&amp;gt;C_j \geqslant m + k + t&amp;lt;/tex&amp;gt;. Однако это противоречит тому, что мы выбрали максимальное &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;. &lt;br /&gt;
}}&lt;br /&gt;
Отсортируем работы в порядке неуменьшения дедлайнов. Для текущей работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; вычислим ''лимит'' &amp;lt;tex&amp;gt;T_i&amp;lt;/tex&amp;gt; {{---}} время, до которого закончится обработка данной работы, то есть &amp;lt;tex&amp;gt;1 \leqslant t_1 &amp;lt; t_2 &amp;lt; \ldots &amp;lt; t_m \leqslant T_i &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;t_j&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;j = 1 \ldots m&amp;lt;/tex&amp;gt; {{---}} периоды обработки работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Будем выбирать эти периоды среди моментов времени, в которые выполняется наименьшее число работ.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Определим ''вектор частот'' &amp;lt;tex&amp;gt;h(t)&amp;lt;/tex&amp;gt; {{---}} количество работ во временном интервале &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Работы отсортированы в порядке &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
   '''function''' &amp;lt;tex&amp;gt;\mathrm{Scheduller}():&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''int''' &amp;lt;tex&amp;gt;h[]&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''vector&amp;lt;int&amp;gt;''' &amp;lt;tex&amp;gt;s[]&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for''' &amp;lt;tex&amp;gt;t = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt;s[t] = \varnothing&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for''' &amp;lt;tex&amp;gt;t = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;m + n - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt;h[t] = 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for''' &amp;lt;tex&amp;gt;i = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt;d_i &amp;lt; m + i - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
         вычислим &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; {{---}} количество временных интервалов &amp;lt;tex&amp;gt;t = 1 \ldots d_i&amp;lt;/tex&amp;gt;, таких, что &amp;lt;tex&amp;gt;h[t] &amp;lt; m&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''if''' &amp;lt;tex&amp;gt;z \geqslant m&amp;lt;/tex&amp;gt;&lt;br /&gt;
            &amp;lt;tex&amp;gt;T_i = d_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''else''' &lt;br /&gt;
            &amp;lt;tex&amp;gt;T_i = d_i + m - z&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''else'''&lt;br /&gt;
         &amp;lt;tex&amp;gt;T_i = m + i - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
      вычислим &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; периодов &amp;lt;tex&amp;gt;1 \leqslant t_1 &amp;lt; t_2 &amp;lt; \ldots &amp;lt; t_m \leqslant T_i &amp;lt;/tex&amp;gt; с минимальными значениями &amp;lt;tex&amp;gt;h(t_j)&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''for''' &amp;lt;tex&amp;gt;j = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt;s[i] =  s[i] \cup \{t_j - 1\}&amp;lt;/tex&amp;gt;         &amp;lt;font color=green&amp;gt;// ставим работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; на время &amp;lt;tex&amp;gt;[t_j - 1, t_j]&amp;lt;/tex&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt;h[t_j] = h[t_j] + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''return''' &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Асимптотика ===&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[O2Cmax|&amp;lt;tex&amp;gt;O2 \mid \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opi1sumu|&amp;lt;tex&amp;gt;O \mid p_{ij} = 1 \mid \sum U_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1di|&amp;lt;tex&amp;gt; O \mid p_{i, j} = 1, d_i \mid - &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1sumwu|&amp;lt;tex&amp;gt; O \mid p_{i, j} = 1 \mid - \sum w_{i} U_{i}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* Peter Brucker «Scheduling Algorithms», fifth edition, Springer {{---}} с. 171-174 ISBN 978-3-540-69515-8&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Opij1SumTi&amp;diff=54572</id>
		<title>Opij1SumTi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Opij1SumTi&amp;diff=54572"/>
				<updated>2016-06-05T11:10:08Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: /* Псевдокод */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; O \mid p_{i,j} = 1 \mid \sum T_{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; одинаковых станков, которые работают параллельно, и &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ, которые необходимо выполнить в произвольном порядке на всех станках. Любая работа на любом станке выполняется единицу времени. Для каждой работы есть время окончания &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; {{---}} время, до которого она должна быть выполнена. Необходимо минимизировать суммарную [[Классификация_задач#Критерий оптимизации|медлительность]].&lt;br /&gt;
}} &lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Будем полагать, что работы заданы в порядке неубывания их дедлайнов, то есть &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;. &lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть есть работы &amp;lt;tex&amp;gt;1 \ldots n&amp;lt;/tex&amp;gt; с дедлайнами &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;. Тогда существует оптимальное расписание, в котором времена завершения работ идут в том же порядке, то есть &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим две работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из какого-либо оптимального расписания такие, что &amp;lt;tex&amp;gt;C_i &amp;gt; C_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d_i &amp;lt; d_j&amp;lt;/tex&amp;gt;. Поменяем эти работы в расписании местами, то есть &amp;lt;tex&amp;gt;C'_i = C_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C'_j = C_i&amp;lt;/tex&amp;gt;. Если они обе успевали выполниться вовремя, то это свойство сохранится, так как &amp;lt;tex&amp;gt;d_i &amp;lt; d_j&amp;lt;/tex&amp;gt;, значит по-прежнему &amp;lt;tex&amp;gt;T_i = 0&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T_j = 0&amp;lt;/tex&amp;gt;, то есть значение целевой функции мы не ухудшили и расписание осталось оптимальным. Если обе работы не успевали выполниться вовремя, то когда мы поменяем их местами ничего не изменится, то есть значение целевой функции останется прежним, так как мы не меняли значения времен окончаний, а только поменяли их местами. Если работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; успевала выполниться, а  &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; {{---}} нет, то мы снова не ухудшим значение целевой функции. Покажем это. До того, как мы поменяли работы местами, было &amp;lt;tex&amp;gt;T_i + T_j = C_i - d_i&amp;lt;/tex&amp;gt;, так как &amp;lt;tex&amp;gt;T_j = 0&amp;lt;/tex&amp;gt;. После того, как мы поменяли работы местами, &amp;lt;tex&amp;gt;T_i + T_j = C'_i - d_i + C'_j - d_j =  C_j - d_i + C_i - d_j = C_i - d_i + (C_j - d_j)&amp;lt;/tex&amp;gt;. Но так как работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; успевает выполниться до дедлайна, то &amp;lt;tex&amp;gt;C_j - d_j \leqslant 0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
Далее будем рассматривать только оптимальное расписание со свойством &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Всегда существует оптимально расписание такое, что в нем &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для любого &amp;lt;tex&amp;gt;i = 1 \ldots n&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; {{---}} количество станков.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим оптимальное расписание &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;, в котором для любого &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt; выполняется &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt;, но &amp;lt;tex&amp;gt;C_k &amp;gt; m + k - 1&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; максимально среди всех возможных. Для начала покажем, что &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; не меньше &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;. Пусть есть оптимальное расписание, у которого &amp;lt;tex&amp;gt;C_1 &amp;gt; m&amp;lt;/tex&amp;gt;. Это значит, что есть период времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; такой, что первая работа выполняется в момент &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; и не выполняется в &amp;lt;tex&amp;gt;t - 1&amp;lt;/tex&amp;gt;. Поменяем эти периоды времени местами. То есть все работы, которые выполнялись в момент &amp;lt;tex&amp;gt;t - 1&amp;lt;/tex&amp;gt;, будут выполняться на тех же станках, но в момент &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, и наоборот. Значение &amp;lt;tex&amp;gt;C_i&amp;lt;/tex&amp;gt; для каждой работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; не увеличится, так как &amp;lt;tex&amp;gt;C_1&amp;lt;/tex&amp;gt; было минимальным из них, а значит ни одна работа не могла быть закончена раньше периода времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Будем продолжать этот процесс, пока не будет выполнено равенство &amp;lt;tex&amp;gt;C_1 = m&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь пусть &amp;lt;tex&amp;gt;C_k = m + k + t&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;t \geqslant 0&amp;lt;/tex&amp;gt;. Будем называть ''итерацией обработки'' работы обработку на одной машине. Разобьем все работы на три множества:&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; будет содержать все итерации обработки работ &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; {{---}} все итерации, запланированные в расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt; строго после момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; {{---}} итерации обработки работ &amp;lt;tex&amp;gt;i = k + 1 \ldots n&amp;lt;/tex&amp;gt;, которые в &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt; запланированы на время &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; и раньше&lt;br /&gt;
Таким образом, мы имеем три непересекающихся множества, которые вместе с работой &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; покрывают все итерации всех работ.&amp;lt;br&amp;gt;&lt;br /&gt;
Построим новое расписание &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;. Для начала расставим все работы из множества &amp;lt;tex&amp;gt;A \cup B&amp;lt;/tex&amp;gt; так же, как они были запланированы в расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt;, ни одна итерация обработки в множестве &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; не поставлена раньше момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; и к моменту времени &amp;lt;tex&amp;gt;C_k = m + k + t&amp;lt;/tex&amp;gt; выполнено &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ, то это значит, что между моментами времени &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k + m - 1&amp;lt;/tex&amp;gt; на каждой машине есть &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; различных простоев, то есть моментов, когда на ней ничего не обрабатывается. Значит, мы всегда сможем поставить на эти простои итерации обработки работы &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, даже если эти простои пересекаются. Таким образом, &amp;lt;tex&amp;gt;C_k \leqslant m + k - 1&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь назначим машины для операций из множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. До момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; сейчас распланировано ровно &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ, так как по определению работы из множества &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; запланированы на время строго большее &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;. Значит, между моментами времени &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; есть &amp;lt;tex&amp;gt;k + m + t - k = m + t&amp;lt;/tex&amp;gt; различных простоев на каждой машине. Исходя из определения множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; и того, что к моменту &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; распланировано &amp;lt;tex&amp;gt;km&amp;lt;/tex&amp;gt; итераций обработок, приходим к неравенству &amp;lt;tex&amp;gt;|C| \leqslant (k + m + t)m - km = (m + t)m&amp;lt;/tex&amp;gt;. Значит, мы можем распланировать итерации из множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; не позднее момента &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;. Таим образом, мы снова построили расписание для задачи open shop, которое так же является оптимальным, так как для множеств &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; все осталось как в оптимальном расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;, работу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; мы научились выполнять быстрее, а для множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; ответ был не ухудшен. Любая работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, итерации обработки которой принадлежат множеству &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, имела время окончания &amp;lt;tex&amp;gt;C_j \geqslant m + k + t&amp;lt;/tex&amp;gt;. Однако это противоречит тому, что мы выбрали максимальное &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;. &lt;br /&gt;
}}&lt;br /&gt;
Отсортируем работы в порядке неуменьшения дедлайнов. Для текущей работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; вычислим ''лимит'' &amp;lt;tex&amp;gt;T_i&amp;lt;/tex&amp;gt; {{---}} время, до которого закончится обработка данной работы, то есть &amp;lt;tex&amp;gt;1 \leqslant t_1 &amp;lt; t_2 &amp;lt; \ldots &amp;lt; t_m \leqslant T_i &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;t_j&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;j = 1 \ldots m&amp;lt;/tex&amp;gt; {{---}} периоды обработки работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Будем выбирать эти периоды среди моментов времени, в которые выполняется наименьшее число работ.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Определим ''вектор частот'' &amp;lt;tex&amp;gt;h(t)&amp;lt;/tex&amp;gt; {{---}} количество работ во временном интервале &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Работы отсортированы в порядке &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
   '''function''' &amp;lt;tex&amp;gt;\mathrm{Scheduller}():&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''int''' &amp;lt;tex&amp;gt;h[]&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''vector&amp;lt;int&amp;gt;''' &amp;lt;tex&amp;gt;s[]&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for''' &amp;lt;tex&amp;gt;t = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt;s[t] = \varnothing&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for''' &amp;lt;tex&amp;gt;t = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;m + n - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt;h[t] = 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for''' &amp;lt;tex&amp;gt;i = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt;d_i &amp;lt; m + i - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
         вычислим &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; {{---}} количество временных интервалов &amp;lt;tex&amp;gt;t = 1 \ldots d_i&amp;lt;/tex&amp;gt;, таких, что &amp;lt;tex&amp;gt;h[t] &amp;lt; m&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''if''' &amp;lt;tex&amp;gt;z \geqslant m&amp;lt;/tex&amp;gt;&lt;br /&gt;
            &amp;lt;tex&amp;gt;T_i = d_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''else''' &lt;br /&gt;
            &amp;lt;tex&amp;gt;T_i = d_i + m - z&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''else'''&lt;br /&gt;
         &amp;lt;tex&amp;gt;T_i = m + i - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
      вычислим &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; периодов &amp;lt;tex&amp;gt;1 \leqslant t_1 &amp;lt; t_2 &amp;lt; \ldots &amp;lt; t_m \leqslant T_i &amp;lt;/tex&amp;gt; с минимальными значениями &amp;lt;tex&amp;gt;h(t_j)&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''for''' &amp;lt;tex&amp;gt;j = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt;s[i] =  s[i] \cup \{t_j - 1\}&amp;lt;/tex&amp;gt;         &amp;lt;font color=green&amp;gt;// ставим работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; на время &amp;lt;tex&amp;gt;[t_j - 1, t_j]&amp;lt;/tex&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt;h[t_j] = h[t_j] + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Асимптотика ===&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[O2Cmax|&amp;lt;tex&amp;gt;O2 \mid \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opi1sumu|&amp;lt;tex&amp;gt;O \mid p_{ij} = 1 \mid \sum U_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1di|&amp;lt;tex&amp;gt; O \mid p_{i, j} = 1, d_i \mid - &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1sumwu|&amp;lt;tex&amp;gt; O \mid p_{i, j} = 1 \mid - \sum w_{i} U_{i}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* Peter Brucker «Scheduling Algorithms», fifth edition, Springer {{---}} с. 171-174 ISBN 978-3-540-69515-8&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Opij1SumTi&amp;diff=54561</id>
		<title>Opij1SumTi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Opij1SumTi&amp;diff=54561"/>
				<updated>2016-06-05T08:01:17Z</updated>
		
		<summary type="html">&lt;p&gt;Анна: Новая страница: «&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; O \mid p_{i,j} = 1 \mid \sum T_{i} &amp;lt;/tex&amp;gt; {{Задача |definition= Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; одинаковых станков, которые ...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt; O \mid p_{i,j} = 1 \mid \sum T_{i} &amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition=&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; одинаковых станков, которые работают параллельно, и &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ, которые необходимо выполнить в произвольном порядке на всех станках. Любая работа на любом станке выполняется единицу времени. Для каждой работы есть время окончания &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt; {{---}} время, до которого она должна быть выполнена. Необходимо минимизировать суммарную [[Классификация_задач#Критерий оптимизации|медлительность]].&lt;br /&gt;
}} &lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Будем полагать, что работы заданы в порядке неубывания их дедлайнов, то есть &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;. &lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть есть работы &amp;lt;tex&amp;gt;1 \ldots n&amp;lt;/tex&amp;gt; с дедлайнами &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;. Тогда существует оптимальное расписание, в котором времена завершения работ идут в том же порядке, то есть &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим две работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из какого-либо оптимального расписания такие, что &amp;lt;tex&amp;gt;C_i &amp;gt; C_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d_i &amp;lt; d_j&amp;lt;/tex&amp;gt;. Поменяем эти работы в расписании местами, то есть &amp;lt;tex&amp;gt;C'_i = C_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;C'_j = C_i&amp;lt;/tex&amp;gt;. Если они обе успевали выполниться вовремя, то это свойство сохранится, так как &amp;lt;tex&amp;gt;d_i &amp;lt; d_j&amp;lt;/tex&amp;gt;, значит по-прежнему &amp;lt;tex&amp;gt;T_i = 0&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T_j = 0&amp;lt;/tex&amp;gt;, то есть значение целевой функции мы не ухудшили и расписание осталось оптимальным. Если обе работы не успевали выполниться вовремя, то когда мы поменяем их местами ничего не изменится, то есть значение целевой функции останется прежним, так как мы не меняли значения времен окончаний, а только поменяли их местами. Если работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; успевала выполниться, а  &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; {{---}} нет, то мы снова не ухудшим значение целевой функции. Покажем это. До того, как мы поменяли работы местами, было &amp;lt;tex&amp;gt;T_i + T_j = C_i - d_i&amp;lt;/tex&amp;gt;, так как &amp;lt;tex&amp;gt;T_j = 0&amp;lt;/tex&amp;gt;. После того, как мы поменяли работы местами, &amp;lt;tex&amp;gt;T_i + T_j = C'_i - d_i + C'_j - d_j =  C_j - d_i + C_i - d_j = C_i - d_i + (C_j - d_j)&amp;lt;/tex&amp;gt;. Но так как работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; успевает выполниться до дедлайна, то &amp;lt;tex&amp;gt;C_j - d_j \leqslant 0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
Далее будем рассматривать только оптимальное расписание со свойством &amp;lt;tex&amp;gt;C_1 \leqslant C_2 \leqslant \ldots \leqslant C_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Всегда существует оптимально расписание такое, что в нем &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для любого &amp;lt;tex&amp;gt;i = 1 \ldots n&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; {{---}} количество станков.&lt;br /&gt;
|proof=&lt;br /&gt;
Рассмотрим оптимальное расписание &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;, в котором для любого &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt; выполняется &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt;, но &amp;lt;tex&amp;gt;C_k &amp;gt; m + k - 1&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; максимально среди всех возможных. Для начала покажем, что &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; не меньше &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;. Пусть есть оптимальное расписание, у которого &amp;lt;tex&amp;gt;C_1 &amp;gt; m&amp;lt;/tex&amp;gt;. Это значит, что есть период времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; такой, что первая работа выполняется в момент &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; и не выполняется в &amp;lt;tex&amp;gt;t - 1&amp;lt;/tex&amp;gt;. Поменяем эти периоды времени местами. То есть все работы, которые выполнялись в момент &amp;lt;tex&amp;gt;t - 1&amp;lt;/tex&amp;gt;, будут выполняться на тех же станках, но в момент &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, и наоборот. Значение &amp;lt;tex&amp;gt;C_i&amp;lt;/tex&amp;gt; для каждой работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; не увеличится, так как &amp;lt;tex&amp;gt;C_1&amp;lt;/tex&amp;gt; было минимальным из них, а значит ни одна работа не могла быть закончена раньше периода времени &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Будем продолжать этот процесс, пока не будет выполнено равенство &amp;lt;tex&amp;gt;C_1 = m&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь пусть &amp;lt;tex&amp;gt;C_k = m + k + t&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;t \geqslant 0&amp;lt;/tex&amp;gt;. Будем называть ''итерацией обработки'' работы обработку на одной машине. Разобьем все работы на три множества:&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; будет содержать все итерации обработки работ &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; {{---}} все итерации, запланированные в расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt; строго после момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;&lt;br /&gt;
* множество &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; {{---}} итерации обработки работ &amp;lt;tex&amp;gt;i = k + 1 \ldots n&amp;lt;/tex&amp;gt;, которые в &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt; запланированы на время &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; и раньше&lt;br /&gt;
Таким образом, мы имеем три непересекающихся множества, которые вместе с работой &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; покрывают все итерации всех работ.&amp;lt;br&amp;gt;&lt;br /&gt;
Построим новое расписание &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;. Для начала расставим все работы из множества &amp;lt;tex&amp;gt;A \cup B&amp;lt;/tex&amp;gt; так же, как они были запланированы в расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;C_i \leqslant m + i - 1&amp;lt;/tex&amp;gt; для &amp;lt;tex&amp;gt;i = 1 \ldots k - 1&amp;lt;/tex&amp;gt;, ни одна итерация обработки в множестве &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; не поставлена раньше момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; и к моменту времени &amp;lt;tex&amp;gt;C_k = m + k + t&amp;lt;/tex&amp;gt; выполнено &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ, то это значит, что между моментами времени &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k + m - 1&amp;lt;/tex&amp;gt; на каждой машине есть &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; различных простоев, то есть моментов, когда на ней ничего не обрабатывается. Значит, мы всегда сможем поставить на эти простои итерации обработки работы &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, даже если эти простои пересекаются. Таким образом, &amp;lt;tex&amp;gt;C_k \leqslant m + k - 1&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь назначим машины для операций из множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. До момента времени &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; сейчас распланировано ровно &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; работ, так как по определению работы из множества &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; запланированы на время строго большее &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;. Значит, между моментами времени &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; есть &amp;lt;tex&amp;gt;k + m + t - k = m + t&amp;lt;/tex&amp;gt; различных простоев на каждой машине. Исходя из определения множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; и того, что к моменту &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt; распланировано &amp;lt;tex&amp;gt;km&amp;lt;/tex&amp;gt; итераций обработок, приходим к неравенству &amp;lt;tex&amp;gt;|C| \leqslant (k + m + t)m - km = (m + t)m&amp;lt;/tex&amp;gt;. Значит, мы можем распланировать итерации из множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; не позднее момента &amp;lt;tex&amp;gt;k + m + t&amp;lt;/tex&amp;gt;. Таим образом, мы снова построили расписание для задачи open shop, которое так же является оптимальным, так как для множеств &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; все осталось как в оптимальном расписании &amp;lt;tex&amp;gt;S^*&amp;lt;/tex&amp;gt;, работу &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; мы научились выполнять быстрее, а для множества &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; ответ был не ухудшен. Любая работа &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, итерации обработки которой принадлежат множеству &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, имела время окончания &amp;lt;tex&amp;gt;C_j \geqslant m + k + t&amp;lt;/tex&amp;gt;. Однако это противоречит тому, что мы выбрали максимальное &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;. &lt;br /&gt;
}}&lt;br /&gt;
Отсортируем работы в порядке неуменьшения дедлайнов. Для текущей работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; вычислим ''лимит'' &amp;lt;tex&amp;gt;T_i&amp;lt;/tex&amp;gt; {{---}} время, до которого закончится обработка данной работы, то есть &amp;lt;tex&amp;gt;1 \leqslant t_1 &amp;lt; t_2 &amp;lt; \ldots &amp;lt; t_m \leqslant T_i &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;t_j&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;j = 1 \ldots m&amp;lt;/tex&amp;gt; {{---}} периоды обработки работы &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Будем выбирать эти периоды среди моментов времени, в которые выполняется наименьшее число работ.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Определим ''вектор частот'' &amp;lt;tex&amp;gt;h(t)&amp;lt;/tex&amp;gt; {{---}} количество работ во временном интервале &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;. Работы отсортированы в порядке &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \ldots \leqslant d_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
   '''for''' &amp;lt;tex&amp;gt;t = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;m + n - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
      &amp;lt;tex&amp;gt;h(t) = 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
   '''for''' &amp;lt;tex&amp;gt;i = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''if''' &amp;lt;tex&amp;gt;d_i &amp;lt; m + i - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
         вычислим &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; {{---}} количество временных интервалов &amp;lt;tex&amp;gt;t = 1 \ldots d_i&amp;lt;/tex&amp;gt;, таких, что &amp;lt;tex&amp;gt;h(t) &amp;lt; m&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''if''' &amp;lt;tex&amp;gt;z \geqslant m&amp;lt;/tex&amp;gt;&lt;br /&gt;
            &amp;lt;tex&amp;gt;T_i = d_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''else''' &lt;br /&gt;
            &amp;lt;tex&amp;gt;T_i = d_i + m - z&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''else'''&lt;br /&gt;
         &amp;lt;tex&amp;gt;T_i = m + i - 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
      вычислим &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; периодов &amp;lt;tex&amp;gt;1 \leqslant t_1 &amp;lt; t_2 &amp;lt; \ldots &amp;lt; t_m \leqslant T_i &amp;lt;/tex&amp;gt; с минимальными значениями &amp;lt;tex&amp;gt;h(t_j)&amp;lt;/tex&amp;gt;&lt;br /&gt;
      '''for''' &amp;lt;tex&amp;gt;j = 1&amp;lt;/tex&amp;gt; '''to''' &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;&lt;br /&gt;
         ставим работу &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; на время &amp;lt;tex&amp;gt;[t_j - 1, t_j]&amp;lt;/tex&amp;gt;&lt;br /&gt;
         &amp;lt;tex&amp;gt;h(t_j) = h(t_j) + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
=== Асимптотика ===&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[O2Cmax|&amp;lt;tex&amp;gt;O2 \mid \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opi1sumu|&amp;lt;tex&amp;gt;O \mid p_{ij} = 1 \mid \sum U_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1di|&amp;lt;tex&amp;gt; O \mid p_{i, j} = 1, d_i \mid - &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1sumwu|&amp;lt;tex&amp;gt; O \mid p_{i, j} = 1 \mid - \sum w_{i} U_{i}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* Peter Brucker «Scheduling Algorithms», fifth edition, Springer {{---}} с. 171-174 ISBN 978-3-540-69515-8&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>Анна</name></author>	</entry>

	</feed>