<?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=Kiryukhinv</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=Kiryukhinv"/>
		<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/Kiryukhinv"/>
		<updated>2026-08-03T23:04:28Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D1%8B&amp;diff=59606</id>
		<title>Локальные автоматы</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D1%8B&amp;diff=59606"/>
				<updated>2017-01-14T17:03:56Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: /* Источники информации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Описание==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Граф Майхилла &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; (над алфавитом &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;)''' (англ. ''Myhill graph'') {{---}} [[Основные определения теории графов | ориентированный граф]], удовлетворяющий свойствам:&lt;br /&gt;
# Для каждой упорядоченной пары вершин &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; существует только одно ребро из &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Некоторые вершины обозначены начальными, а некоторые {{---}} конечными. Ребро может одновременно быть начальным и конечным.&lt;br /&gt;
# Вершины обозначены различными символами из конечного алфавита &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;, то есть мы можем обращаться к вершине по ее символу.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;G&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;c \in \Sigma&amp;lt;/tex&amp;gt; назовем разрешенным, если им помечена вершина, являющая одновременно начальной и конечной.&lt;br /&gt;
&lt;br /&gt;
Не пустая строка &amp;lt;tex&amp;gt;c_1c_2 \ldots c_n&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;\Sigma^*&amp;lt;/tex&amp;gt; длиной не менее двух символов, называется разрешенной, если символом &amp;lt;tex&amp;gt;c_1&amp;lt;/tex&amp;gt; отмечена стартовая вершина, а символом &amp;lt;tex&amp;gt;c_n&amp;lt;/tex&amp;gt; {{---}} конечная, и для всех &amp;lt;tex&amp;gt;1 \leqslant i \leqslant n - 1&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; существует ребро &amp;lt;tex&amp;gt;(c_i, c_{i+1})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Язык &amp;lt;tex&amp;gt;L(G)&amp;lt;/tex&amp;gt;, распознаваемый графом Майхилла, состоит из всех разрешенных строк из  &amp;lt;tex&amp;gt;\Sigma^+&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Покажем, что графы Майхилла могут быть представлены в виде автоматов. &lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\mathcal{A} = (S,  \Sigma, i, \delta, T)&amp;lt;/tex&amp;gt; {{---}} [[Детерминированные_конечные_автоматы | ДКА]].&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition= Автомат &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; называется '''локальным''' (англ. ''local automaton'', ''Glushkov automaton''), если для любого &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; из  &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt; множество &amp;lt;tex&amp;gt;\{\delta(s, c) \mid s \in S\}&amp;lt;/tex&amp;gt; содержит не более одного элемента. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=Локальный автомат &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; называется '''стандартным локальным''' автоматом (англ. ''standard local automation''), если в нем нет перехода в начальное состояние.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Таким образом, автомат является локальным, если для каждого &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; из  &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt; нет переходов, отмеченных &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;, или если все они ведут в одно состояние.&lt;br /&gt;
&lt;br /&gt;
Покажем, что граф Майхилла может быть преобразован в стандартный локальный автомат таким образом, что распознаваемый им язык не изменится.&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Язык распознается графом Майхилла тогда и только тогда, когда он распознается стандартным локальным автоматом, стартовое состояние которого не является терминальным.&lt;br /&gt;
|proof=&lt;br /&gt;
&amp;lt;tex&amp;gt;\Rightarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:Пусть &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; {{---}} граф Майхилла. &lt;br /&gt;
:Построим автомат &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; следующим образом: &lt;br /&gt;
:* Добавим вершину &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; с ребрами от &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; к каждой стартовой вершине &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;; отметим вершину &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; как стартовое состояние.&lt;br /&gt;
:* Отметим конечные вершины как терминальные состояния.&lt;br /&gt;
:* Отметим каждое ребро результирующего ориентированного графа символом, стоящим в вершине, на которою оно указывает. &lt;br /&gt;
:Переходы преобразуются следующим образом: [[Файл:Myhill1.png|150px]]&lt;br /&gt;
&lt;br /&gt;
:По построению стартовое состояние не является терминальным. &lt;br /&gt;
&lt;br /&gt;
:Покажем, что полученный автомат конечен. &lt;br /&gt;
:Ребра, выходящие из стартового состояния обозначены различными символами, потому что они указывают на вершины, которые, по свойству 3, были отмечены различными символами в исходном автомате.&lt;br /&gt;
:Если мы рассмотрим любое другое состояние &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;, то два перехода из &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; могут иметь одинаковые метки только в том случае, если в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; оба ориентированных ребра идут в одну и ту же вершину. Но этого не может быть по свойтсву 1. &lt;br /&gt;
:То есть &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} [[Детерминированные_конечные_автоматы | ДКА]]. По построению он является стандартным локальным автоматом. &lt;br /&gt;
:Теперь просто проверить, что &amp;lt;tex&amp;gt;L(\mathcal{A}) = L(G)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\Leftarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:Пусть &amp;lt;tex&amp;gt;\mathcal{A} = (S, \Sigma, i, \delta, T)&amp;lt;/tex&amp;gt; {{---}} стандартный локальный автомат, стартовое состояние которого не является терминальным.&lt;br /&gt;
:Построим по нему граф Майхилла следующим образом:&lt;br /&gt;
:* Отметим все состояния &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, кроме стартового, &amp;lt;tex&amp;gt;input&amp;lt;/tex&amp;gt; символами, стоящими на ребрах, входящих в эти состояния. &lt;br /&gt;
:* Сотрем все метки на ребрах &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
:* Отметим все состояния &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; как начальные вершины, если существует переход из &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;&lt;br /&gt;
:* Отметим все терминальные состояния как конечные вершины.&lt;br /&gt;
:* Удалим вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и все ребра, исходящие из нее.&lt;br /&gt;
:Назовем полученный граф &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; {{---}} он будет графом Майхилла по построению. Легко проверить, что &amp;lt;tex&amp;gt;L(G) = L(\mathcal{A})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Пример==&lt;br /&gt;
{| cellpadding=&amp;quot;3&amp;quot; style=&amp;quot;margin-left: auto; margin-right: auto;&amp;quot;&lt;br /&gt;
| [[Файл:Myhill2.png|300px|thumb|right|Рисунок 1]] &lt;br /&gt;
| [[Файл:Myhill3.png|200px|thumb|right|Рисунок 2]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Граф Майхилла, изображенный на рисунке 1 может быть использован для распознавания строк над алфавитом &amp;lt;tex&amp;gt;\Sigma = \{a, b\}&amp;lt;/tex&amp;gt;. По определению, язык, распознаваемый данным графом, состоит из непустых строк, начинающихся и заканчивающихся на &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Недетерминированный автомат на рисунке 2 является локальным автоматом и распознает тот же самый язык.&lt;br /&gt;
&lt;br /&gt;
==Локальный язык==&lt;br /&gt;
Рассмотрим язык, распознаваемый стандартным локальным автоматом. &lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=Язык &amp;lt;tex&amp;gt;L \subseteq A^*&amp;lt;/tex&amp;gt; называется '''локальным языком''' (англ. ''local language''), если &amp;lt;tex&amp;gt;L \setminus \varepsilon&amp;lt;/tex&amp;gt; может быть описан следующим образом:  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt;\exists P, S \subseteq A, N \subseteq A^2: L \setminus \varepsilon = (P A^* \cap A^* S) \setminus A^* N A^*&amp;lt;/tex&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Другими словами, непустое слово принадлежит локальному языку, если оно начинается с символа из &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, оканчивается на символ из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; и не содержит пары символов из множества &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L = (P A^* \cap A^* S) \setminus A^* N A^*&amp;lt;/tex&amp;gt; {{---}} локальный язык. Определим автомат &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; следующим образом:&lt;br /&gt;
* набор состояний &amp;lt;tex&amp;gt;Q = A \cup \{ \varepsilon \}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* начальное состояние &amp;lt;tex&amp;gt;\varepsilon&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* терминальные состояния &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\delta(\varepsilon, a) = a&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;a \in P&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta(a, b) = b&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;ab \not\in N&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Если &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; содержит пустую строку, то множество терминальных состояний &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;S \cup \{ \varepsilon \}&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Определенный таким образом автомат &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} стандартный локальный автомат, распознающий &amp;lt;tex&amp;gt;L&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;a&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;\delta(s, a)&amp;lt;/tex&amp;gt; либо неопределена либо равна &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;. По построению автомат является стандартным. Покажем, что &amp;lt;tex&amp;gt;L(\mathcal{A}) = L&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;x = a_1 \ldots a_n \in L(\mathcal{A})&amp;lt;/tex&amp;gt;. Тогда в автомате существует путь: &amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;tex&amp;gt;\varepsilon \xrightarrow{a_1} a_1 \xrightarrow{a_2} a_2 \ldots a_{n-1} \xrightarrow{a_n} a_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Здесь &amp;lt;tex&amp;gt;a_n&amp;lt;/tex&amp;gt; {{---}} терминальное состояние, &amp;lt;tex&amp;gt;a_n \in S&amp;lt;/tex&amp;gt;. Переход из &amp;lt;tex&amp;gt;\varepsilon&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;a_1&amp;lt;/tex&amp;gt; определен, поэтому &amp;lt;tex&amp;gt;a_1 \in P&amp;lt;/tex&amp;gt;. Для каждого &amp;lt;tex&amp;gt;j: 1 \leqslant j \leqslant n - 1&amp;lt;/tex&amp;gt; факт, что переход &amp;lt;tex&amp;gt;a_j \rightarrow a_{j+1}&amp;lt;/tex&amp;gt; существует, означает что &amp;lt;tex&amp;gt;a_j a_{j+1} \not \in N&amp;lt;/tex&amp;gt;. Следовательно, &amp;lt;tex&amp;gt;x \in L&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;x = a_1 \ldots a_n \in L&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;a_1 \in P&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;a_n \in S&amp;lt;/tex&amp;gt; и для каждого &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;a_j a_{j+1} \not \in N&amp;lt;/tex&amp;gt;. Следовательно в автомате существует путь из начального состояния в терминальное: &amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;tex&amp;gt;\varepsilon \xrightarrow{a_1} a_1 \xrightarrow{a_2} a_2 \ldots a_{n-1} \xrightarrow{a_n} a_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Следовательно, &amp;lt;tex&amp;gt;x \in L(\mathcal{A})&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Язык, распознаваемый локальным автоматом, является локальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Алгоритм Глушкова==&lt;br /&gt;
===Описание===&lt;br /&gt;
Дано регулярное выражение &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Алгоритм Глушкова строит недетерминированный автомат, который распознает язык &amp;lt;tex&amp;gt;L(e)&amp;lt;/tex&amp;gt;, распознаваемый &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Построение происходит в несколько шагов:&lt;br /&gt;
# Линеаризация регулярного выражения. Каждый символ из алфавита, содержащийся в регулярном выражении, переименовывается таким образом, что каждый символ содержится в новом регулярном выражении не более одного раза. Пусть &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; {{---}} исходный алфавит, &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; {{---}} новый алфавит.&lt;br /&gt;
# Вычисление множеств &amp;lt;tex&amp;gt;P(e'), S(e'), N(e')&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;e'&amp;lt;/tex&amp;gt; {{---}} линеаризованное регулярное выражение. &amp;lt;tex&amp;gt;P(e')&amp;lt;/tex&amp;gt; {{---}} множество символов, с которых начинается слово из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;S(e')&amp;lt;/tex&amp;gt; {{---}} множество символов, на которые оканчивается слово из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;N(e')&amp;lt;/tex&amp;gt; {{---}} множество пар символов, которые встречаются в слове из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt;. Более формально: &amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;P(e')=\{a\in B\mid aB^*\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;S(e')=\{a\in B\mid B^*a\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;N(e')=\{u\in B^2\mid B^*uB^*\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Вычисление множества &amp;lt;tex&amp;gt;\Lambda(e')&amp;lt;/tex&amp;gt; такого что &amp;lt;tex&amp;gt;\Lambda(e')=\{\varepsilon\}\cap L(e')&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Вычисление локального языка с заданными множествами и построение по нему автомата.&lt;br /&gt;
# Делинеаризация, переименование каждого символа из &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; в соответствующий ему символ из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
===Пример работы===&lt;br /&gt;
[[Файл:Glushkov_lin_automata.jpg|frame|right|Автомат, построенный в ходе работы алгоритма Глушкова]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим регулярное выражение &amp;lt;tex&amp;gt;e = (a(ab)^*)^* + (ba)^*&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Линеаризуем его путем добавления индекса к каждому символу:&lt;br /&gt;
:&amp;lt;tex&amp;gt;e'=(a_1(a_2b_3)^*)^*+(b_4a_5)^*&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2. Составим множества &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt;:&lt;br /&gt;
:&amp;lt;tex&amp;gt;P(e')=\{a_1,b_4\}&amp;lt;/tex&amp;gt;,&amp;lt;br /&amp;gt;&lt;br /&gt;
:&amp;lt;tex&amp;gt;S(e')=\{a_1,b_3,a_5\}&amp;lt;/tex&amp;gt;,&amp;lt;br /&amp;gt;&lt;br /&gt;
:&amp;lt;tex&amp;gt;N(e')=\{a_1a_2, a_1a_1, a_2b_3, b_3a_1,b_3a_2,b_4a_5,a_5b_4\}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как пустое слово принадлежит языку, то &amp;lt;math&amp;gt;\Lambda(e')=\{\varepsilon\}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
3. Автомат локального языка &amp;lt;tex&amp;gt;L'=P'B^*\cap B^*S'\setminus B^*(B^2\setminus N')B^*&amp;lt;/tex&amp;gt; содержит начальное состояние, обозначенное как &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, и состояния для каждого из пяти символов алфавита &amp;lt;tex&amp;gt;B=\{a_1, a_2, b_3, b_4, a_5\}&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
В построенном автомате существует переход из &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; (соответствующего пустой строке) в два состояния из &amp;lt;tex&amp;gt;P'&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;ab \in N'&amp;lt;/tex&amp;gt;, три состояния &amp;lt;math&amp;gt;S'&amp;lt;/math&amp;gt; терминальные (как и состояние &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
4. Получим автомат для &amp;lt;tex&amp;gt;L(e)&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;
* Mark V. Lawson {{---}} Finite Automata&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Glushkov's_construction_algorithm Wikipedia {{---}} Glushkov's construction algorithm]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;br /&gt;
[[Категория: Другие автоматы]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D1%8B&amp;diff=59604</id>
		<title>Локальные автоматы</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D1%8B&amp;diff=59604"/>
				<updated>2017-01-14T12:04:29Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Описание==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Граф Майхилла &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; (над алфавитом &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;)''' (англ. ''Myhill graph'') {{---}} [[Основные определения теории графов | ориентированный граф]], удовлетворяющий свойствам:&lt;br /&gt;
# Для каждой упорядоченной пары вершин &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; существует только одно ребро из &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Некоторые вершины обозначены начальными, а некоторые {{---}} конечными. Ребро может одновременно быть начальным и конечным.&lt;br /&gt;
# Вершины обозначены различными символами из конечного алфавита &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;, то есть мы можем обращаться к вершине по ее символу.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;G&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;c \in \Sigma&amp;lt;/tex&amp;gt; назовем разрешенным, если им помечена вершина, являющая одновременно начальной и конечной.&lt;br /&gt;
&lt;br /&gt;
Не пустая строка &amp;lt;tex&amp;gt;c_1c_2...c_n&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;\Sigma^*&amp;lt;/tex&amp;gt; длиной не менее двух символов, называется разрешенной, если символом &amp;lt;tex&amp;gt;c_1&amp;lt;/tex&amp;gt; отмечена стартовая вершина, а символом &amp;lt;tex&amp;gt;c_n&amp;lt;/tex&amp;gt; {{---}} конечная, и для всех &amp;lt;tex&amp;gt;1 \leqslant i \leqslant n - 1&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; существует ребро &amp;lt;tex&amp;gt;(c_i, c_{i+1})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Язык &amp;lt;tex&amp;gt;L(G)&amp;lt;/tex&amp;gt;, распознаваемый графом Майхилла, состоит из всех разрешенных строк из  &amp;lt;tex&amp;gt;\Sigma^+&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Покажем, что графы Майхилла могут быть представлены в виде автоматов. &lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A = (S,  \Sigma, i, \delta, T)&amp;lt;/tex&amp;gt; {{---}} [[Детерминированные_конечные_автоматы | ДКА]].&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition= Автомат &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; называется '''локальным''' (англ. ''local automaton'', ''Glushkov automaton''), если для любого &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; из  &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt; множество &amp;lt;tex&amp;gt;\{\delta(s, c) \mid s \in S\}&amp;lt;/tex&amp;gt; содержит не более одного элемента. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=Локальный автомат &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; называется '''стандартным локальным''' автоматом (англ. ''standard local automation''), если в нем нет перехода в начальное состояние.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Таким образом, автомат является локальным, если для каждого &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; из  &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt; нет переходов, отмеченных &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;, или если все они ведут в одно состояние.&lt;br /&gt;
&lt;br /&gt;
Покажем, что граф Майхилла может быть преобразован в стандартный локальный автомат таким образом, что распознаваемый им язык не изменится.&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Язык распознается графом Майхилла тогда и только тогда, когда он распознается стандартным локальным автоматом, стартовое состояние которого не является терминальным.&lt;br /&gt;
|proof=&lt;br /&gt;
&amp;lt;tex&amp;gt;\Rightarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:Пусть &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; {{---}} граф Майхилла. &lt;br /&gt;
:Построим автомат &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; следующим образом: &lt;br /&gt;
:* Добавим вершину &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; с ребрами от &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; к каждой стартовой вершине &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;; отметим вершину &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; как стартовое состояние.&lt;br /&gt;
:* Отметим конечные вершины как терминальные состояния.&lt;br /&gt;
:* Отметим каждое ребро результирующего ориентированного графа символом, стоящим в вершине, на которою оно указывает. &lt;br /&gt;
:Переходы преобразуются следующим образом: [[Файл:Myhill1.png|150px]]&lt;br /&gt;
&lt;br /&gt;
:По построению стартовое состояние не является терминальным. &lt;br /&gt;
&lt;br /&gt;
:Покажем, что полученный автомат конечен. &lt;br /&gt;
:Ребра, выходящие из стартового состояния обозначены различными символами, потому что они указывают на вершины, которые, по свойству 3, были отмечены различными символами в исходном автомате.&lt;br /&gt;
:Если мы рассмотрим любое другое состояние &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;, то два перехода из &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; могут иметь одинаковые метки только в том случае, если в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; оба ориентированных ребра идут в одну и ту же вершину. Но этого не может быть по свойтсву 1. &lt;br /&gt;
:То есть &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} [[Детерминированные_конечные_автоматы | ДКА]]. По построению он является стандартным локальным автоматом. &lt;br /&gt;
:Теперь просто проверить, что &amp;lt;tex&amp;gt;L(\mathcal{A}) = L(G)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\Leftarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:Пусть &amp;lt;tex&amp;gt;\mathcal{A} = (S, \Sigma, i, \delta, T)&amp;lt;/tex&amp;gt; {{---}} стандартный локальный автомат, стартовое состояние которого не является терминальным.&lt;br /&gt;
:Построим по нему граф Майхилла следующим образом:&lt;br /&gt;
:* Отметим все состояния &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, кроме стартового, &amp;lt;tex&amp;gt;input&amp;lt;/tex&amp;gt; символами, стоящими на ребрах, входящих в эти состояния. &lt;br /&gt;
:* Сотрем все метки на ребрах &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
:* Отметим все состояния &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; как начальные вершины, если существует переход из &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;&lt;br /&gt;
:* Отметим все терминальные состояния как конечные вершины.&lt;br /&gt;
:* Удалим вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и все ребра, исходящие из нее.&lt;br /&gt;
:Назовем полученный граф &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; {{---}} он будет графом Майхилла по построению. Легко проверить, что &amp;lt;tex&amp;gt;L(G) = L(\mathcal{A})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Пример==&lt;br /&gt;
{| cellpadding=&amp;quot;3&amp;quot; style=&amp;quot;margin-left: auto; margin-right: auto;&amp;quot;&lt;br /&gt;
| [[Файл:Myhill2.png|300px|thumb|right|Рисунок 1]] &lt;br /&gt;
| [[Файл:Myhill3.png|200px|thumb|right|Рисунок 2]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Граф Майхилла, изображенный на рисунке 1 может быть использован для распознавания строк над алфавитом &amp;lt;tex&amp;gt;\Sigma = \{a, b\}&amp;lt;/tex&amp;gt;. По определению, язык, распознаваемый данным графом, состоит из непустых строк, начинающихся и заканчивающихся на &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Недетерминированный автомат на рисунке 2 является локальным автоматом и распознает тот же самый язык.&lt;br /&gt;
&lt;br /&gt;
==Локальный язык==&lt;br /&gt;
Рассмотрим язык, распознаваемый стандартным локальным автоматом. &lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=Язык &amp;lt;tex&amp;gt;L \subseteq A^*&amp;lt;/tex&amp;gt; называется '''локальным языком''' (англ. ''local language''), если &amp;lt;tex&amp;gt;L \setminus \varepsilon&amp;lt;/tex&amp;gt; может быть описан следующим образом:  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\exists P, S \subseteq A, N \subseteq A^2: L \setminus \varepsilon = (P A^* \cap A^* S) \setminus A^* N A^*&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Другими словами, непустое слово принадлежит локальному языку, если оно начинается с символа из &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, оканчивается на символ из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; и не содержит пары символов из множества &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L = (P A^* \cap A^* S) \setminus A^* N A^*&amp;lt;/tex&amp;gt; {{---}} локальный язык. Определим автомат &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; следующим образом:&lt;br /&gt;
* набор состояний &amp;lt;tex&amp;gt;Q = A \cup \{ \varepsilon \}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* начальное состояние &amp;lt;tex&amp;gt;\varepsilon&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* терминальные состояния &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\delta(\varepsilon, a) = a&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;a \in P&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta(a, b) = b&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;ab \not\in N&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Если &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; содержит пустую строку, то множество терминальных состояний &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;S \cup \{ \varepsilon \}&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Автомат &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; – стандартный локальный автомат, распознающий &amp;lt;tex&amp;gt;L&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;a&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;\delta(s, a)&amp;lt;/tex&amp;gt; либо неопределена либо равна &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;. По построению автомат является стандартным. Покажем, что &amp;lt;tex&amp;gt;L(\mathcal{A}) = L&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;x = a_1 \ldots a_n \in L(\mathcal{A})&amp;lt;/tex&amp;gt;. Тогда в автомате существует путь: &amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;tex&amp;gt;\varepsilon \xrightarrow{a_1} a_1 \xrightarrow{a_2} a_2 \ldots a_{n-1} \xrightarrow{a_n} a_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Здесь &amp;lt;tex&amp;gt;a_n&amp;lt;/tex&amp;gt; {{---}} терминальное состояние, &amp;lt;tex&amp;gt;a_n \in S&amp;lt;/tex&amp;gt;. Переход из &amp;lt;tex&amp;gt;\varepsilon&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;a_1&amp;lt;/tex&amp;gt; определен, поэтому &amp;lt;tex&amp;gt;a_1 \in P&amp;lt;/tex&amp;gt;. Для каждого &amp;lt;tex&amp;gt;j: 1 \leqslant j \leqslant n - 1&amp;lt;/tex&amp;gt; факт, что переход &amp;lt;tex&amp;gt;a_j \rightarrow a_{j+1}&amp;lt;/tex&amp;gt; существует, означает что &amp;lt;tex&amp;gt;a_j a_{j+1} \not \in N&amp;lt;/tex&amp;gt;. Следовательно, &amp;lt;tex&amp;gt;x \in L&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;x = a_1 \ldots a_n \in L&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;a_1 \in P&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;a_n \in S&amp;lt;/tex&amp;gt; и для каждого &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;a_j a_{j+1} \not \in N&amp;lt;/tex&amp;gt;. Следовательно в автомате существует путь из начального состояния в терминальное: &amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;tex&amp;gt;\varepsilon \xrightarrow{a_1} a_1 \xrightarrow{a_2} a_2 \ldots a_{n-1} \xrightarrow{a_n} a_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Следовательно, &amp;lt;tex&amp;gt;x \in L(\mathcal{A})&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Язык, распознаваемый локальным автоматом, является локальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Алгоритм Глушкова==&lt;br /&gt;
===Описание===&lt;br /&gt;
Дано регулярное выражение &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Алгоритм Глушкова строит недетерминированный автомат, который распознает язык &amp;lt;tex&amp;gt;L(e)&amp;lt;/tex&amp;gt;, распознаваемый &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Построение происходит в несколько шагов:&lt;br /&gt;
# Линеаризация регулярного выражения. Каждый символ из алфавита, содержащийся в регулярном выражении, переименовывается таким образом, что каждый символ содержится в новом регулярном выражении не более одного раза. Пусть &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; {{---}} исходный алфавит, &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; {{---}} новый алфавит.&lt;br /&gt;
# Вычисление множеств &amp;lt;tex&amp;gt;P(e'), S(e'), N(e')&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;e'&amp;lt;/tex&amp;gt; {{---}} линеаризованное регулярное выражение. &amp;lt;tex&amp;gt;P(e')&amp;lt;/tex&amp;gt; {{---}} множество символов, с которых начинается слово из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;S(e')&amp;lt;/tex&amp;gt; {{---}} множество символов, на которые оканчивается слово из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;N(e')&amp;lt;/tex&amp;gt; {{---}} множество пар символов, которые встречаются в слове из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt;. Более формально: &amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;P(e')=\{a\in B\mid aB^*\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;S(e')=\{a\in B\mid B^*a\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;N(e')=\{u\in B^2\mid B^*uB^*\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Вычисление множества &amp;lt;tex&amp;gt;\Lambda(e')&amp;lt;/tex&amp;gt; такого что &amp;lt;tex&amp;gt;\Lambda(e')=\{\varepsilon\}\cap L(e')&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Вычисление локального языка с заданными множествами и построение по нему автомата.&lt;br /&gt;
# Делинеаризация, переименование каждого символа из &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; в соответствующий ему символ из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
===Пример работы===&lt;br /&gt;
[[Файл:Glushkov_lin_automata.jpg|frame|right|Автомат, построенный в ходе работы алгоритма Глушкова]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим регулярное выражение &amp;lt;tex&amp;gt;e = (a(ab)^*)^* + (ba)^*&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Линеаризуем его путем добавления индекса к каждому символу:&lt;br /&gt;
:&amp;lt;tex&amp;gt;e'=(a_1(a_2b_3)^*)^*+(b_4a_5)^*&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2. Составим множества &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt;:&lt;br /&gt;
:&amp;lt;tex&amp;gt;P(e')=\{a_1,b_4\}&amp;lt;/tex&amp;gt;,&amp;lt;br /&amp;gt;&lt;br /&gt;
:&amp;lt;tex&amp;gt;S(e')=\{a_1,b_3,a_5\}&amp;lt;/tex&amp;gt;,&amp;lt;br /&amp;gt;&lt;br /&gt;
:&amp;lt;tex&amp;gt;N(e')=\{a_1a_2, a_1a_1, a_2b_3, b_3a_1,b_3a_2,b_4a_5,a_5b_4\}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как пустое слово принадлежит языку, то &amp;lt;math&amp;gt;\Lambda(e')=\{\varepsilon\}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
3. Автомат локального языка &amp;lt;tex&amp;gt;L'=P'B^*\cap B^*S'\setminus B^*(B^2\setminus N')B^*&amp;lt;/tex&amp;gt; содержит начальное состояние, обозначенное как &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, и состояния для каждого из пяти символов алфавита &amp;lt;tex&amp;gt;B=\{a_1, a_2, b_3, b_4, a_5\}&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
В построенном автомате существует переход из &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; (соответствующего пустой строке) в два состояния из &amp;lt;tex&amp;gt;P'&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;ab \in N'&amp;lt;/tex&amp;gt;, три состояния &amp;lt;math&amp;gt;S'&amp;lt;/math&amp;gt; терминальные (как и состояние &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
4. Получим автомат для &amp;lt;tex&amp;gt;L(e)&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;
* Mark V. Lawson {{---}} Finite Automata&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Glushkov's_construction_algorithm Wikipedia {{---}} Glushkov's construction algorithm]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D1%8B&amp;diff=59603</id>
		<title>Локальные автоматы</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D1%8B&amp;diff=59603"/>
				<updated>2017-01-14T11:53:15Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Описание==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Граф Майхилла &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; (над алфавитом &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;)''' (англ. ''Myhill graph'') {{---}} [[Основные определения теории графов | ориентированный граф]], удовлетворяющий свойствам:&lt;br /&gt;
# Для каждой упорядоченной пары вершин &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; существует только одно ребро из &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Некоторые вершины обозначены начальными, а некоторые {{---}} конечными. Ребро может одновременно быть начальным и конечным.&lt;br /&gt;
# Вершины обозначены различными символами из конечного алфавита &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;, то есть мы можем обращаться к вершине по ее символу.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;G&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;c \in \Sigma&amp;lt;/tex&amp;gt; назовем разрешенным, если им помечена вершина, являющая одновременно начальной и конечной.&lt;br /&gt;
&lt;br /&gt;
Не пустая строка &amp;lt;tex&amp;gt;c_1c_2...c_n&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;\Sigma^*&amp;lt;/tex&amp;gt; длиной не менее двух символов, называется разрешенной, если символом &amp;lt;tex&amp;gt;c_1&amp;lt;/tex&amp;gt; отмечена стартовая вершина, а символом &amp;lt;tex&amp;gt;c_n&amp;lt;/tex&amp;gt; {{---}} конечная, и для всех &amp;lt;tex&amp;gt;1 \leqslant i \leqslant n - 1&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; существует ребро &amp;lt;tex&amp;gt;(c_i, c_{i+1})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Язык &amp;lt;tex&amp;gt;L(G)&amp;lt;/tex&amp;gt;, распознаваемый графом Майхилла, состоит из всех разрешенных строк из  &amp;lt;tex&amp;gt;\Sigma^+&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Покажем, что графы Майхилла могут быть представлены в виде автоматов. &lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A = (S,  \Sigma, i, \delta, T)&amp;lt;/tex&amp;gt; {{---}} [[Детерминированные_конечные_автоматы | ДКА]].&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition= Автомат &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; называется '''локальным''' (англ. ''local automaton'', ''Glushkov automaton''), если для любого &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; из  &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt; множество &amp;lt;tex&amp;gt;\{\delta(s, c) \mid s \in S\}&amp;lt;/tex&amp;gt; содержит не более одного элемента. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=Локальный автомат &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; называется '''стандартным локальным''' автоматом (англ. ''standard local automation''), если в нем нет перехода в начальное состояние.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Таким образом, автомат является локальным, если для каждого &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; из  &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt; нет переходов, отмеченных &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;, или если все они ведут в одно состояние.&lt;br /&gt;
&lt;br /&gt;
Покажем, что граф Майхилла может быть преобразован в стандартный локальный автомат таким образом, что распознаваемый им язык не изменится.&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Язык распознается графом Майхилла тогда и только тогда, когда он распознается стандартным локальным автоматом, стартовое состояние которого не является терминальным.&lt;br /&gt;
|proof=&lt;br /&gt;
&amp;lt;tex&amp;gt;\Rightarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:Пусть &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; {{---}} граф Майхилла. &lt;br /&gt;
:Построим автомат &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; следующим образом: &lt;br /&gt;
:* Добавим вершину &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; с ребрами от &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; к каждой стартовой вершине &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;; отметим вершину &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; как стартовое состояние.&lt;br /&gt;
:* Отметим конечные вершины как терминальные состояния.&lt;br /&gt;
:* Отметим каждое ребро результирующего ориентированного графа символом, стоящим в вершине, на которою оно указывает. &lt;br /&gt;
:Переходы преобразуются следующим образом: [[Файл:Myhill1.png|150px]]&lt;br /&gt;
&lt;br /&gt;
:По построению стартовое состояние не является терминальным. &lt;br /&gt;
&lt;br /&gt;
:Покажем, что полученный автомат конечен. &lt;br /&gt;
:Ребра, выходящие из стартового состояния обозначены различными символами, потому что они указывают на вершины, которые, по свойству 3, были отмечены различными символами в исходном автомате.&lt;br /&gt;
:Если мы рассмотрим любое другое состояние &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;, то два перехода из &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; могут иметь одинаковые метки только в том случае, если в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; оба ориентированных ребра идут в одну и ту же вершину. Но этого не может быть по свойтсву 1. &lt;br /&gt;
:То есть &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} [[Детерминированные_конечные_автоматы | ДКА]]. По построению он является стандартным локальным автоматом. &lt;br /&gt;
:Теперь просто проверить, что &amp;lt;tex&amp;gt;L(\mathcal{A}) = L(G)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\Leftarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:Пусть &amp;lt;tex&amp;gt;\mathcal{A} = (S, \Sigma, i, \delta, T)&amp;lt;/tex&amp;gt; {{---}} стандартный локальный автомат, стартовое состояние которого не является терминальным.&lt;br /&gt;
:Построим по нему граф Майхилла следующим образом:&lt;br /&gt;
:* Отметим все состояния &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, кроме стартового, &amp;lt;tex&amp;gt;input&amp;lt;/tex&amp;gt; символами, стоящими на ребрах, входящих в эти состояния. &lt;br /&gt;
:* Сотрем все метки на ребрах &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
:* Отметим все состояния &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; как начальные вершины, если существует переход из &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;&lt;br /&gt;
:* Отметим все терминальные состояния как конечные вершины.&lt;br /&gt;
:* Удалим вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и все ребра, исходящие из нее.&lt;br /&gt;
:Назовем полученный граф &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; {{---}} он будет графом Майхилла по построению. Легко проверить, что &amp;lt;tex&amp;gt;L(G) = L(\mathcal{A})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Пример==&lt;br /&gt;
{| cellpadding=&amp;quot;3&amp;quot; style=&amp;quot;margin-left: auto; margin-right: auto;&amp;quot;&lt;br /&gt;
| [[Файл:Myhill2.png|300px|thumb|right|Рисунок 1]] &lt;br /&gt;
| [[Файл:Myhill3.png|200px|thumb|right|Рисунок 2]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Граф Майхилла, изображенный на рисунке 1 может быть использован для распознавания строк над алфавитом &amp;lt;tex&amp;gt;\Sigma = \{a, b\}&amp;lt;/tex&amp;gt;. По определению, язык, распознаваемый данным графом, состоит из непустых строк, начинающихся и заканчивающихся на &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Недетерминированный автомат на рисунке 2 является локальным автоматом и распознает тот же самый язык.&lt;br /&gt;
&lt;br /&gt;
==Локальный язык==&lt;br /&gt;
Рассмотрим язык, распознаваемый стандартным локальным автоматом. &lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=Язык &amp;lt;tex&amp;gt;L \subseteq A^*&amp;lt;/tex&amp;gt; называется '''локальным языком''' (англ. ''local language''), если &amp;lt;tex&amp;gt;L \setminus \varepsilon&amp;lt;/tex&amp;gt; может быть описан следующим образом:  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\exists P, S \subseteq A, N \subseteq A^2: L \setminus \varepsilon = (P A^* \cap A^* S) \setminus A^* N A^*&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Другими словами, непустое слово принадлежит локальному языку, если оно начинается с символа из &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, оканчивается на символ из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; и не содержит пары символов из множества &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L = (P A^* \cap A^* S) \setminus A^* N A^*&amp;lt;/tex&amp;gt; {{---}} локальный язык. Определим автомат &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; следующим образом:&lt;br /&gt;
* набор состояний &amp;lt;tex&amp;gt;Q = A \cup \{ \varepsilon \}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* начальное состояние &amp;lt;tex&amp;gt;\varepsilon&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* терминальные состояния &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\delta(\varepsilon, a) = a&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;a \in P&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta(a, b) = b&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;ab \not\in N&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Если &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; содержит пустую строку, то множество терминальных состояний &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;S \cup \{ \varepsilon \}&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Автомат &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; – стандартный локальный автомат, распознающий &amp;lt;tex&amp;gt;L&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;a&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;\delta(s, a)&amp;lt;/tex&amp;gt; либо неопределена либо равна &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;. По построению автомат является стандартным. &amp;lt;br&amp;gt;&lt;br /&gt;
Покажем, что &amp;lt;tex&amp;gt;L(\mathcal{A}) = L&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;x = a_1 \ldots a_n \in L(\mathcal{A})&amp;lt;/tex&amp;gt;. Тогда в автомате существует путь: &amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;tex&amp;gt;\varepsilon \xrightarrow{a_1} a_1 \xrightarrow{a_2} a_2 \ldots a_{n-1} \xrightarrow{a_n} a_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Здесь &amp;lt;tex&amp;gt;a_n&amp;lt;/tex&amp;gt; {{---}} терминальное состояние, &amp;lt;tex&amp;gt;a_n \in S&amp;lt;/tex&amp;gt;. Переход из &amp;lt;tex&amp;gt;\varepsilon&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;a_1&amp;lt;/tex&amp;gt; определен, поэтому &amp;lt;tex&amp;gt;a_1 \in P&amp;lt;/tex&amp;gt;. Для каждого &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; такого что &amp;lt;tex&amp;gt;1 \leqslant j \leqslant n - 1&amp;lt;/tex&amp;gt; факт, что переход &amp;lt;tex&amp;gt;a_j \rightarrow a_{j+1}&amp;lt;/tex&amp;gt; существует, означает что &amp;lt;tex&amp;gt;a_j a_{j+1} \not \in N&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;Следовательно, &amp;lt;tex&amp;gt;x \in L&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Язык, распознаваемый локальным автоматом, является локальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Алгоритм Глушкова==&lt;br /&gt;
===Описание===&lt;br /&gt;
Дано регулярное выражение &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Алгоритм Глушкова строит недетерминированный автомат, который распознает язык &amp;lt;tex&amp;gt;L(e)&amp;lt;/tex&amp;gt;, распознаваемый &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Построение происходит в несколько шагов:&lt;br /&gt;
# Линеаризация регулярного выражения. Каждый символ из алфавита, содержащийся в регулярном выражении, переименовывается таким образом, что каждый символ содержится в новом регулярном выражении не более одного раза. Пусть &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; {{---}} исходный алфавит, &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; {{---}} новый алфавит.&lt;br /&gt;
# Вычисление множеств &amp;lt;tex&amp;gt;P(e'), S(e'), N(e')&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;e'&amp;lt;/tex&amp;gt; {{---}} линеаризованное регулярное выражение. &amp;lt;tex&amp;gt;P(e')&amp;lt;/tex&amp;gt; {{---}} множество символов, с которых начинается слово из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;S(e')&amp;lt;/tex&amp;gt; {{---}} множество символов, на которые оканчивается слово из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;N(e')&amp;lt;/tex&amp;gt; {{---}} множество пар символов, которые встречаются в слове из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt;. Более формально: &amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;P(e')=\{a\in B\mid aB^*\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;S(e')=\{a\in B\mid B^*a\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;N(e')=\{u\in B^2\mid B^*uB^*\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Вычисление множества &amp;lt;tex&amp;gt;\Lambda(e')&amp;lt;/tex&amp;gt; такого что &amp;lt;tex&amp;gt;\Lambda(e')=\{\varepsilon\}\cap L(e')&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Вычисление локального языка с заданными множествами и построение по нему автомата.&lt;br /&gt;
# Делинеаризация, переименование каждого символа из &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; в соответствующий ему символ из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
===Пример работы===&lt;br /&gt;
[[Файл:Glushkov_lin_automata.jpg|frame|right|Автомат, построенный в ходе работы алгоритма Глушкова]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим регулярное выражение &amp;lt;tex&amp;gt;e = (a(ab)^*)^* + (ba)^*&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Линеаризуем его путем добавления индекса к каждому символу:&lt;br /&gt;
:&amp;lt;tex&amp;gt;e'=(a_1(a_2b_3)^*)^*+(b_4a_5)^*&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2. Составим множества &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt;:&lt;br /&gt;
:&amp;lt;tex&amp;gt;P(e')=\{a_1,b_4\}&amp;lt;/tex&amp;gt;,&amp;lt;br /&amp;gt;&lt;br /&gt;
:&amp;lt;tex&amp;gt;S(e')=\{a_1,b_3,a_5\}&amp;lt;/tex&amp;gt;,&amp;lt;br /&amp;gt;&lt;br /&gt;
:&amp;lt;tex&amp;gt;N(e')=\{a_1a_2, a_1a_1, a_2b_3, b_3a_1,b_3a_2,b_4a_5,a_5b_4\}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как пустое слово принадлежит языку, то &amp;lt;math&amp;gt;\Lambda(e')=\{\varepsilon\}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
3. Автомат локального языка &amp;lt;tex&amp;gt;L'=P'B^*\cap B^*S'\setminus B^*(B^2\setminus N')B^*&amp;lt;/tex&amp;gt; содержит начальное состояние, обозначенное как &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, и состояния для каждого из пяти символов алфавита &amp;lt;tex&amp;gt;B=\{a_1, a_2, b_3, b_4, a_5\}&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
В построенном автомате существует переход из &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; (соответствующего пустой строке) в два состояния из &amp;lt;tex&amp;gt;P'&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;ab \in N'&amp;lt;/tex&amp;gt;, три состояния &amp;lt;math&amp;gt;S'&amp;lt;/math&amp;gt; терминальные (как и состояние &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
4. Получим автомат для &amp;lt;tex&amp;gt;L(e)&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;
* Mark V. Lawson {{---}} Finite Automata&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Glushkov's_construction_algorithm Wikipedia {{---}} Glushkov's construction algorithm]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D1%8B&amp;diff=59600</id>
		<title>Локальные автоматы</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D1%8B&amp;diff=59600"/>
				<updated>2017-01-14T11:51:13Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: /* Локальный язык */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Описание==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Граф Майхилла &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; (над алфавитом &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;)''' (англ. ''Myhill graph'') {{---}} [[Основные определения теории графов | ориентированный граф]], удовлетворяющий свойствам:&lt;br /&gt;
# Для каждой упорядоченной пары вершин &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; существует только одно ребро из &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Некоторые вершины обозначены начальными, а некоторые {{---}} конечными. Ребро может одновременно быть начальным и конечным.&lt;br /&gt;
# Вершины обозначены различными символами из конечного алфавита &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;, то есть мы можем обращаться к вершине по ее символу.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;G&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;c \in \Sigma&amp;lt;/tex&amp;gt; назовем разрешенным, если им помечена вершина, являющая одновременно начальной и конечной.&lt;br /&gt;
&lt;br /&gt;
Не пустая строка &amp;lt;tex&amp;gt;c_1c_2...c_n&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;\Sigma^*&amp;lt;/tex&amp;gt; длиной не менее двух символов, называется разрешенной, если символом &amp;lt;tex&amp;gt;c_1&amp;lt;/tex&amp;gt; отмечена стартовая вершина, а символом &amp;lt;tex&amp;gt;c_n&amp;lt;/tex&amp;gt; {{---}} конечная, и для всех &amp;lt;tex&amp;gt;1 \leqslant i \leqslant n - 1&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; существует ребро &amp;lt;tex&amp;gt;(c_i, c_{i+1})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Язык &amp;lt;tex&amp;gt;L(G)&amp;lt;/tex&amp;gt;, распознаваемый графом Майхилла, состоит из всех разрешенных строк из  &amp;lt;tex&amp;gt;\Sigma^+&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Покажем, что графы Майхилла могут быть представлены в виде автоматов. &lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A = (S,  \Sigma, i, \delta, T)&amp;lt;/tex&amp;gt; {{---}} [[Детерминированные_конечные_автоматы | ДКА]].&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition= Автомат &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; называется '''локальным''' (англ. ''local automaton'', ''Glushkov automaton''), если для любого &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; из  &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt; множество &amp;lt;tex&amp;gt;\{\delta(s, c) \mid s \in S\}&amp;lt;/tex&amp;gt; содержит не более одного элемента. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=Локальный автомат &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; называется '''стандартным локальным''' автоматом (англ. ''standard local automation''), если в нем нет перехода в начальное состояние.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Таким образом, автомат является локальным, если для каждого &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; из  &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt; нет переходов, отмеченных &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;, или если все они ведут в одно состояние.&lt;br /&gt;
&lt;br /&gt;
Покажем, что граф Майхилла может быть преобразован в стандартный локальный автомат таким образом, что распознаваемый им язык не изменится.&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Язык распознается графом Майхилла тогда и только тогда, когда он распознается стандартным локальным автоматом, стартовое состояние которого не является терминальным.&lt;br /&gt;
|proof=&lt;br /&gt;
&amp;lt;tex&amp;gt;\Rightarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:Пусть &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; {{---}} граф Майхилла. &lt;br /&gt;
:Построим автомат &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; следующим образом: &lt;br /&gt;
:* Добавим вершину &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; с ребрами от &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; к каждой стартовой вершине &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;; отметим вершину &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; как стартовое состояние.&lt;br /&gt;
:* Отметим конечные вершины как терминальные состояния.&lt;br /&gt;
:* Отметим каждое ребро результирующего ориентированного графа символом, стоящим в вершине, на которою оно указывает. &lt;br /&gt;
:Переходы преобразуются следующим образом: [[Файл:Myhill1.png|150px]]&lt;br /&gt;
&lt;br /&gt;
:По построению стартовое состояние не является терминальным. &lt;br /&gt;
&lt;br /&gt;
:Покажем, что полученный автомат конечен. &lt;br /&gt;
:Ребра, выходящие из стартового состояния обозначены различными символами, потому что они указывают на вершины, которые, по свойству 3, были отмечены различными символами в исходном автомате.&lt;br /&gt;
:Если мы рассмотрим любое другое состояние &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;, то два перехода из &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; могут иметь одинаковые метки только в том случае, если в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; оба ориентированных ребра идут в одну и ту же вершину. Но этого не может быть по свойтсву 1. &lt;br /&gt;
:То есть &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; {{---}} [[Детерминированные_конечные_автоматы | ДКА]]. По построению он является стандартным локальным автоматом. &lt;br /&gt;
:Теперь просто проверить, что &amp;lt;tex&amp;gt;L(A) = L(G)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\Leftarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:Пусть &amp;lt;tex&amp;gt;A = (S, \Sigma, i, \delta, T)&amp;lt;/tex&amp;gt; {{---}} стандартный локальный автомат, стартовое состояние которого не является терминальным.&lt;br /&gt;
:Построим по нему граф Майхилла следующим образом:&lt;br /&gt;
:* Отметим все состояния &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, кроме стартового, &amp;lt;tex&amp;gt;input&amp;lt;/tex&amp;gt; символами, стоящими на ребрах, входящих в эти состояния. &lt;br /&gt;
:* Сотрем все метки на ребрах &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
:* Отметим все состояния &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; как начальные вершины, если существует переход из &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;&lt;br /&gt;
:* Отметим все терминальные состояния как конечные вершины.&lt;br /&gt;
:* Удалим вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и все ребра, исходящие из нее.&lt;br /&gt;
:Назовем полученный граф &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; {{---}} он будет графом Майхилла по построению. Легко проверить, что &amp;lt;tex&amp;gt;L(G) = L(A)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Пример==&lt;br /&gt;
{| cellpadding=&amp;quot;3&amp;quot; style=&amp;quot;margin-left: auto; margin-right: auto;&amp;quot;&lt;br /&gt;
| [[Файл:Myhill2.png|300px|thumb|right|Рисунок 1]] &lt;br /&gt;
| [[Файл:Myhill3.png|200px|thumb|right|Рисунок 2]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Граф Майхилла, изображенный на рисунке 1 может быть использован для распознавания строк над алфавитом &amp;lt;tex&amp;gt;\Sigma = \{a, b\}&amp;lt;/tex&amp;gt;. По определению, язык, распознаваемый данным графом, состоит из непустых строк, начинающихся и заканчивающихся на &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Недетерминированный автомат на рисунке 2 является локальным автоматом и распознает тот же самый язык.&lt;br /&gt;
&lt;br /&gt;
==Локальный язык==&lt;br /&gt;
Рассмотрим язык, распознаваемый стандартным локальным автоматом. &lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=Язык &amp;lt;tex&amp;gt;L \subseteq A^*&amp;lt;/tex&amp;gt; называется '''локальным языком''' (англ. ''local language''), если &amp;lt;tex&amp;gt;L \setminus \varepsilon&amp;lt;/tex&amp;gt; может быть описан следующим образом:  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\exists P, S \subseteq A, N \subseteq A^2: L \setminus \varepsilon = (P A^* \cap A^* S) \setminus A^* N A^*&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Другими словами, непустое слово принадлежит локальному языку, если оно начинается с символа из &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, оканчивается на символ из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; и не содержит пары символов из множества &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L = (P A^* \cap A^* S) \setminus A^* N A^*&amp;lt;/tex&amp;gt; {{---}} локальный язык. Определим автомат &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; следующим образом:&lt;br /&gt;
* набор состояний &amp;lt;tex&amp;gt;Q = A \cup \{ \varepsilon \}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* начальное состояние &amp;lt;tex&amp;gt;\varepsilon&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* терминальные состояния &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\delta(\varepsilon, a) = a&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;a \in P&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta(a, b) = b&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;ab \not\in N&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Если &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; содержит пустую строку, то множество терминальных состояний &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;S \cup \{ \varepsilon \}&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Автомат &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; – стандартный локальный автомат, распознающий &amp;lt;tex&amp;gt;L&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;a&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;\delta(s, a)&amp;lt;/tex&amp;gt; либо неопределена либо равна &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;. По построению автомат является стандартным. &amp;lt;br&amp;gt;&lt;br /&gt;
Покажем, что &amp;lt;tex&amp;gt;L(\mathcal{A}) = L&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;x = a_1 \ldots a_n \in L(\mathcal{A})&amp;lt;/tex&amp;gt;. Тогда в автомате существует путь: &amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;tex&amp;gt;\varepsilon \xrightarrow{a_1} a_1 \xrightarrow{a_2} a_2 \ldots a_{n-1} \xrightarrow{a_n} a_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Здесь &amp;lt;tex&amp;gt;a_n&amp;lt;/tex&amp;gt; {{---}} терминальное состояние, &amp;lt;tex&amp;gt;a_n \in S&amp;lt;/tex&amp;gt;. Переход из &amp;lt;tex&amp;gt;\varepsilon&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;a_1&amp;lt;/tex&amp;gt; определен, поэтому &amp;lt;tex&amp;gt;a_1 \in P&amp;lt;/tex&amp;gt;. Для каждого &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; такого что &amp;lt;tex&amp;gt;1 \leqslant j \leqslant n - 1&amp;lt;/tex&amp;gt; факт, что переход &amp;lt;tex&amp;gt;a_j \rightarrow a_{j+1}&amp;lt;/tex&amp;gt; существует, означает что &amp;lt;tex&amp;gt;a_j a_{j+1} \not \in N&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;Следовательно, &amp;lt;tex&amp;gt;x \in L&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Язык, распознаваемый локальным автоматом, является локальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Алгоритм Глушкова==&lt;br /&gt;
===Описание===&lt;br /&gt;
Дано регулярное выражение &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Алгоритм Глушкова строит недетерминированный автомат, который распознает язык &amp;lt;tex&amp;gt;L(e)&amp;lt;/tex&amp;gt;, распознаваемый &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Построение происходит в несколько шагов:&lt;br /&gt;
# Линеаризация регулярного выражения. Каждый символ из алфавита, содержащийся в регулярном выражении, переименовывается таким образом, что каждый символ содержится в новом регулярном выражении не более одного раза. Пусть &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; {{---}} исходный алфавит, &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; {{---}} новый алфавит.&lt;br /&gt;
# Вычисление множеств &amp;lt;tex&amp;gt;P(e'), S(e'), N(e')&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;e'&amp;lt;/tex&amp;gt; {{---}} линеаризованное регулярное выражение. &amp;lt;tex&amp;gt;P(e')&amp;lt;/tex&amp;gt; {{---}} множество символов, с которых начинается слово из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;S(e')&amp;lt;/tex&amp;gt; {{---}} множество символов, на которые оканчивается слово из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;N(e')&amp;lt;/tex&amp;gt; {{---}} множество пар символов, которые встречаются в слове из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt;. Более формально: &amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;P(e')=\{a\in B\mid aB^*\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;S(e')=\{a\in B\mid B^*a\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;N(e')=\{u\in B^2\mid B^*uB^*\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Вычисление множества &amp;lt;tex&amp;gt;\Lambda(e')&amp;lt;/tex&amp;gt; такого что &amp;lt;tex&amp;gt;\Lambda(e')=\{\varepsilon\}\cap L(e')&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Вычисление локального языка с заданными множествами и построение по нему автомата.&lt;br /&gt;
# Делинеаризация, переименование каждого символа из &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; в соответствующий ему символ из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
===Пример работы===&lt;br /&gt;
[[Файл:Glushkov_lin_automata.jpg|frame|right|Автомат, построенный в ходе работы алгоритма Глушкова]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим регулярное выражение &amp;lt;tex&amp;gt;e = (a(ab)^*)^* + (ba)^*&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Линеаризуем его путем добавления индекса к каждому символу:&lt;br /&gt;
:&amp;lt;tex&amp;gt;e'=(a_1(a_2b_3)^*)^*+(b_4a_5)^*&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2. Составим множества &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt;:&lt;br /&gt;
:&amp;lt;tex&amp;gt;P(e')=\{a_1,b_4\}&amp;lt;/tex&amp;gt;,&amp;lt;br /&amp;gt;&lt;br /&gt;
:&amp;lt;tex&amp;gt;S(e')=\{a_1,b_3,a_5\}&amp;lt;/tex&amp;gt;,&amp;lt;br /&amp;gt;&lt;br /&gt;
:&amp;lt;tex&amp;gt;N(e')=\{a_1a_2, a_1a_1, a_2b_3, b_3a_1,b_3a_2,b_4a_5,a_5b_4\}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как пустое слово принадлежит языку, то &amp;lt;math&amp;gt;\Lambda(e')=\{\varepsilon\}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
3. Автомат локального языка &amp;lt;tex&amp;gt;L'=P'B^*\cap B^*S'\setminus B^*(B^2\setminus N')B^*&amp;lt;/tex&amp;gt; содержит начальное состояние, обозначенное как &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, и состояния для каждого из пяти символов алфавита &amp;lt;tex&amp;gt;B=\{a_1, a_2, b_3, b_4, a_5\}&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
В построенном автомате существует переход из &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; (соответствующего пустой строке) в два состояния из &amp;lt;tex&amp;gt;P'&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;ab \in N'&amp;lt;/tex&amp;gt;, три состояния &amp;lt;math&amp;gt;S'&amp;lt;/math&amp;gt; терминальные (как и состояние &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
4. Получим автомат для &amp;lt;tex&amp;gt;L(e)&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;
* Mark V. Lawson {{---}} Finite Automata&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Glushkov's_construction_algorithm Wikipedia {{---}} Glushkov's construction algorithm]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D1%8B&amp;diff=59596</id>
		<title>Локальные автоматы</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D1%8B&amp;diff=59596"/>
				<updated>2017-01-14T11:29:16Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Описание==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Граф Майхилла &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; (над алфавитом &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;)''' (англ. ''Myhill graph'') {{---}} [[Основные определения теории графов | ориентированный граф]], удовлетворяющий свойствам:&lt;br /&gt;
# Для каждой упорядоченной пары вершин &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; существует только одно ребро из &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Некоторые вершины обозначены начальными, а некоторые {{---}} конечными. Ребро может одновременно быть начальным и конечным.&lt;br /&gt;
# Вершины обозначены различными символами из конечного алфавита &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;, то есть мы можем обращаться к вершине по ее символу.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;G&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;c \in \Sigma&amp;lt;/tex&amp;gt; назовем разрешенным, если им помечена вершина, являющая одновременно начальной и конечной.&lt;br /&gt;
&lt;br /&gt;
Не пустая строка &amp;lt;tex&amp;gt;c_1c_2...c_n&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;\Sigma^*&amp;lt;/tex&amp;gt; длиной не менее двух символов, называется разрешенной, если символом &amp;lt;tex&amp;gt;c_1&amp;lt;/tex&amp;gt; отмечена стартовая вершина, а символом &amp;lt;tex&amp;gt;c_n&amp;lt;/tex&amp;gt; {{---}} конечная, и для всех &amp;lt;tex&amp;gt;1 \leqslant i \leqslant n - 1&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; существует ребро &amp;lt;tex&amp;gt;(c_i, c_{i+1})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Язык &amp;lt;tex&amp;gt;L(G)&amp;lt;/tex&amp;gt;, распознаваемый графом Майхилла, состоит из всех разрешенных строк из  &amp;lt;tex&amp;gt;\Sigma^+&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Покажем, что графы Майхилла могут быть представлены в виде автоматов. &lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A = (S,  \Sigma, i, \delta, T)&amp;lt;/tex&amp;gt; {{---}} [[Детерминированные_конечные_автоматы | ДКА]].&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition= Автомат &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; называется '''локальным''' (англ. ''local automaton'', ''Glushkov automaton''), если для любого &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; из  &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt; множество &amp;lt;tex&amp;gt;\{\delta(s, c) \mid s \in S\}&amp;lt;/tex&amp;gt; содержит не более одного элемента. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=Локальный автомат &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; называется '''стандартным локальным''' автоматом (англ. ''standard local automation''), если в нем нет перехода в начальное состояние.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Таким образом, автомат является локальным, если для каждого &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; из  &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt; нет переходов, отмеченных &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;, или если все они ведут в одно состояние.&lt;br /&gt;
&lt;br /&gt;
Покажем, что граф Майхилла может быть преобразован в стандартный локальный автомат таким образом, что распознаваемый им язык не изменится.&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Язык распознается графом Майхилла тогда и только тогда, когда он распознается стандартным локальным автоматом, стартовое состояние которого не является терминальным.&lt;br /&gt;
|proof=&lt;br /&gt;
&amp;lt;tex&amp;gt;\Rightarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:Пусть &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; {{---}} граф Майхилла. &lt;br /&gt;
:Построим автомат &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; следующим образом: &lt;br /&gt;
:* Добавим вершину &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; с ребрами от &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; к каждой стартовой вершине &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;; отметим вершину &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; как стартовое состояние.&lt;br /&gt;
:* Отметим конечные вершины как терминальные состояния.&lt;br /&gt;
:* Отметим каждое ребро результирующего ориентированного графа символом, стоящим в вершине, на которою оно указывает. &lt;br /&gt;
:Переходы преобразуются следующим образом: [[Файл:Myhill1.png|150px]]&lt;br /&gt;
&lt;br /&gt;
:По построению стартовое состояние не является терминальным. &lt;br /&gt;
&lt;br /&gt;
:Покажем, что полученный автомат конечен. &lt;br /&gt;
:Ребра, выходящие из стартового состояния обозначены различными символами, потому что они указывают на вершины, которые, по свойству 3, были отмечены различными символами в исходном автомате.&lt;br /&gt;
:Если мы рассмотрим любое другое состояние &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;, то два перехода из &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; могут иметь одинаковые метки только в том случае, если в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; оба ориентированных ребра идут в одну и ту же вершину. Но этого не может быть по свойтсву 1. &lt;br /&gt;
:То есть &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; {{---}} [[Детерминированные_конечные_автоматы | ДКА]]. По построению он является стандартным локальным автоматом. &lt;br /&gt;
:Теперь просто проверить, что &amp;lt;tex&amp;gt;L(A) = L(G)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\Leftarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:Пусть &amp;lt;tex&amp;gt;A = (S, \Sigma, i, \delta, T)&amp;lt;/tex&amp;gt; {{---}} стандартный локальный автомат, стартовое состояние которого не является терминальным.&lt;br /&gt;
:Построим по нему граф Майхилла следующим образом:&lt;br /&gt;
:* Отметим все состояния &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, кроме стартового, &amp;lt;tex&amp;gt;input&amp;lt;/tex&amp;gt; символами, стоящими на ребрах, входящих в эти состояния. &lt;br /&gt;
:* Сотрем все метки на ребрах &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
:* Отметим все состояния &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; как начальные вершины, если существует переход из &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;&lt;br /&gt;
:* Отметим все терминальные состояния как конечные вершины.&lt;br /&gt;
:* Удалим вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и все ребра, исходящие из нее.&lt;br /&gt;
:Назовем полученный граф &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; {{---}} он будет графом Майхилла по построению. Легко проверить, что &amp;lt;tex&amp;gt;L(G) = L(A)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Пример==&lt;br /&gt;
{| cellpadding=&amp;quot;3&amp;quot; style=&amp;quot;margin-left: auto; margin-right: auto;&amp;quot;&lt;br /&gt;
| [[Файл:Myhill2.png|300px|thumb|right|Рисунок 1]] &lt;br /&gt;
| [[Файл:Myhill3.png|200px|thumb|right|Рисунок 2]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Граф Майхилла, изображенный на рисунке 1 может быть использован для распознавания строк над алфавитом &amp;lt;tex&amp;gt;\Sigma = \{a, b\}&amp;lt;/tex&amp;gt;. По определению, язык, распознаваемый данным графом, состоит из непустых строк, начинающихся и заканчивающихся на &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Недетерминированный автомат на рисунке 2 является локальным автоматом и распознает тот же самый язык.&lt;br /&gt;
&lt;br /&gt;
==Локальный язык==&lt;br /&gt;
Рассмотрим язык, распознаваемый стандартным локальным автоматом. &lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=Язык &amp;lt;tex&amp;gt;L \subseteq A^*&amp;lt;/tex&amp;gt; называется '''локальным языком''' (англ. ''local language''), если &amp;lt;tex&amp;gt;L \setminus \varepsilon&amp;lt;/tex&amp;gt; может быть описан следующим образом:  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\exists P, S \subseteq A, N \subseteq A^2: L \setminus \varepsilon = (P A^* \cap A^* S) \setminus A^* N A^*&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Другими словами, непустое слово принадлежит локальному языку, если оно начинается с символа из &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, оканчивается на символ из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; и не содержит пары символов из множества &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L = (P A^* \cap A^* S) \setminus A^* N A^*&amp;lt;/tex&amp;gt; {{---}} локальный язык. Определим автомат &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; следующим образом:&lt;br /&gt;
* набор состояний &amp;lt;tex&amp;gt;Q = A \cup \{ \varepsilon \}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* начальное состояние &amp;lt;tex&amp;gt;\varepsilon&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* терминальные состояния &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\delta(\varepsilon, a) = a&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;a \in P&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta(a, b) = b&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;ab \not\in N&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Если &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; содержит пустую строку, то множество терминальных состояний &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;S \cup \{ \varepsilon \}&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Автомат &amp;lt;tex&amp;gt;\mathcal{A}&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=Язык, распознаваемый локальным автоматом, является локальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Алгоритм Глушкова==&lt;br /&gt;
===Описание===&lt;br /&gt;
Дано регулярное выражение &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Алгоритм Глушкова строит недетерминированный автомат, который распознает язык &amp;lt;tex&amp;gt;L(e)&amp;lt;/tex&amp;gt;, распознаваемый &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Построение происходит в несколько шагов:&lt;br /&gt;
# Линеаризация регулярного выражения. Каждый символ из алфавита, содержащийся в регулярном выражении, переименовывается таким образом, что каждый символ содержится в новом регулярном выражении не более одного раза. Пусть &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; {{---}} исходный алфавит, &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; {{---}} новый алфавит.&lt;br /&gt;
# Вычисление множеств &amp;lt;tex&amp;gt;P(e'), S(e'), N(e')&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;e'&amp;lt;/tex&amp;gt; {{---}} линеаризованное регулярное выражение. &amp;lt;tex&amp;gt;P(e')&amp;lt;/tex&amp;gt; {{---}} множество символов, с которых начинается слово из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;S(e')&amp;lt;/tex&amp;gt; {{---}} множество символов, на которые оканчивается слово из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;N(e')&amp;lt;/tex&amp;gt; {{---}} множество пар символов, которые встречаются в слове из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt;. Более формально: &amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;P(e')=\{a\in B\mid aB^*\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;S(e')=\{a\in B\mid B^*a\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;N(e')=\{u\in B^2\mid B^*uB^*\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Вычисление множества &amp;lt;tex&amp;gt;\Lambda(e')&amp;lt;/tex&amp;gt; такого что &amp;lt;tex&amp;gt;\Lambda(e')=\{\varepsilon\}\cap L(e')&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Вычисление локального языка с заданными множествами и построение по нему автомата.&lt;br /&gt;
# Делинеаризация, переименование каждого символа из &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; в соответствующий ему символ из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
===Пример работы===&lt;br /&gt;
[[Файл:Glushkov_lin_automata.jpg|frame|right|Автомат, построенный в ходе работы алгоритма Глушкова]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим регулярное выражение &amp;lt;tex&amp;gt;e = (a(ab)^*)^* + (ba)^*&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Линеаризуем его путем добавления индекса к каждому символу:&lt;br /&gt;
:&amp;lt;tex&amp;gt;e'=(a_1(a_2b_3)^*)^*+(b_4a_5)^*&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2. Составим множества &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt;:&lt;br /&gt;
:&amp;lt;tex&amp;gt;P(e')=\{a_1,b_4\}&amp;lt;/tex&amp;gt;,&amp;lt;br /&amp;gt;&lt;br /&gt;
:&amp;lt;tex&amp;gt;S(e')=\{a_1,b_3,a_5\}&amp;lt;/tex&amp;gt;,&amp;lt;br /&amp;gt;&lt;br /&gt;
:&amp;lt;tex&amp;gt;N(e')=\{a_1a_2, a_1a_1, a_2b_3, b_3a_1,b_3a_2,b_4a_5,a_5b_4\}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как пустое слово принадлежит языку, то &amp;lt;math&amp;gt;\Lambda(e')=\{\varepsilon\}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
3. Автомат локального языка &amp;lt;tex&amp;gt;L'=P'B^*\cap B^*S'\setminus B^*(B^2\setminus N')B^*&amp;lt;/tex&amp;gt; содержит начальное состояние, обозначенное как &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, и состояния для каждого из пяти символов алфавита &amp;lt;tex&amp;gt;B=\{a_1, a_2, b_3, b_4, a_5\}&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
В построенном автомате существует переход из &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; (соответствующего пустой строке) в два состояния из &amp;lt;tex&amp;gt;P'&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;ab \in N'&amp;lt;/tex&amp;gt;, три состояния &amp;lt;math&amp;gt;S'&amp;lt;/math&amp;gt; терминальные (как и состояние &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
4. Получим автомат для &amp;lt;tex&amp;gt;L(e)&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;
* Mark V. Lawson {{---}} Finite Automata&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Glushkov's_construction_algorithm Wikipedia {{---}} Glushkov's construction algorithm]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D1%8B&amp;diff=59594</id>
		<title>Локальные автоматы</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D1%8B&amp;diff=59594"/>
				<updated>2017-01-13T23:00:14Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: /* Пример работы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Описание==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Граф Майхилла &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; (над алфавитом &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;)''' (англ. ''Myhill graph'') {{---}} [[Основные определения теории графов | ориентированный граф]], удовлетворяющий свойствам:&lt;br /&gt;
# Для каждой упорядоченной пары вершин &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; существует только одно ребро из &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Некоторые вершины обозначены начальными, а некоторые {{---}} конечными. Ребро может одновременно быть начальным и конечным.&lt;br /&gt;
# Вершины обозначены различными символами из конечного алфавита &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;, то есть мы можем обращаться к вершине по ее символу.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;G&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;c \in \Sigma&amp;lt;/tex&amp;gt; назовем разрешенным, если им помечена вершина, являющая одновременно начальной и конечной.&lt;br /&gt;
&lt;br /&gt;
Не пустая строка &amp;lt;tex&amp;gt;c_1c_2...c_n&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;\Sigma^*&amp;lt;/tex&amp;gt; длиной не менее двух символов, называется разрешенной, если символом &amp;lt;tex&amp;gt;c_1&amp;lt;/tex&amp;gt; отмечена стартовая вершина, а символом &amp;lt;tex&amp;gt;c_n&amp;lt;/tex&amp;gt; {{---}} конечная, и для всех &amp;lt;tex&amp;gt;1 \leqslant i \leqslant n - 1&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; существует ребро &amp;lt;tex&amp;gt;(c_i, c_{i+1})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Язык &amp;lt;tex&amp;gt;L(G)&amp;lt;/tex&amp;gt;, распознаваемый графом Майхилла, состоит из всех разрешенных строк из  &amp;lt;tex&amp;gt;\Sigma^+&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Покажем, что графы Майхилла могут быть представлены в виде автоматов. &lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A = (S,  \Sigma, i, \delta, T)&amp;lt;/tex&amp;gt; {{---}} [[Детерминированные_конечные_автоматы | ДКА]].&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition= Автомат &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''локальным''' (англ. ''local automation''), если для любого &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; из  &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt; множество &amp;lt;tex&amp;gt;\{\delta(s, c) \mid s \in S\}&amp;lt;/tex&amp;gt; содержит не более одного элемента. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition= Автомат &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''стандартным локальным''' автоматом (англ. ''standard local automation''), если в нем нет перехода в начальное состояние.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Таким образом, автомат является локальным, если для каждого &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; из  &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt; нет переходов, отмеченных &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;, или если все они ведут в одно состояние.&lt;br /&gt;
&lt;br /&gt;
Покажем, что граф Майхилла может быть преобразован в стандартный локальный автомат таким образом, что распознаваемый им язык не изменится.&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Язык распознается графом Майхилла тогда и только тогда, когда он распознается стандартным локальным автоматом, стартовое состояние которого не является терминальным.&lt;br /&gt;
|proof=&lt;br /&gt;
&amp;lt;tex&amp;gt;\Rightarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; {{---}} граф Майхилла. &lt;br /&gt;
Построим автомат &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; следующим образом: &lt;br /&gt;
* Добавим вершину &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; с ребрами от &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; к каждой стартовой вершине &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;; отметим вершину &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; как стартовое состояние.&lt;br /&gt;
* Отметим конечные вершины как терминальные состояния.&lt;br /&gt;
* Отметим каждое ребро результирующего ориентированного графа символом, стоящим в вершине, на которою оно указывает. &lt;br /&gt;
Переходы преобразуются следующим образом: [[Файл:Myhill1.png|150px]]&lt;br /&gt;
&lt;br /&gt;
По построению стартовое состояние не является терминальным. &lt;br /&gt;
&lt;br /&gt;
Покажем, что полученный автомат конечен. &lt;br /&gt;
Ребра, выходящие из стартового состояния обозначены различными символами, потому что они указывают на вершины, которые, по свойству 3, были отмечены различными символами в исходном автомате.&lt;br /&gt;
Если мы рассмотрим любое другое состояние &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;, то два перехода из &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; могут иметь одинаковые метки только в том случае, если в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; оба ориентированных ребра идут в одну и ту же вершину. Но этого не может быть по свойтсву 1. &lt;br /&gt;
То есть &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; {{---}} [[Детерминированные_конечные_автоматы | ДКА]]. По построению он является стандартным локальным автоматом. &lt;br /&gt;
Теперь просто проверить, что &amp;lt;tex&amp;gt;L(A) = L(G)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\Leftarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A = (S, \Sigma, i, \delta, T)&amp;lt;/tex&amp;gt; {{---}} стандартный локальный автомат, стартовое состояние которого не является терминальным.&lt;br /&gt;
Построим по нему граф Майхилла следующим образом:&lt;br /&gt;
* Отметим все состояния &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, кроме стартового, &amp;lt;tex&amp;gt;input&amp;lt;/tex&amp;gt; символами, стоящими на ребрах, входящих в эти состояния. &lt;br /&gt;
* Сотрем все метки на ребрах &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Отметим все состояния &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; как начальные вершины, если существует переход из &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;&lt;br /&gt;
* Отметим все терминальные состояния как конечные вершины.&lt;br /&gt;
* Удалим вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и все ребра, исходящие из нее.&lt;br /&gt;
Назовем полученный граф &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; {{---}} он будет графом Майхилла по построению. Легко проверить, что &amp;lt;tex&amp;gt;L(G) = L(A)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Пример==&lt;br /&gt;
{| cellpadding=&amp;quot;3&amp;quot; style=&amp;quot;margin-left: auto; margin-right: auto;&amp;quot;&lt;br /&gt;
| [[Файл:Myhill2.png|300px|thumb|right|Рисунок 1]] &lt;br /&gt;
| [[Файл:Myhill3.png|200px|thumb|right|Рисунок 2]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Граф, изображенный на рисунке 1 может быть использован для распознавания строк над алфавитом &amp;lt;tex&amp;gt;\Sigma = \{a, b\}&amp;lt;/tex&amp;gt;. По определению, язык, распознаваемый данным графом, состоит из непустых строк, начинающихся и заканчивающихся на &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим детерменированный конечный автомат, представленный на рисунке 2. &lt;br /&gt;
Не сложно проверить, что он распознает тот же язык, что и граф на рисунке 1.&lt;br /&gt;
&lt;br /&gt;
==Локальный язык==&lt;br /&gt;
Рассмотрим язык, распознаваемый стандартным локальным автоматом. &lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=Язык &amp;lt;tex&amp;gt;L \subseteq A^*&amp;lt;/tex&amp;gt; называется '''локальным языком''' (англ. ''local language''), если &amp;lt;tex&amp;gt;L \setminus \varepsilon&amp;lt;/tex&amp;gt; может быть описан следующим образом:  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\exists P, S \subseteq A, N \subseteq A^2: L \setminus \varepsilon = (P A^* \cap A^* S) \setminus A^* N A^*&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Другими словами, непустое слово принадлежит локальному языку, если оно начинается с символа из &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, оканчивается на символ из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; и не содержит пары символов из множества &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L = (P A^* \cap A^* S) \setminus A^* N A^*&amp;lt;/tex&amp;gt; {{---}} локальный язык. Определим автомат &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; следующим образом:&lt;br /&gt;
* набор состояний &amp;lt;tex&amp;gt;Q = A \cup \{ \varepsilon \}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* начальное состояние &amp;lt;tex&amp;gt;\varepsilon&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* терминальные состояния &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\delta(\varepsilon, a) = a&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;a \in P&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta(a, b) = b&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;ab \not\in N&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Если &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; содержит пустую строку, то множество терминальных состояний &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;S \cup \{ \varepsilon \}&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Автомат &amp;lt;tex&amp;gt;\mathcal{A}&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=Язык, распознаваемый локальным автоматом, является локальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Алгоритм Глушкова==&lt;br /&gt;
===Описание===&lt;br /&gt;
Дано регулярное выражение &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Алгоритм Глушкова строит недетерминированный автомат, который распознает язык &amp;lt;tex&amp;gt;L(e)&amp;lt;/tex&amp;gt;, распознаваемый &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Построение происходит в несколько шагов:&lt;br /&gt;
# Линеаризация регулярного выражения. Каждый символ из алфавита, содержащийся в регулярном выражении, переименовывается таким образом, что каждый символ содержится в новом регулярном выражении не более одного раза. Пусть &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; {{---}} исходный алфавит, &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; {{---}} новый алфавит.&lt;br /&gt;
# Вычисление множеств &amp;lt;tex&amp;gt;P(e'), S(e'), N(e')&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;e'&amp;lt;/tex&amp;gt; {{---}} линеаризованное регулярное выражение. &amp;lt;tex&amp;gt;P(e')&amp;lt;/tex&amp;gt; {{---}} множество символов, с которых начинается слово из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;S(e')&amp;lt;/tex&amp;gt; {{---}} множество символов, на которые оканчивается слово из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;N(e')&amp;lt;/tex&amp;gt; {{---}} множество пар символов, которые встречаются в слове из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt;. Более формально: &amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;P(e')=\{a\in B\mid aB^*\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;S(e')=\{a\in B\mid B^*a\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;N(e')=\{u\in B^2\mid B^*uB^*\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Вычисление множества &amp;lt;tex&amp;gt;\Lambda(e')&amp;lt;/tex&amp;gt; такого что &amp;lt;tex&amp;gt;\Lambda(e')=\{\varepsilon\}\cap L(e')&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Вычисление локального языка с заданными множествами и построение по нему автомата.&lt;br /&gt;
# Делинеаризация, переименование каждого символа из &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; в соответствующий ему символ из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
===Пример работы===&lt;br /&gt;
[[Файл:Glushkov_lin_automata.jpg|frame|right|Автомат, построенный в ходе работы алгоритма Глушкова]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим регулярное выражение &amp;lt;tex&amp;gt;e = (a(ab)^*)^* + (ba)^*&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Линеаризуем его путем добавления индекса к каждому символу:&lt;br /&gt;
:&amp;lt;tex&amp;gt;e'=(a_1(a_2b_3)^*)^*+(b_4a_5)^*&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2. Составим множества &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt;:&lt;br /&gt;
:&amp;lt;tex&amp;gt;P(e')=\{a_1,b_4\}&amp;lt;/tex&amp;gt;,&amp;lt;br /&amp;gt;&lt;br /&gt;
:&amp;lt;tex&amp;gt;S(e')=\{a_1,b_3,a_5\}&amp;lt;/tex&amp;gt;,&amp;lt;br /&amp;gt;&lt;br /&gt;
:&amp;lt;tex&amp;gt;N(e')=\{a_1a_2, a_1a_1, a_2b_3, b_3a_1,b_3a_2,b_4a_5,a_5b_4\}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как пустое слово принадлежит языку, то &amp;lt;math&amp;gt;\Lambda(e')=\{\varepsilon\}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
3. Автомат локального языка &amp;lt;tex&amp;gt;L'=P'B^*\cap B^*S'\setminus B^*(B^2\setminus N')B^*&amp;lt;/tex&amp;gt; содержит начальное состояние, обозначенное как &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, и состояния для каждого из пяти символов алфавита &amp;lt;tex&amp;gt;B=\{a_1, a_2, b_3, b_4, a_5\}&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
В построенном автомате существует переход из &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; (соответствующего пустой строке) в два состояния из &amp;lt;tex&amp;gt;P'&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;ab \in N'&amp;lt;/tex&amp;gt;, три состояния &amp;lt;math&amp;gt;S'&amp;lt;/math&amp;gt; терминальные (как и состояние &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
4. Получим автомат для &amp;lt;tex&amp;gt;L(e)&amp;lt;/tex&amp;gt;, удалив индексы, добавленные на первом этапе.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[Контексты и синтаксические моноиды]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* Хопкрофт Д., Мотвани Р., Ульман Д. Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. {{---}} М.:Издательский дом «Вильямс», 2002.&lt;br /&gt;
* Mark V. Lawson Finite Automata, стр 132.&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Glushkov_lin_automata.jpg&amp;diff=59593</id>
		<title>Файл:Glushkov lin automata.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:Glushkov_lin_automata.jpg&amp;diff=59593"/>
				<updated>2017-01-13T22:57:54Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: загружена новая версия «Файл:Glushkov lin automata.jpg»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Glushkov_lin_automata.jpg&amp;diff=59592</id>
		<title>Файл:Glushkov lin automata.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:Glushkov_lin_automata.jpg&amp;diff=59592"/>
				<updated>2017-01-13T22:51:53Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: загружена новая версия «Файл:Glushkov lin automata.jpg»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Glushkov_lin_automata.jpg&amp;diff=59591</id>
		<title>Файл:Glushkov lin automata.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:Glushkov_lin_automata.jpg&amp;diff=59591"/>
				<updated>2017-01-13T22:39:01Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D1%8B&amp;diff=59590</id>
		<title>Локальные автоматы</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D1%8B&amp;diff=59590"/>
				<updated>2017-01-13T22:33:29Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: /* Локальный язык */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Описание==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Граф Майхилла &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; (над алфавитом &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;)''' (англ. ''Myhill graph'') {{---}} [[Основные определения теории графов | ориентированный граф]], удовлетворяющий свойствам:&lt;br /&gt;
# Для каждой упорядоченной пары вершин &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; существует только одно ребро из &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Некоторые вершины обозначены начальными, а некоторые {{---}} конечными. Ребро может одновременно быть начальным и конечным.&lt;br /&gt;
# Вершины обозначены различными символами из конечного алфавита &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;, то есть мы можем обращаться к вершине по ее символу.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;G&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;c \in \Sigma&amp;lt;/tex&amp;gt; назовем разрешенным, если им помечена вершина, являющая одновременно начальной и конечной.&lt;br /&gt;
&lt;br /&gt;
Не пустая строка &amp;lt;tex&amp;gt;c_1c_2...c_n&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;\Sigma^*&amp;lt;/tex&amp;gt; длиной не менее двух символов, называется разрешенной, если символом &amp;lt;tex&amp;gt;c_1&amp;lt;/tex&amp;gt; отмечена стартовая вершина, а символом &amp;lt;tex&amp;gt;c_n&amp;lt;/tex&amp;gt; {{---}} конечная, и для всех &amp;lt;tex&amp;gt;1 \leqslant i \leqslant n - 1&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; существует ребро &amp;lt;tex&amp;gt;(c_i, c_{i+1})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Язык &amp;lt;tex&amp;gt;L(G)&amp;lt;/tex&amp;gt;, распознаваемый графом Майхилла, состоит из всех разрешенных строк из  &amp;lt;tex&amp;gt;\Sigma^+&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Покажем, что графы Майхилла могут быть представлены в виде автоматов. &lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A = (S,  \Sigma, i, \delta, T)&amp;lt;/tex&amp;gt; {{---}} [[Детерминированные_конечные_автоматы | ДКА]].&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition= Автомат &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''локальным''' (англ. ''local automation''), если для любого &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; из  &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt; множество &amp;lt;tex&amp;gt;\{\delta(s, c) \mid s \in S\}&amp;lt;/tex&amp;gt; содержит не более одного элемента. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition= Автомат &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''стандартным локальным''' автоматом (англ. ''standard local automation''), если в нем нет перехода в начальное состояние.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Таким образом, автомат является локальным, если для каждого &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; из  &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt; нет переходов, отмеченных &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;, или если все они ведут в одно состояние.&lt;br /&gt;
&lt;br /&gt;
Покажем, что граф Майхилла может быть преобразован в стандартный локальный автомат таким образом, что распознаваемый им язык не изменится.&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Язык распознается графом Майхилла тогда и только тогда, когда он распознается стандартным локальным автоматом, стартовое состояние которого не является терминальным.&lt;br /&gt;
|proof=&lt;br /&gt;
&amp;lt;tex&amp;gt;\Rightarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; {{---}} граф Майхилла. &lt;br /&gt;
Построим автомат &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; следующим образом: &lt;br /&gt;
* Добавим вершину &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; с ребрами от &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; к каждой стартовой вершине &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;; отметим вершину &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; как стартовое состояние.&lt;br /&gt;
* Отметим конечные вершины как терминальные состояния.&lt;br /&gt;
* Отметим каждое ребро результирующего ориентированного графа символом, стоящим в вершине, на которою оно указывает. &lt;br /&gt;
Переходы преобразуются следующим образом: [[Файл:Myhill1.png|150px]]&lt;br /&gt;
&lt;br /&gt;
По построению стартовое состояние не является терминальным. &lt;br /&gt;
&lt;br /&gt;
Покажем, что полученный автомат конечен. &lt;br /&gt;
Ребра, выходящие из стартового состояния обозначены различными символами, потому что они указывают на вершины, которые, по свойству 3, были отмечены различными символами в исходном автомате.&lt;br /&gt;
Если мы рассмотрим любое другое состояние &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;, то два перехода из &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; могут иметь одинаковые метки только в том случае, если в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; оба ориентированных ребра идут в одну и ту же вершину. Но этого не может быть по свойтсву 1. &lt;br /&gt;
То есть &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; {{---}} [[Детерминированные_конечные_автоматы | ДКА]]. По построению он является стандартным локальным автоматом. &lt;br /&gt;
Теперь просто проверить, что &amp;lt;tex&amp;gt;L(A) = L(G)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\Leftarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A = (S, \Sigma, i, \delta, T)&amp;lt;/tex&amp;gt; {{---}} стандартный локальный автомат, стартовое состояние которого не является терминальным.&lt;br /&gt;
Построим по нему граф Майхилла следующим образом:&lt;br /&gt;
* Отметим все состояния &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, кроме стартового, &amp;lt;tex&amp;gt;input&amp;lt;/tex&amp;gt; символами, стоящими на ребрах, входящих в эти состояния. &lt;br /&gt;
* Сотрем все метки на ребрах &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Отметим все состояния &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; как начальные вершины, если существует переход из &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;&lt;br /&gt;
* Отметим все терминальные состояния как конечные вершины.&lt;br /&gt;
* Удалим вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и все ребра, исходящие из нее.&lt;br /&gt;
Назовем полученный граф &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; {{---}} он будет графом Майхилла по построению. Легко проверить, что &amp;lt;tex&amp;gt;L(G) = L(A)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Пример==&lt;br /&gt;
{| cellpadding=&amp;quot;3&amp;quot; style=&amp;quot;margin-left: auto; margin-right: auto;&amp;quot;&lt;br /&gt;
| [[Файл:Myhill2.png|300px|thumb|right|Рисунок 1]] &lt;br /&gt;
| [[Файл:Myhill3.png|200px|thumb|right|Рисунок 2]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Граф, изображенный на рисунке 1 может быть использован для распознавания строк над алфавитом &amp;lt;tex&amp;gt;\Sigma = \{a, b\}&amp;lt;/tex&amp;gt;. По определению, язык, распознаваемый данным графом, состоит из непустых строк, начинающихся и заканчивающихся на &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим детерменированный конечный автомат, представленный на рисунке 2. &lt;br /&gt;
Не сложно проверить, что он распознает тот же язык, что и граф на рисунке 1.&lt;br /&gt;
&lt;br /&gt;
==Локальный язык==&lt;br /&gt;
Рассмотрим язык, распознаваемый стандартным локальным автоматом. &lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=Язык &amp;lt;tex&amp;gt;L \subseteq A^*&amp;lt;/tex&amp;gt; называется '''локальным языком''' (англ. ''local language''), если &amp;lt;tex&amp;gt;L \setminus \varepsilon&amp;lt;/tex&amp;gt; может быть описан следующим образом:  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\exists P, S \subseteq A, N \subseteq A^2: L \setminus \varepsilon = (P A^* \cap A^* S) \setminus A^* N A^*&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Другими словами, непустое слово принадлежит локальному языку, если оно начинается с символа из &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, оканчивается на символ из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; и не содержит пары символов из множества &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L = (P A^* \cap A^* S) \setminus A^* N A^*&amp;lt;/tex&amp;gt; {{---}} локальный язык. Определим автомат &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; следующим образом:&lt;br /&gt;
* набор состояний &amp;lt;tex&amp;gt;Q = A \cup \{ \varepsilon \}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* начальное состояние &amp;lt;tex&amp;gt;\varepsilon&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* терминальные состояния &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\delta(\varepsilon, a) = a&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;a \in P&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta(a, b) = b&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;ab \not\in N&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Если &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; содержит пустую строку, то множество терминальных состояний &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;S \cup \{ \varepsilon \}&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Автомат &amp;lt;tex&amp;gt;\mathcal{A}&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=Язык, распознаваемый локальным автоматом, является локальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Алгоритм Глушкова==&lt;br /&gt;
===Описание===&lt;br /&gt;
Дано регулярное выражение &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Алгоритм Глушкова строит недетерминированный автомат, который распознает язык &amp;lt;tex&amp;gt;L(e)&amp;lt;/tex&amp;gt;, распознаваемый &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Построение происходит в несколько шагов:&lt;br /&gt;
# Линеаризация регулярного выражения. Каждый символ из алфавита, содержащийся в регулярном выражении, переименовывается таким образом, что каждый символ содержится в новом регулярном выражении не более одного раза. Пусть &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; {{---}} исходный алфавит, &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; {{---}} новый алфавит.&lt;br /&gt;
# Вычисление множеств &amp;lt;tex&amp;gt;P(e'), S(e'), N(e')&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;e'&amp;lt;/tex&amp;gt; {{---}} линеаризованное регулярное выражение. &amp;lt;tex&amp;gt;P(e')&amp;lt;/tex&amp;gt; {{---}} множество символов, с которых начинается слово из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;S(e')&amp;lt;/tex&amp;gt; {{---}} множество символов, на которые оканчивается слово из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;N(e')&amp;lt;/tex&amp;gt; {{---}} множество пар символов, которые встречаются в слове из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt;. Более формально: &amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;P(e')=\{a\in B\mid aB^*\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;S(e')=\{a\in B\mid B^*a\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;N(e')=\{u\in B^2\mid B^*uB^*\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Вычисление множества &amp;lt;tex&amp;gt;\Lambda(e')&amp;lt;/tex&amp;gt; такого что &amp;lt;tex&amp;gt;\Lambda(e')=\{\varepsilon\}\cap L(e')&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Вычисление локального языка с заданными множествами и построение по нему автомата.&lt;br /&gt;
# Делинеаризация, переименование каждого символа из &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; в соответствующий ему символ из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
===Пример работы===&lt;br /&gt;
Рассмотрим регулярное выражение &amp;lt;tex&amp;gt;e = (a(ab)^*)^* + (ba)^*&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Линеаризуем его путем добавления индекса к каждому символу:&lt;br /&gt;
:&amp;lt;tex&amp;gt;e'=(a_1(a_2b_3)^*)^*+(b_4a_5)^*&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2. Составим множества &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt;:&lt;br /&gt;
:&amp;lt;tex&amp;gt;P(e')=\{a_1,b_4\}&amp;lt;/tex&amp;gt;,&amp;lt;br /&amp;gt;&lt;br /&gt;
:&amp;lt;tex&amp;gt;S(e')=\{a_1,b_3,a_5\}&amp;lt;/tex&amp;gt;,&amp;lt;br /&amp;gt;&lt;br /&gt;
:&amp;lt;tex&amp;gt;N(e')=\{a_1a_2, a_1a_1, a_2b_3, b_3a_1,b_3a_2,b_4a_5,a_5b_4\}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как пустое слово принадлежит языку, то &amp;lt;math&amp;gt;\Lambda(e')=\{\varepsilon\}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
3. Автомат локального языка &amp;lt;tex&amp;gt;L'=P'B^*\cap B^*S'\setminus B^*(B^2\setminus N')B^*&amp;lt;/tex&amp;gt; содержит начальное состояние, обозначенное как &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, и состояния для каждого из пяти символов алфавита &amp;lt;tex&amp;gt;B=\{a_1, a_2, b_3, b_4, a_5\}&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
В построенном автомате существует переход из &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; (соответствующего пустой строке) в два состояния из &amp;lt;tex&amp;gt;P'&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;ab \in N'&amp;lt;/tex&amp;gt;, три состояния &amp;lt;math&amp;gt;S'&amp;lt;/math&amp;gt; терминальные (как и состояние &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
4. Получим автомат для &amp;lt;tex&amp;gt;L(e)&amp;lt;/tex&amp;gt; удалив индексы, добавленные на первом этапе.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[Контексты и синтаксические моноиды]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* Хопкрофт Д., Мотвани Р., Ульман Д. Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. {{---}} М.:Издательский дом «Вильямс», 2002.&lt;br /&gt;
* Mark V. Lawson Finite Automata, стр 132.&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D1%8B&amp;diff=59589</id>
		<title>Локальные автоматы</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D1%8B&amp;diff=59589"/>
				<updated>2017-01-13T22:31:41Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: /* Пример работы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Описание==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Граф Майхилла &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; (над алфавитом &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;)''' (англ. ''Myhill graph'') {{---}} [[Основные определения теории графов | ориентированный граф]], удовлетворяющий свойствам:&lt;br /&gt;
# Для каждой упорядоченной пары вершин &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; существует только одно ребро из &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Некоторые вершины обозначены начальными, а некоторые {{---}} конечными. Ребро может одновременно быть начальным и конечным.&lt;br /&gt;
# Вершины обозначены различными символами из конечного алфавита &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;, то есть мы можем обращаться к вершине по ее символу.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;G&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;c \in \Sigma&amp;lt;/tex&amp;gt; назовем разрешенным, если им помечена вершина, являющая одновременно начальной и конечной.&lt;br /&gt;
&lt;br /&gt;
Не пустая строка &amp;lt;tex&amp;gt;c_1c_2...c_n&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;\Sigma^*&amp;lt;/tex&amp;gt; длиной не менее двух символов, называется разрешенной, если символом &amp;lt;tex&amp;gt;c_1&amp;lt;/tex&amp;gt; отмечена стартовая вершина, а символом &amp;lt;tex&amp;gt;c_n&amp;lt;/tex&amp;gt; {{---}} конечная, и для всех &amp;lt;tex&amp;gt;1 \leqslant i \leqslant n - 1&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; существует ребро &amp;lt;tex&amp;gt;(c_i, c_{i+1})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Язык &amp;lt;tex&amp;gt;L(G)&amp;lt;/tex&amp;gt;, распознаваемый графом Майхилла, состоит из всех разрешенных строк из  &amp;lt;tex&amp;gt;\Sigma^+&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Покажем, что графы Майхилла могут быть представлены в виде автоматов. &lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A = (S,  \Sigma, i, \delta, T)&amp;lt;/tex&amp;gt; {{---}} [[Детерминированные_конечные_автоматы | ДКА]].&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition= Автомат &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''локальным''' (англ. ''local automation''), если для любого &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; из  &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt; множество &amp;lt;tex&amp;gt;\{\delta(s, c) \mid s \in S\}&amp;lt;/tex&amp;gt; содержит не более одного элемента. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition= Автомат &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''стандартным локальным''' автоматом (англ. ''standard local automation''), если в нем нет перехода в начальное состояние.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Таким образом, автомат является локальным, если для каждого &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; из  &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt; нет переходов, отмеченных &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;, или если все они ведут в одно состояние.&lt;br /&gt;
&lt;br /&gt;
Покажем, что граф Майхилла может быть преобразован в стандартный локальный автомат таким образом, что распознаваемый им язык не изменится.&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Язык распознается графом Майхилла тогда и только тогда, когда он распознается стандартным локальным автоматом, стартовое состояние которого не является терминальным.&lt;br /&gt;
|proof=&lt;br /&gt;
&amp;lt;tex&amp;gt;\Rightarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; {{---}} граф Майхилла. &lt;br /&gt;
Построим автомат &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; следующим образом: &lt;br /&gt;
* Добавим вершину &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; с ребрами от &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; к каждой стартовой вершине &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;; отметим вершину &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; как стартовое состояние.&lt;br /&gt;
* Отметим конечные вершины как терминальные состояния.&lt;br /&gt;
* Отметим каждое ребро результирующего ориентированного графа символом, стоящим в вершине, на которою оно указывает. &lt;br /&gt;
Переходы преобразуются следующим образом: [[Файл:Myhill1.png|150px]]&lt;br /&gt;
&lt;br /&gt;
По построению стартовое состояние не является терминальным. &lt;br /&gt;
&lt;br /&gt;
Покажем, что полученный автомат конечен. &lt;br /&gt;
Ребра, выходящие из стартового состояния обозначены различными символами, потому что они указывают на вершины, которые, по свойству 3, были отмечены различными символами в исходном автомате.&lt;br /&gt;
Если мы рассмотрим любое другое состояние &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;, то два перехода из &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; могут иметь одинаковые метки только в том случае, если в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; оба ориентированных ребра идут в одну и ту же вершину. Но этого не может быть по свойтсву 1. &lt;br /&gt;
То есть &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; {{---}} [[Детерминированные_конечные_автоматы | ДКА]]. По построению он является стандартным локальным автоматом. &lt;br /&gt;
Теперь просто проверить, что &amp;lt;tex&amp;gt;L(A) = L(G)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\Leftarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A = (S, \Sigma, i, \delta, T)&amp;lt;/tex&amp;gt; {{---}} стандартный локальный автомат, стартовое состояние которого не является терминальным.&lt;br /&gt;
Построим по нему граф Майхилла следующим образом:&lt;br /&gt;
* Отметим все состояния &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, кроме стартового, &amp;lt;tex&amp;gt;input&amp;lt;/tex&amp;gt; символами, стоящими на ребрах, входящих в эти состояния. &lt;br /&gt;
* Сотрем все метки на ребрах &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Отметим все состояния &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; как начальные вершины, если существует переход из &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;&lt;br /&gt;
* Отметим все терминальные состояния как конечные вершины.&lt;br /&gt;
* Удалим вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и все ребра, исходящие из нее.&lt;br /&gt;
Назовем полученный граф &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; {{---}} он будет графом Майхилла по построению. Легко проверить, что &amp;lt;tex&amp;gt;L(G) = L(A)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Пример==&lt;br /&gt;
{| cellpadding=&amp;quot;3&amp;quot; style=&amp;quot;margin-left: auto; margin-right: auto;&amp;quot;&lt;br /&gt;
| [[Файл:Myhill2.png|300px|thumb|right|Рисунок 1]] &lt;br /&gt;
| [[Файл:Myhill3.png|200px|thumb|right|Рисунок 2]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Граф, изображенный на рисунке 1 может быть использован для распознавания строк над алфавитом &amp;lt;tex&amp;gt;\Sigma = \{a, b\}&amp;lt;/tex&amp;gt;. По определению, язык, распознаваемый данным графом, состоит из непустых строк, начинающихся и заканчивающихся на &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим детерменированный конечный автомат, представленный на рисунке 2. &lt;br /&gt;
Не сложно проверить, что он распознает тот же язык, что и граф на рисунке 1.&lt;br /&gt;
&lt;br /&gt;
==Локальный язык==&lt;br /&gt;
Рассмотрим язык, распознаваемый стандартным локальным автоматом. &lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=Язык &amp;lt;tex&amp;gt;L \subseteq A^*&amp;lt;/tex&amp;gt; называется '''локальным языком''' (англ. ''local language''), если &amp;lt;tex&amp;gt;L \backslash \varepsilon&amp;lt;/tex&amp;gt; может быть описан следующим образом:  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\exists P, S \subseteq A, N \subseteq A^2: L \backslash \varepsilon = (P A^* \cap A^* S) \backslash A^* N A^*&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Другими словами, непустое слово принадлежит локальному языку, если оно начинается с символа из &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, оканчивается на символ из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; и не содержит пары символов из множества &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L = (P A^* \cap A^* S) \backslash A^* N A^*&amp;lt;/tex&amp;gt; {{---}} локальный язык. Определим автомат &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; следующим образом:&lt;br /&gt;
* набор состояний &amp;lt;tex&amp;gt;Q = A \cup \{ \varepsilon \}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* начальное состояние &amp;lt;tex&amp;gt;\varepsilon&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* терминальные состояния &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\delta(\varepsilon, a) = a&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;a \in P&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta(a, b) = b&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;ab \not\in N&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Если &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; содержит пустую строку, то множество терминальных состояний &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;S \cup \{ \varepsilon \}&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Автомат &amp;lt;tex&amp;gt;\mathcal{A}&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=Язык, распознаваемый локальным автоматом, является локальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Алгоритм Глушкова==&lt;br /&gt;
===Описание===&lt;br /&gt;
Дано регулярное выражение &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Алгоритм Глушкова строит недетерминированный автомат, который распознает язык &amp;lt;tex&amp;gt;L(e)&amp;lt;/tex&amp;gt;, распознаваемый &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Построение происходит в несколько шагов:&lt;br /&gt;
# Линеаризация регулярного выражения. Каждый символ из алфавита, содержащийся в регулярном выражении, переименовывается таким образом, что каждый символ содержится в новом регулярном выражении не более одного раза. Пусть &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; {{---}} исходный алфавит, &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; {{---}} новый алфавит.&lt;br /&gt;
# Вычисление множеств &amp;lt;tex&amp;gt;P(e'), S(e'), N(e')&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;e'&amp;lt;/tex&amp;gt; {{---}} линеаризованное регулярное выражение. &amp;lt;tex&amp;gt;P(e')&amp;lt;/tex&amp;gt; {{---}} множество символов, с которых начинается слово из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;S(e')&amp;lt;/tex&amp;gt; {{---}} множество символов, на которые оканчивается слово из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;N(e')&amp;lt;/tex&amp;gt; {{---}} множество пар символов, которые встречаются в слове из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt;. Более формально: &amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;P(e')=\{a\in B\mid aB^*\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;S(e')=\{a\in B\mid B^*a\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;N(e')=\{u\in B^2\mid B^*uB^*\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Вычисление множества &amp;lt;tex&amp;gt;\Lambda(e')&amp;lt;/tex&amp;gt; такого что &amp;lt;tex&amp;gt;\Lambda(e')=\{\varepsilon\}\cap L(e')&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Вычисление локального языка с заданными множествами и построение по нему автомата.&lt;br /&gt;
# Делинеаризация, переименование каждого символа из &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; в соответствующий ему символ из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
===Пример работы===&lt;br /&gt;
Рассмотрим регулярное выражение &amp;lt;tex&amp;gt;e = (a(ab)^*)^* + (ba)^*&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Линеаризуем его путем добавления индекса к каждому символу:&lt;br /&gt;
:&amp;lt;tex&amp;gt;e'=(a_1(a_2b_3)^*)^*+(b_4a_5)^*&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2. Составим множества &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt;:&lt;br /&gt;
:&amp;lt;tex&amp;gt;P(e')=\{a_1,b_4\}&amp;lt;/tex&amp;gt;,&amp;lt;br /&amp;gt;&lt;br /&gt;
:&amp;lt;tex&amp;gt;S(e')=\{a_1,b_3,a_5\}&amp;lt;/tex&amp;gt;,&amp;lt;br /&amp;gt;&lt;br /&gt;
:&amp;lt;tex&amp;gt;N(e')=\{a_1a_2, a_1a_1, a_2b_3, b_3a_1,b_3a_2,b_4a_5,a_5b_4\}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как пустое слово принадлежит языку, то &amp;lt;math&amp;gt;\Lambda(e')=\{\varepsilon\}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
3. Автомат локального языка &amp;lt;tex&amp;gt;L'=P'B^*\cap B^*S'\setminus B^*(B^2\setminus N')B^*&amp;lt;/tex&amp;gt; содержит начальное состояние, обозначенное как &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, и состояния для каждого из пяти символов алфавита &amp;lt;tex&amp;gt;B=\{a_1, a_2, b_3, b_4, a_5\}&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
В построенном автомате существует переход из &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; (соответствующего пустой строке) в два состояния из &amp;lt;tex&amp;gt;P'&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;ab \in N'&amp;lt;/tex&amp;gt;, три состояния &amp;lt;math&amp;gt;S'&amp;lt;/math&amp;gt; терминальные (как и состояние &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
4. Получим автомат для &amp;lt;tex&amp;gt;L(e)&amp;lt;/tex&amp;gt; удалив индексы, добавленные на первом этапе.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[Контексты и синтаксические моноиды]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* Хопкрофт Д., Мотвани Р., Ульман Д. Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. {{---}} М.:Издательский дом «Вильямс», 2002.&lt;br /&gt;
* Mark V. Lawson Finite Automata, стр 132.&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D1%8B&amp;diff=59588</id>
		<title>Локальные автоматы</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D1%8B&amp;diff=59588"/>
				<updated>2017-01-13T22:31:01Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: /* Алгоритм Глушкова */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Описание==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Граф Майхилла &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; (над алфавитом &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;)''' (англ. ''Myhill graph'') {{---}} [[Основные определения теории графов | ориентированный граф]], удовлетворяющий свойствам:&lt;br /&gt;
# Для каждой упорядоченной пары вершин &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; существует только одно ребро из &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Некоторые вершины обозначены начальными, а некоторые {{---}} конечными. Ребро может одновременно быть начальным и конечным.&lt;br /&gt;
# Вершины обозначены различными символами из конечного алфавита &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;, то есть мы можем обращаться к вершине по ее символу.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;G&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;c \in \Sigma&amp;lt;/tex&amp;gt; назовем разрешенным, если им помечена вершина, являющая одновременно начальной и конечной.&lt;br /&gt;
&lt;br /&gt;
Не пустая строка &amp;lt;tex&amp;gt;c_1c_2...c_n&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;\Sigma^*&amp;lt;/tex&amp;gt; длиной не менее двух символов, называется разрешенной, если символом &amp;lt;tex&amp;gt;c_1&amp;lt;/tex&amp;gt; отмечена стартовая вершина, а символом &amp;lt;tex&amp;gt;c_n&amp;lt;/tex&amp;gt; {{---}} конечная, и для всех &amp;lt;tex&amp;gt;1 \leqslant i \leqslant n - 1&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; существует ребро &amp;lt;tex&amp;gt;(c_i, c_{i+1})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Язык &amp;lt;tex&amp;gt;L(G)&amp;lt;/tex&amp;gt;, распознаваемый графом Майхилла, состоит из всех разрешенных строк из  &amp;lt;tex&amp;gt;\Sigma^+&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Покажем, что графы Майхилла могут быть представлены в виде автоматов. &lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A = (S,  \Sigma, i, \delta, T)&amp;lt;/tex&amp;gt; {{---}} [[Детерминированные_конечные_автоматы | ДКА]].&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition= Автомат &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''локальным''' (англ. ''local automation''), если для любого &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; из  &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt; множество &amp;lt;tex&amp;gt;\{\delta(s, c) \mid s \in S\}&amp;lt;/tex&amp;gt; содержит не более одного элемента. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition= Автомат &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''стандартным локальным''' автоматом (англ. ''standard local automation''), если в нем нет перехода в начальное состояние.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Таким образом, автомат является локальным, если для каждого &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; из  &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt; нет переходов, отмеченных &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;, или если все они ведут в одно состояние.&lt;br /&gt;
&lt;br /&gt;
Покажем, что граф Майхилла может быть преобразован в стандартный локальный автомат таким образом, что распознаваемый им язык не изменится.&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Язык распознается графом Майхилла тогда и только тогда, когда он распознается стандартным локальным автоматом, стартовое состояние которого не является терминальным.&lt;br /&gt;
|proof=&lt;br /&gt;
&amp;lt;tex&amp;gt;\Rightarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; {{---}} граф Майхилла. &lt;br /&gt;
Построим автомат &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; следующим образом: &lt;br /&gt;
* Добавим вершину &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; с ребрами от &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; к каждой стартовой вершине &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;; отметим вершину &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; как стартовое состояние.&lt;br /&gt;
* Отметим конечные вершины как терминальные состояния.&lt;br /&gt;
* Отметим каждое ребро результирующего ориентированного графа символом, стоящим в вершине, на которою оно указывает. &lt;br /&gt;
Переходы преобразуются следующим образом: [[Файл:Myhill1.png|150px]]&lt;br /&gt;
&lt;br /&gt;
По построению стартовое состояние не является терминальным. &lt;br /&gt;
&lt;br /&gt;
Покажем, что полученный автомат конечен. &lt;br /&gt;
Ребра, выходящие из стартового состояния обозначены различными символами, потому что они указывают на вершины, которые, по свойству 3, были отмечены различными символами в исходном автомате.&lt;br /&gt;
Если мы рассмотрим любое другое состояние &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;, то два перехода из &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; могут иметь одинаковые метки только в том случае, если в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; оба ориентированных ребра идут в одну и ту же вершину. Но этого не может быть по свойтсву 1. &lt;br /&gt;
То есть &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; {{---}} [[Детерминированные_конечные_автоматы | ДКА]]. По построению он является стандартным локальным автоматом. &lt;br /&gt;
Теперь просто проверить, что &amp;lt;tex&amp;gt;L(A) = L(G)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\Leftarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A = (S, \Sigma, i, \delta, T)&amp;lt;/tex&amp;gt; {{---}} стандартный локальный автомат, стартовое состояние которого не является терминальным.&lt;br /&gt;
Построим по нему граф Майхилла следующим образом:&lt;br /&gt;
* Отметим все состояния &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, кроме стартового, &amp;lt;tex&amp;gt;input&amp;lt;/tex&amp;gt; символами, стоящими на ребрах, входящих в эти состояния. &lt;br /&gt;
* Сотрем все метки на ребрах &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Отметим все состояния &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; как начальные вершины, если существует переход из &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;&lt;br /&gt;
* Отметим все терминальные состояния как конечные вершины.&lt;br /&gt;
* Удалим вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и все ребра, исходящие из нее.&lt;br /&gt;
Назовем полученный граф &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; {{---}} он будет графом Майхилла по построению. Легко проверить, что &amp;lt;tex&amp;gt;L(G) = L(A)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Пример==&lt;br /&gt;
{| cellpadding=&amp;quot;3&amp;quot; style=&amp;quot;margin-left: auto; margin-right: auto;&amp;quot;&lt;br /&gt;
| [[Файл:Myhill2.png|300px|thumb|right|Рисунок 1]] &lt;br /&gt;
| [[Файл:Myhill3.png|200px|thumb|right|Рисунок 2]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Граф, изображенный на рисунке 1 может быть использован для распознавания строк над алфавитом &amp;lt;tex&amp;gt;\Sigma = \{a, b\}&amp;lt;/tex&amp;gt;. По определению, язык, распознаваемый данным графом, состоит из непустых строк, начинающихся и заканчивающихся на &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим детерменированный конечный автомат, представленный на рисунке 2. &lt;br /&gt;
Не сложно проверить, что он распознает тот же язык, что и граф на рисунке 1.&lt;br /&gt;
&lt;br /&gt;
==Локальный язык==&lt;br /&gt;
Рассмотрим язык, распознаваемый стандартным локальным автоматом. &lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=Язык &amp;lt;tex&amp;gt;L \subseteq A^*&amp;lt;/tex&amp;gt; называется '''локальным языком''' (англ. ''local language''), если &amp;lt;tex&amp;gt;L \backslash \varepsilon&amp;lt;/tex&amp;gt; может быть описан следующим образом:  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\exists P, S \subseteq A, N \subseteq A^2: L \backslash \varepsilon = (P A^* \cap A^* S) \backslash A^* N A^*&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Другими словами, непустое слово принадлежит локальному языку, если оно начинается с символа из &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, оканчивается на символ из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; и не содержит пары символов из множества &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L = (P A^* \cap A^* S) \backslash A^* N A^*&amp;lt;/tex&amp;gt; {{---}} локальный язык. Определим автомат &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; следующим образом:&lt;br /&gt;
* набор состояний &amp;lt;tex&amp;gt;Q = A \cup \{ \varepsilon \}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* начальное состояние &amp;lt;tex&amp;gt;\varepsilon&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* терминальные состояния &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\delta(\varepsilon, a) = a&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;a \in P&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta(a, b) = b&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;ab \not\in N&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Если &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; содержит пустую строку, то множество терминальных состояний &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;S \cup \{ \varepsilon \}&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Автомат &amp;lt;tex&amp;gt;\mathcal{A}&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=Язык, распознаваемый локальным автоматом, является локальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Алгоритм Глушкова==&lt;br /&gt;
===Описание===&lt;br /&gt;
Дано регулярное выражение &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Алгоритм Глушкова строит недетерминированный автомат, который распознает язык &amp;lt;tex&amp;gt;L(e)&amp;lt;/tex&amp;gt;, распознаваемый &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Построение происходит в несколько шагов:&lt;br /&gt;
# Линеаризация регулярного выражения. Каждый символ из алфавита, содержащийся в регулярном выражении, переименовывается таким образом, что каждый символ содержится в новом регулярном выражении не более одного раза. Пусть &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; {{---}} исходный алфавит, &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; {{---}} новый алфавит.&lt;br /&gt;
# Вычисление множеств &amp;lt;tex&amp;gt;P(e'), S(e'), N(e')&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;e'&amp;lt;/tex&amp;gt; {{---}} линеаризованное регулярное выражение. &amp;lt;tex&amp;gt;P(e')&amp;lt;/tex&amp;gt; {{---}} множество символов, с которых начинается слово из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;S(e')&amp;lt;/tex&amp;gt; {{---}} множество символов, на которые оканчивается слово из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;N(e')&amp;lt;/tex&amp;gt; {{---}} множество пар символов, которые встречаются в слове из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt;. Более формально: &amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;P(e')=\{a\in B\mid aB^*\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;S(e')=\{a\in B\mid B^*a\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;N(e')=\{u\in B^2\mid B^*uB^*\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Вычисление множества &amp;lt;tex&amp;gt;\Lambda(e')&amp;lt;/tex&amp;gt; такого что &amp;lt;tex&amp;gt;\Lambda(e')=\{\varepsilon\}\cap L(e')&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Вычисление локального языка с заданными множествами и построение по нему автомата.&lt;br /&gt;
# Делинеаризация, переименование каждого символа из &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; в соответствующий ему символ из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
===Пример работы===&lt;br /&gt;
Рассмотрим регулярное выражение &amp;lt;tex&amp;gt;e = (a(ab)^*)^* + (ba)^*&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Линеаризуем его путем добавления индекса к каждому символу:&lt;br /&gt;
:&amp;lt;tex&amp;gt;e'=(a_1(a_2b_3)^*)^*+(b_4a_5)^*&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2. Составим множества &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt;:&lt;br /&gt;
:&amp;lt;tex&amp;gt;P(e')=\{a_1,b_4\}&amp;lt;/tex&amp;gt;,&amp;lt;br /&amp;gt;&lt;br /&gt;
:&amp;lt;tex&amp;gt;S(e')=\{a_1,b_3,a_5\}&amp;lt;/tex&amp;gt;,&amp;lt;br /&amp;gt;&lt;br /&gt;
:&amp;lt;tex&amp;gt;N(e')=\{a_1a_2, a_1a_1, a_2b_3, b_3a_1,b_3a_2,b_4a_5,a_5b_4\}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как пустое слово принадлежит языку, то &amp;lt;math&amp;gt;\Lambda(e')=\{\varepsilon\}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
3. Автомат локального языка &amp;lt;tex&amp;gt;L'=P'B^*\cap B^*D'\setminus B^*(B^2\setminus F')B^*&amp;lt;/tex&amp;gt; содержит начальное состояние, обозначенное как &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, и состояния для каждого из пяти символов алфавита &amp;lt;tex&amp;gt;B=\{a_1, a_2, b_3, b_4, a_5\}&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
В построенном автомате существует переход из &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; (соответствующего пустой строке) в два состояния из &amp;lt;tex&amp;gt;P'&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;ab \in N'&amp;lt;/tex&amp;gt;, три состояния &amp;lt;math&amp;gt;S'&amp;lt;/math&amp;gt; терминальные (как и состояние &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
4. Получим автомат для &amp;lt;tex&amp;gt;L(e)&amp;lt;/tex&amp;gt; удалив индексы, добавленные на первом этапе.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[Контексты и синтаксические моноиды]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* Хопкрофт Д., Мотвани Р., Ульман Д. Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. {{---}} М.:Издательский дом «Вильямс», 2002.&lt;br /&gt;
* Mark V. Lawson Finite Automata, стр 132.&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D1%8B&amp;diff=59587</id>
		<title>Локальные автоматы</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D1%8B&amp;diff=59587"/>
				<updated>2017-01-13T22:08:23Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Описание==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Граф Майхилла &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; (над алфавитом &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;)''' (англ. ''Myhill graph'') {{---}} [[Основные определения теории графов | ориентированный граф]], удовлетворяющий свойствам:&lt;br /&gt;
# Для каждой упорядоченной пары вершин &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; существует только одно ребро из &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Некоторые вершины обозначены начальными, а некоторые {{---}} конечными. Ребро может одновременно быть начальным и конечным.&lt;br /&gt;
# Вершины обозначены различными символами из конечного алфавита &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;, то есть мы можем обращаться к вершине по ее символу.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;G&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;c \in \Sigma&amp;lt;/tex&amp;gt; назовем разрешенным, если им помечена вершина, являющая одновременно начальной и конечной.&lt;br /&gt;
&lt;br /&gt;
Не пустая строка &amp;lt;tex&amp;gt;c_1c_2...c_n&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;\Sigma^*&amp;lt;/tex&amp;gt; длиной не менее двух символов, называется разрешенной, если символом &amp;lt;tex&amp;gt;c_1&amp;lt;/tex&amp;gt; отмечена стартовая вершина, а символом &amp;lt;tex&amp;gt;c_n&amp;lt;/tex&amp;gt; {{---}} конечная, и для всех &amp;lt;tex&amp;gt;1 \leqslant i \leqslant n - 1&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; существует ребро &amp;lt;tex&amp;gt;(c_i, c_{i+1})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Язык &amp;lt;tex&amp;gt;L(G)&amp;lt;/tex&amp;gt;, распознаваемый графом Майхилла, состоит из всех разрешенных строк из  &amp;lt;tex&amp;gt;\Sigma^+&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Покажем, что графы Майхилла могут быть представлены в виде автоматов. &lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A = (S,  \Sigma, i, \delta, T)&amp;lt;/tex&amp;gt; {{---}} [[Детерминированные_конечные_автоматы | ДКА]].&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition= Автомат &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''локальным''' (англ. ''local automation''), если для любого &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; из  &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt; множество &amp;lt;tex&amp;gt;\{\delta(s, c) \mid s \in S\}&amp;lt;/tex&amp;gt; содержит не более одного элемента. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition= Автомат &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''стандартным локальным''' автоматом (англ. ''standard local automation''), если в нем нет перехода в начальное состояние.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Таким образом, автомат является локальным, если для каждого &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; из  &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt; нет переходов, отмеченных &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;, или если все они ведут в одно состояние.&lt;br /&gt;
&lt;br /&gt;
Покажем, что граф Майхилла может быть преобразован в стандартный локальный автомат таким образом, что распознаваемый им язык не изменится.&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Язык распознается графом Майхилла тогда и только тогда, когда он распознается стандартным локальным автоматом, стартовое состояние которого не является терминальным.&lt;br /&gt;
|proof=&lt;br /&gt;
&amp;lt;tex&amp;gt;\Rightarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; {{---}} граф Майхилла. &lt;br /&gt;
Построим автомат &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; следующим образом: &lt;br /&gt;
* Добавим вершину &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; с ребрами от &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; к каждой стартовой вершине &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;; отметим вершину &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; как стартовое состояние.&lt;br /&gt;
* Отметим конечные вершины как терминальные состояния.&lt;br /&gt;
* Отметим каждое ребро результирующего ориентированного графа символом, стоящим в вершине, на которою оно указывает. &lt;br /&gt;
Переходы преобразуются следующим образом: [[Файл:Myhill1.png|150px]]&lt;br /&gt;
&lt;br /&gt;
По построению стартовое состояние не является терминальным. &lt;br /&gt;
&lt;br /&gt;
Покажем, что полученный автомат конечен. &lt;br /&gt;
Ребра, выходящие из стартового состояния обозначены различными символами, потому что они указывают на вершины, которые, по свойству 3, были отмечены различными символами в исходном автомате.&lt;br /&gt;
Если мы рассмотрим любое другое состояние &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;, то два перехода из &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; могут иметь одинаковые метки только в том случае, если в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; оба ориентированных ребра идут в одну и ту же вершину. Но этого не может быть по свойтсву 1. &lt;br /&gt;
То есть &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; {{---}} [[Детерминированные_конечные_автоматы | ДКА]]. По построению он является стандартным локальным автоматом. &lt;br /&gt;
Теперь просто проверить, что &amp;lt;tex&amp;gt;L(A) = L(G)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\Leftarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A = (S, \Sigma, i, \delta, T)&amp;lt;/tex&amp;gt; {{---}} стандартный локальный автомат, стартовое состояние которого не является терминальным.&lt;br /&gt;
Построим по нему граф Майхилла следующим образом:&lt;br /&gt;
* Отметим все состояния &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, кроме стартового, &amp;lt;tex&amp;gt;input&amp;lt;/tex&amp;gt; символами, стоящими на ребрах, входящих в эти состояния. &lt;br /&gt;
* Сотрем все метки на ребрах &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Отметим все состояния &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; как начальные вершины, если существует переход из &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;&lt;br /&gt;
* Отметим все терминальные состояния как конечные вершины.&lt;br /&gt;
* Удалим вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и все ребра, исходящие из нее.&lt;br /&gt;
Назовем полученный граф &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; {{---}} он будет графом Майхилла по построению. Легко проверить, что &amp;lt;tex&amp;gt;L(G) = L(A)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Пример==&lt;br /&gt;
{| cellpadding=&amp;quot;3&amp;quot; style=&amp;quot;margin-left: auto; margin-right: auto;&amp;quot;&lt;br /&gt;
| [[Файл:Myhill2.png|300px|thumb|right|Рисунок 1]] &lt;br /&gt;
| [[Файл:Myhill3.png|200px|thumb|right|Рисунок 2]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Граф, изображенный на рисунке 1 может быть использован для распознавания строк над алфавитом &amp;lt;tex&amp;gt;\Sigma = \{a, b\}&amp;lt;/tex&amp;gt;. По определению, язык, распознаваемый данным графом, состоит из непустых строк, начинающихся и заканчивающихся на &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим детерменированный конечный автомат, представленный на рисунке 2. &lt;br /&gt;
Не сложно проверить, что он распознает тот же язык, что и граф на рисунке 1.&lt;br /&gt;
&lt;br /&gt;
==Локальный язык==&lt;br /&gt;
Рассмотрим язык, распознаваемый стандартным локальным автоматом. &lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=Язык &amp;lt;tex&amp;gt;L \subseteq A^*&amp;lt;/tex&amp;gt; называется '''локальным языком''' (англ. ''local language''), если &amp;lt;tex&amp;gt;L \backslash \varepsilon&amp;lt;/tex&amp;gt; может быть описан следующим образом:  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\exists P, S \subseteq A, N \subseteq A^2: L \backslash \varepsilon = (P A^* \cap A^* S) \backslash A^* N A^*&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Другими словами, непустое слово принадлежит локальному языку, если оно начинается с символа из &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, оканчивается на символ из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; и не содержит пары символов из множества &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L = (P A^* \cap A^* S) \backslash A^* N A^*&amp;lt;/tex&amp;gt; {{---}} локальный язык. Определим автомат &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; следующим образом:&lt;br /&gt;
* набор состояний &amp;lt;tex&amp;gt;Q = A \cup \{ \varepsilon \}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* начальное состояние &amp;lt;tex&amp;gt;\varepsilon&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* терминальные состояния &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\delta(\varepsilon, a) = a&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;a \in P&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta(a, b) = b&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;ab \not\in N&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Если &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; содержит пустую строку, то множество терминальных состояний &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;S \cup \{ \varepsilon \}&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Автомат &amp;lt;tex&amp;gt;\mathcal{A}&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=Язык, распознаваемый локальным автоматом, является локальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Алгоритм Глушкова==&lt;br /&gt;
===Описание===&lt;br /&gt;
Дано регулярное выражение &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Алгоритм Глушкова строит недетерминированный автомат, который распознает язык &amp;lt;tex&amp;gt;L(e)&amp;lt;/tex&amp;gt;, распознаваемый &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Построение происходит в несколько шагов:&lt;br /&gt;
# Линеаризация регулярного выражения. Каждый символ из алфавита, содержащийся в регулярном выражении, переименовывается таким образом, что каждый символ содержится в новом регулярном выражении не более одного раза. Пусть &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; {{---}} исходный алфавит, &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; {{---}} новый алфавит.&lt;br /&gt;
# Вычисление множеств &amp;lt;tex&amp;gt;P(e'), D(e'), N(e')&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;e'&amp;lt;/tex&amp;gt; {{---}} линеаризованное регулярное выражение. &amp;lt;tex&amp;gt;P(e')&amp;lt;/tex&amp;gt; {{---}} множество символов, с которых начинается слово из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;S(e')&amp;lt;/tex&amp;gt; {{---}} множество символов, на которые оканчивается слово из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;N(e')&amp;lt;/tex&amp;gt; {{---}} множество пар символов, которые встречаются в слове из &amp;lt;tex&amp;gt;L(e')&amp;lt;/tex&amp;gt;. Более формально: &amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;P(e')=\{a\in B\mid aB^*\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;S(e')=\{a\in B\mid B^*a\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;,&amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;N(e')=\{u\in B^2\mid B^*uB^*\cap L(e')\ne\emptyset\}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Вычисление множества &amp;lt;tex&amp;gt;\Lambda(e')&amp;lt;/tex&amp;gt; такого что &amp;lt;tex&amp;gt;\Lambda(e')=\{\varepsilon\}\cap L(e')&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Вычисление локального языка с заданными множествами и построение по нему автомата.&lt;br /&gt;
# Делинеаризация, переименование каждого символа из &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; в соответствующий ему символ из &amp;lt;tex&amp;gt;A&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;
* Хопкрофт Д., Мотвани Р., Ульман Д. Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. {{---}} М.:Издательский дом «Вильямс», 2002.&lt;br /&gt;
* Mark V. Lawson Finite Automata, стр 132.&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D1%8B&amp;diff=59586</id>
		<title>Локальные автоматы</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D1%8B&amp;diff=59586"/>
				<updated>2017-01-13T21:24:35Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Описание==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Граф Майхилла &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; (над алфавитом &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;)''' (англ. ''Myhill graph'') {{---}} [[Основные определения теории графов | ориентированный граф]], удовлетворяющий свойствам:&lt;br /&gt;
# Для каждой упорядоченной пары вершин &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; существует только одно ребро из &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Некоторые вершины обозначены начальными, а некоторые {{---}} конечными. Ребро может одновременно быть начальным и конечным.&lt;br /&gt;
# Вершины обозначены различными символами из конечного алфавита &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;, то есть мы можем обращаться к вершине по ее символу.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;G&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;c \in \Sigma&amp;lt;/tex&amp;gt; назовем разрешенным, если им помечена вершина, являющая одновременно начальной и конечной.&lt;br /&gt;
&lt;br /&gt;
Не пустая строка &amp;lt;tex&amp;gt;c_1c_2...c_n&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;\Sigma^*&amp;lt;/tex&amp;gt; длиной не менее двух символов, называется разрешенной, если символом &amp;lt;tex&amp;gt;c_1&amp;lt;/tex&amp;gt; отмечена стартовая вершина, а символом &amp;lt;tex&amp;gt;c_n&amp;lt;/tex&amp;gt; {{---}} конечная, и для всех &amp;lt;tex&amp;gt;1 \leqslant i \leqslant n - 1&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; существует ребро &amp;lt;tex&amp;gt;(c_i, c_{i+1})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Язык &amp;lt;tex&amp;gt;L(G)&amp;lt;/tex&amp;gt;, распознаваемый графом Майхилла, состоит из всех разрешенных строк из  &amp;lt;tex&amp;gt;\Sigma^+&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Покажем, что графы Майхилла могут быть представлены в виде автоматов. &lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A = (S,  \Sigma, i, \delta, T)&amp;lt;/tex&amp;gt; {{---}} [[Детерминированные_конечные_автоматы | ДКА]].&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition= Автомат &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''локальным''' (англ. ''local automation''), если для любого &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; из  &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt; множество &amp;lt;tex&amp;gt;\{\delta(s, c) \mid s \in S\}&amp;lt;/tex&amp;gt; содержит не более одного элемента. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition= Автомат &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''стандартным локальным''' автоматом (англ. ''standard local automation''), если в нем нет перехода в начальное состояние.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Таким образом, автомат является локальным, если для каждого &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; из  &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt; нет переходов, отмеченных &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;, или если все они ведут в одно состояние.&lt;br /&gt;
&lt;br /&gt;
Покажем, что граф Майхилла может быть преобразован в стандартный локальный автомат таким образом, что распознаваемый им язык не изменится.&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Язык распознается графом Майхилла тогда и только тогда, когда он распознается стандартным локальным автоматом, стартовое состояние которого не является терминальным.&lt;br /&gt;
|proof=&lt;br /&gt;
&amp;lt;tex&amp;gt;\Rightarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; {{---}} граф Майхилла. &lt;br /&gt;
Построим автомат &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; следующим образом: &lt;br /&gt;
* Добавим вершину &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; с ребрами от &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; к каждой стартовой вершине &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;; отметим вершину &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; как стартовое состояние.&lt;br /&gt;
* Отметим конечные вершины как терминальные состояния.&lt;br /&gt;
* Отметим каждое ребро результирующего ориентированного графа символом, стоящим в вершине, на которою оно указывает. &lt;br /&gt;
Переходы преобразуются следующим образом: [[Файл:Myhill1.png|150px]]&lt;br /&gt;
&lt;br /&gt;
По построению стартовое состояние не является терминальным. &lt;br /&gt;
&lt;br /&gt;
Покажем, что полученный автомат конечен. &lt;br /&gt;
Ребра, выходящие из стартового состояния обозначены различными символами, потому что они указывают на вершины, которые, по свойству 3, были отмечены различными символами в исходном автомате.&lt;br /&gt;
Если мы рассмотрим любое другое состояние &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;, то два перехода из &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; могут иметь одинаковые метки только в том случае, если в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; оба ориентированных ребра идут в одну и ту же вершину. Но этого не может быть по свойтсву 1. &lt;br /&gt;
То есть &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; {{---}} [[Детерминированные_конечные_автоматы | ДКА]]. По построению он является стандартным локальным автоматом. &lt;br /&gt;
Теперь просто проверить, что &amp;lt;tex&amp;gt;L(A) = L(G)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\Leftarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A = (S, \Sigma, i, \delta, T)&amp;lt;/tex&amp;gt; {{---}} стандартный локальный автомат, стартовое состояние которого не является терминальным.&lt;br /&gt;
Построим по нему граф Майхилла следующим образом:&lt;br /&gt;
* Отметим все состояния &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, кроме стартового, &amp;lt;tex&amp;gt;input&amp;lt;/tex&amp;gt; символами, стоящими на ребрах, входящих в эти состояния. &lt;br /&gt;
* Сотрем все метки на ребрах &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Отметим все состояния &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; как начальные вершины, если существует переход из &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;&lt;br /&gt;
* Отметим все терминальные состояния как конечные вершины.&lt;br /&gt;
* Удалим вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и все ребра, исходящие из нее.&lt;br /&gt;
Назовем полученный граф &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; {{---}} он будет графом Майхилла по построению. Легко проверить, что &amp;lt;tex&amp;gt;L(G) = L(A)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Пример==&lt;br /&gt;
{| cellpadding=&amp;quot;3&amp;quot; style=&amp;quot;margin-left: auto; margin-right: auto;&amp;quot;&lt;br /&gt;
| [[Файл:Myhill2.png|300px|thumb|right|Рисунок 1]] &lt;br /&gt;
| [[Файл:Myhill3.png|200px|thumb|right|Рисунок 2]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Граф, изображенный на рисунке 1 может быть использован для распознавания строк над алфавитом &amp;lt;tex&amp;gt;\Sigma = \{a, b\}&amp;lt;/tex&amp;gt;. По определению, язык, распознаваемый данным графом, состоит из непустых строк, начинающихся и заканчивающихся на &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим детерменированный конечный автомат, представленный на рисунке 2. &lt;br /&gt;
Не сложно проверить, что он распознает тот же язык, что и граф на рисунке 1.&lt;br /&gt;
&lt;br /&gt;
==Локальный язык==&lt;br /&gt;
Рассмотрим язык, распознаваемый стандартным локальным автоматом. &lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=Язык &amp;lt;tex&amp;gt;L \subseteq A^*&amp;lt;/tex&amp;gt; называется '''локальным языком''' (англ. ''local language''), если &amp;lt;tex&amp;gt;L \backslash \varepsilon&amp;lt;/tex&amp;gt; может быть описан следующим образом:  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\exists P, S \subseteq A, N \subseteq A^2: L \backslash \varepsilon = (P A^* \bigcap A^* S) \backslash A^* N A^*&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Другими словами, непустое слово принадлежит локальному языку, если оно начинается с символа из &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, оканчивается на символ из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; и не содержит пары символов из множества &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L = (P A^* \bigcap A^* S) \backslash A^* N A^*&amp;lt;/tex&amp;gt; – локальный язык. Определим автомат &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; следующим образом:&lt;br /&gt;
* набор состояний &amp;lt;tex&amp;gt;Q = A \bigcup \{ \varepsilon \}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* начальное состояние &amp;lt;tex&amp;gt;\varepsilon&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* терминальные состояния &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\delta(\varepsilon, a) = a&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;a \in P&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\delta(a, b) = b&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt;ab \not\in N&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Если &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; содержит пустую строку, то множество терминальных состояний &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; – &amp;lt;tex&amp;gt;S \bigcup \{ \varepsilon \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|statement=Автомат &amp;lt;tex&amp;gt;\mathcal{A}&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=Язык, распознаваемый локальным автоматом, является локальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[Контексты и синтаксические моноиды]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* Хопкрофт Д., Мотвани Р., Ульман Д. Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. {{---}} М.:Издательский дом «Вильямс», 2002.&lt;br /&gt;
* Mark V. Lawson Finite Automata, стр 132.&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D1%8B&amp;diff=59585</id>
		<title>Локальные автоматы</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D1%8B&amp;diff=59585"/>
				<updated>2017-01-13T21:02:18Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Описание==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Граф Майхилла &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; (над алфавитом &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;)''' (англ. ''Myhill graph'') {{---}} [[Основные определения теории графов | ориентированный граф]], удовлетворяющий свойствам:&lt;br /&gt;
# Для каждой упорядоченной пары вершин &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; существует только одно ребро из &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Некоторые вершины обозначены начальными, а некоторые {{---}} конечными. Ребро может одновременно быть начальным и конечным.&lt;br /&gt;
# Вершины обозначены различными символами из конечного алфавита &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;, то есть мы можем обращаться к вершине по ее символу.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;G&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;c \in \Sigma&amp;lt;/tex&amp;gt; назовем разрешенным, если им помечена вершина, являющая одновременно начальной и конечной.&lt;br /&gt;
&lt;br /&gt;
Не пустая строка &amp;lt;tex&amp;gt;c_1c_2...c_n&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;\Sigma^*&amp;lt;/tex&amp;gt; длиной не менее двух символов, называется разрешенной, если символом &amp;lt;tex&amp;gt;c_1&amp;lt;/tex&amp;gt; отмечена стартовая вершина, а символом &amp;lt;tex&amp;gt;c_n&amp;lt;/tex&amp;gt; {{---}} конечная, и для всех &amp;lt;tex&amp;gt;1 \leqslant i \leqslant n - 1&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; существует ребро &amp;lt;tex&amp;gt;(c_i, c_{i+1})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Язык &amp;lt;tex&amp;gt;L(G)&amp;lt;/tex&amp;gt;, распознаваемый графом Майхилла, состоит из всех разрешенных строк из  &amp;lt;tex&amp;gt;\Sigma^+&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Покажем, что графы Майхилла могут быть представлены в виде автоматов. &lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A = (S,  \Sigma, i, \delta, T)&amp;lt;/tex&amp;gt; {{---}} [[Детерминированные_конечные_автоматы | ДКА]].&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition= Автомат &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''локальным''' (англ. ''local automation''), если для любого &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; из  &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt; множество &amp;lt;tex&amp;gt;\{\delta(s, c) \mid s \in S\}&amp;lt;/tex&amp;gt; содержит не более одного элемента. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition= Автомат &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''стандартным локальным''' автоматом (англ. ''standard local automation''), если в нем нет перехода в начальное состояние.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Таким образом, автомат является локальным, если для каждого &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; из  &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt; нет переходов, отмеченных &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;, или если все они ведут в одно состояние.&lt;br /&gt;
&lt;br /&gt;
Покажем, что граф Майхилла может быть преобразован в стандартный локальный автомат таким образом, что распознаваемый им язык не изменится.&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Язык распознается графом Майхилла тогда и только тогда, когда он распознается стандартным локальным автоматом, стартовое состояние которого не является терминальным.&lt;br /&gt;
|proof=&lt;br /&gt;
&amp;lt;tex&amp;gt;\Rightarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; {{---}} граф Майхилла. &lt;br /&gt;
Построим автомат &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; следующим образом: &lt;br /&gt;
* Добавим вершину &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; с ребрами от &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; к каждой стартовой вершине &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;; отметим вершину &amp;lt;tex&amp;gt;\Diamond&amp;lt;/tex&amp;gt; как стартовое состояние.&lt;br /&gt;
* Отметим конечные вершины как терминальные состояния.&lt;br /&gt;
* Отметим каждое ребро результирующего ориентированного графа символом, стоящим в вершине, на которою оно указывает. &lt;br /&gt;
Переходы преобразуются следующим образом: [[Файл:Myhill1.png|150px]]&lt;br /&gt;
&lt;br /&gt;
По построению стартовое состояние не является терминальным. &lt;br /&gt;
&lt;br /&gt;
Покажем, что полученный автомат конечен. &lt;br /&gt;
Ребра, выходящие из стартового состояния обозначены различными символами, потому что они указывают на вершины, которые, по свойству 3, были отмечены различными символами в исходном автомате.&lt;br /&gt;
Если мы рассмотрим любое другое состояние &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;, то два перехода из &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; могут иметь одинаковые метки только в том случае, если в &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; оба ориентированных ребра идут в одну и ту же вершину. Но этого не может быть по свойтсву 1. &lt;br /&gt;
То есть &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; {{---}} [[Детерминированные_конечные_автоматы | ДКА]]. По построению он является стандартным локальным автоматом. &lt;br /&gt;
Теперь просто проверить, что &amp;lt;tex&amp;gt;L(A) = L(G)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\Leftarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A = (S, \Sigma, i, \delta, T)&amp;lt;/tex&amp;gt; {{---}} стандартный локальный автомат, стартовое состояние которого не является терминальным.&lt;br /&gt;
Построим по нему граф Майхилла следующим образом:&lt;br /&gt;
* Отметим все состояния &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, кроме стартового, &amp;lt;tex&amp;gt;input&amp;lt;/tex&amp;gt; символами, стоящими на ребрах, входящих в эти состояния. &lt;br /&gt;
* Сотрем все метки на ребрах &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Отметим все состояния &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; как начальные вершины, если существует переход из &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;&lt;br /&gt;
* Отметим все терминальные состояния как конечные вершины.&lt;br /&gt;
* Удалим вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и все ребра, исходящие из нее.&lt;br /&gt;
Назовем полученный граф &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; {{---}} он будет графом Майхилла по построению. Легко проверить, что &amp;lt;tex&amp;gt;L(G) = L(A)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Пример==&lt;br /&gt;
{| cellpadding=&amp;quot;3&amp;quot; style=&amp;quot;margin-left: auto; margin-right: auto;&amp;quot;&lt;br /&gt;
| [[Файл:Myhill2.png|300px|thumb|right|Рисунок 1]] &lt;br /&gt;
| [[Файл:Myhill3.png|200px|thumb|right|Рисунок 2]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Граф, изображенный на рисунке 1 может быть использован для распознавания строк над алфавитом &amp;lt;tex&amp;gt;\Sigma = \{a, b\}&amp;lt;/tex&amp;gt;. По определению, язык, распознаваемый данным графом, состоит из непустых строк, начинающихся и заканчивающихся на &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим детерменированный конечный автомат, представленный на рисунке 2. &lt;br /&gt;
Не сложно проверить, что он распознает тот же язык, что и граф на рисунке 1.&lt;br /&gt;
&lt;br /&gt;
==Локальный язык==&lt;br /&gt;
Рассмотрим язык, распознаваемый стандартным локальным автоматом. &lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=Язык &amp;lt;tex&amp;gt;L \subseteq A^*&amp;lt;/tex&amp;gt; называется '''локальным языком''' (англ. ''local language''), если &amp;lt;tex&amp;gt;L \backslash \varepsilon&amp;lt;/tex&amp;gt; может быть описан следующим образом:  &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\exists P, S \subseteq A, N \subseteq A^2: L \backslash \varepsilon = (P A^* \bigcap A^* S) \backslash A^* N A^*&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Другими словами, непустое слово принадлежит локальному языку, если оно начинается с символа из &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, оканчивается на символ из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; и не содержит пары символов из множества &amp;lt;tex&amp;gt;N&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;
* Хопкрофт Д., Мотвани Р., Ульман Д. Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. {{---}} М.:Издательский дом «Вильямс», 2002.&lt;br /&gt;
* Mark V. Lawson Finite Automata, стр 132.&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55860</id>
		<title>Алгоритм Бржозовского</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55860"/>
				<updated>2016-11-13T13:35:23Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: /* Источники информации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Задача&lt;br /&gt;
|definition = &lt;br /&gt;
Пусть дан [[Детерминированные_конечные_автоматы|автомат]] &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;. Требуется построить автомат &amp;lt;tex&amp;gt;\mathcal{A}_{min}&amp;lt;/tex&amp;gt; с наименьшим количеством состояний, распознающий тот же язык, что и &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; {{---}} состояние автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q, s \in Q, T \subset Q, \delta : Q \times \Sigma \to Q \rangle&amp;lt;/tex&amp;gt;. &lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Правым языком''' (англ. ''right language'') называется язык &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;, распознаваемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; является уникальным начальным состоянием.&lt;br /&gt;
 }}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Левым языком''' (англ. ''left language'') называется язык &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, распознаваемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; является уникальным терминальным состоянием.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
Таким образом, допустимые слова языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, проходящие через состояние &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;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;y&amp;lt;/tex&amp;gt; из левого языка &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;. Тогда множество слов &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt; {{---}} [[Контексты_и_синтаксические_моноиды|правый контекст]] слова &amp;lt;tex&amp;gt;y&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;
|about=1&lt;br /&gt;
|statement=&lt;br /&gt;
Автомат является детерминированным тогда и только тогда, когда левые языки его состояний попарно не пересекаются.&lt;br /&gt;
|proof=Рассмотрим состояния &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 \neq q'&amp;lt;/tex&amp;gt;) в ДКА. Пусть левые языки этих состояний пересекаются, то есть &amp;lt;tex&amp;gt;L_g(q) \cap L_g(q') = \{ w \}&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;По окончании процесса допуска слова &amp;lt;tex&amp;gt;w&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;w&amp;lt;/tex&amp;gt;, а значит &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} НКА. Получаем противоречие.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратное слово''' (англ. ''reverse of the word'') &amp;lt;tex&amp;gt;r(u)&amp;lt;/tex&amp;gt; для слова &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; определяется следующим образом: &amp;lt;tex&amp;gt;r(\varepsilon) = \varepsilon&amp;lt;/tex&amp;gt; и если &amp;lt;tex&amp;gt;u = u_1 u_2 u_3 \dotsc u_p&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;r(u) = v_1 v_2 v_3 \dotsc v_p&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_i = u_{p - i + 1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный язык''' (англ. ''reverse of the language'') для языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} язык &amp;lt;tex&amp;gt;r(L) = \{ u \mid r(u) \in L \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный автомат''' (англ. ''reverse of the automaton'') для автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q , S , T , \delta \rangle&amp;lt;/tex&amp;gt; {{---}} автомат &amp;lt;tex&amp;gt;r(\mathcal{A}) = \langle \Sigma , Q , T , I , r(\delta) \rangle&amp;lt;/tex&amp;gt;, полученный из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; сменой местами начальных и конечных состояний и сменой направлений переходов.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=&lt;br /&gt;
Если &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; распознает язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt; распознает &amp;lt;tex&amp;gt;r(L)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=3&lt;br /&gt;
|statement=&lt;br /&gt;
Если левый язык состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, тогда его левый язык в &amp;lt;tex&amp;gt;r(A)&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;. Аналогично для правого языка &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q , I , T , \delta \rangle&amp;lt;/tex&amp;gt; {{---}} [[Недетерминированные_конечные_автоматы|НКА]].&amp;lt;br&amp;gt;Тогда детерминированный автомат &amp;lt;tex&amp;gt;d(\mathcal{A}) = \langle \Sigma , Q' , \{ i' \} , T' , \delta' \rangle&amp;lt;/tex&amp;gt; определяется следующим образом:&lt;br /&gt;
* Детерминированному состоянию соответствует множество недетерминированных состояний: для каждого &amp;lt;tex&amp;gt;q' \in Q'&amp;lt;/tex&amp;gt; имеем &amp;lt;tex&amp;gt;q' \subseteq Q&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* Начальное состояние в &amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} множество из &amp;lt;tex&amp;gt;I&amp;lt;/tex&amp;gt; начальных состояний автомата &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* Состояние в детерминированном автомате является терминальным тогда и только тогда, когда оно содержится хотя бы в одном недетерминированном состоянии,&lt;br /&gt;
* Пусть &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; {{---}} состояние детерминированного автомата и &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; – символ из &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;. Если переход из &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; по символу &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; определен, тогда, по построению: &amp;lt;tex&amp;gt;\delta'(q', a) = \bigcup\limits_{q \in q'}{ \delta(q, a)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=4&lt;br /&gt;
|statement=&lt;br /&gt;
Правый язык состояния &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; эквивалентен объединению правых языков состояний &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; автомата &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, принадлежащих множеству &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Левое отношение'''  (англ. ''left quotient'') регулярного языка &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;\Sigma^{*}&amp;lt;/tex&amp;gt; {{---}} язык &amp;lt;tex&amp;gt;u^{-1}L = \{ v \in X^{*} \mid uv \in L \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Минимальный автомат &amp;lt;tex&amp;gt;\mathcal{A}_{L}&amp;lt;/tex&amp;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;
* начальное состояние {{---}} &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* терминальные состояния {{---}} множество отношений, содержащих пустое слово,&lt;br /&gt;
* функция перехода &amp;lt;tex&amp;gt;\delta(u^{-1}L, x) = (ux)^{-1}L&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Автомат &amp;lt;tex&amp;gt;\mathcal{A}_L&amp;lt;/tex&amp;gt; уникален с точностью до изоморфизма и имеет минимальное количество состояний. &lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=5&lt;br /&gt;
|statement=&lt;br /&gt;
Детерминированный автомат минимален тогда и только тогда, когда правые языки его состояний различны и все состояния достижимы.&lt;br /&gt;
|proof=&lt;br /&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 \neq q'&amp;lt;/tex&amp;gt;) в ДКА. Пусть их правые языки &amp;lt;tex&amp;gt;L_d(q) = L_d(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;br&amp;gt;&lt;br /&gt;
Если состояние &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; недостижимо из начального состояния &amp;lt;tex&amp;gt;s&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;
===Описание===&lt;br /&gt;
Алгоритм минимизации конечных [[Детерминированные конечные автоматы|автоматов]] Бржозовского (Janusz A. (John) Brzozowski) выделяется, по крайней мере, следующими качествами:&lt;br /&gt;
* Он элегантен и весьма оригинален.&lt;br /&gt;
* Он эффективен.&lt;br /&gt;
* Он работает даже с [[Недетерминированные конечные автоматы|недетерминированными конечными автоматами]].&lt;br /&gt;
&lt;br /&gt;
Введём следующие обозначения:&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} конечный автомат,&lt;br /&gt;
*&amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} детерминизированный автомат для &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
*&amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} обратный автомат для &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
*&amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} результат &amp;lt;tex&amp;gt;d(r(\mathcal{A}))&amp;lt;/tex&amp;gt;. Аналогично для &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about=Бржозовский, 1962&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} автомат (необязательно детерминированный), распознающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Минимальный детерминированный автомат &amp;lt;tex&amp;gt;\mathcal{A}_L&amp;lt;/tex&amp;gt; может быть вычислен следующим образом: &amp;lt;tex&amp;gt;\mathcal{A}_L = drdr(\mathcal{A})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
По построению автомат &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; детерминированный. Согласно утверждению 2, он распознает язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt; &lt;br /&gt;
Покажем, что все правые языки &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; различны. Из утверждения 1, левые языки &amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt; попарно не пересекаются. Из утверждения 3, правые языки &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt; являются левыми языками &amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt;. Таким образом, они попарно не пересекаются. Согласно утверждению 4, правый язык &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} объединение правых языков &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Поскольку правые языки &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt; попарно не пересекаются, все правые языки &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; различны. &lt;br /&gt;
Так как все правые языки &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; различны, согласно утверждению 5 автомат &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; минимальный. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Пример работы===&lt;br /&gt;
# Исходный [[Недетерминированные конечные автоматы|НКА]] &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Fa.png|Исходный НКА]]&lt;br /&gt;
# Первый шаг, &amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Rfa.png|Первый шаг]]&lt;br /&gt;
# Второй шаг, &amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Drfa.png|Второй шаг]]&amp;lt;br&amp;gt;В детерминизированных автоматах состояния переименованы, так что &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; всегда является начальным состоянием.&lt;br /&gt;
# Третий шаг, &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Rdrfa.png|Третий шаг]]&amp;lt;br&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;
# Заключительный шаг, &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Drdrfa.png|Заключительный шаг]]&lt;br /&gt;
&lt;br /&gt;
== Заключение ==&lt;br /&gt;
Самым эффективным алгоритмом минимизации принято считать [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]], который, как и прочие традиционные алгоритмы, работает только с [[Детерминированные_конечные_автоматы|ДКА]]. Его асимптотическое время выполнения зависит от логарифма исходных данных. С другой стороны очевидно, что алгоритм Бржозовского в худшем случае будет обладать экспоненциальным временем выполнения, ведь этого требует процедура детерминизации, выполняемая дважды. На практике же наблюдается парадокс, алгоритм Бржозовского во многих случаях опережает прочие подходы к минимизации, включая и [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]]. В работе&amp;lt;ref&amp;gt;[http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=A511A421C93DF66BDCC32A0E133D1F99?doi=10.1.1.59.8276&amp;amp;rep=rep1&amp;amp;type=pdf Deian Tabakov, Moshe Y. Vardi. Experimental evaluation of classical automata constructions]&amp;lt;/ref&amp;gt;, сравнивающей оба алгоритма, показано, что алгоритм Бржозовского оказывается эффективнее [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритма Хопкрофта]] для автоматов с большим числом переходов.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Минимизация ДКА, алгоритм за O(n^2) с построением пар различимых состояний]]&lt;br /&gt;
*[[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))]]&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [https://pdfs.semanticscholar.org/f3be/b5e5825e6eedaab7f382341c9dd9c2ab33fa.pdf J.-M. Champarnaud, A. Khorsi, T. Paranthoen {{---}} Split and join for minimizing: Brzozowski's algorithm]&lt;br /&gt;
* [http://sovietov.com/txt/minfa/minfa.html Пётр Советов {{---}} Алгоритм Бржозовского для минимизации конечного автомата]&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;br /&gt;
[[Категория: Минимизация ДКА]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55845</id>
		<title>Удаление бесполезных символов из грамматики</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55845"/>
				<updated>2016-11-12T18:30:44Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Порождающие и непорождающие нетерминалы ==&lt;br /&gt;
===Описание===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
[[Формальные_грамматики|Нетерминал]] &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''порождающим''' (англ. ''generating''), если из него может быть выведена конечная терминальная цепочка. Иначе он называется '''непорождающим'''.&lt;br /&gt;
}}&lt;br /&gt;
Очевидно, что если и только если все нетерминалы правой части правила являются порождающими, то порождающим является и нетерминал, стоящий в его левой части. &lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих непорождающие нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Непорождающие нетерминалы по определению не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Алгоритм===&lt;br /&gt;
'''Шаг 0'''. Множество порождающих нетерминалов пустое.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 1'''. Находим правила, не содержащие нетерминалов в правых частях и добавляем нетерминалы, встречающихся в левых частях таких правил, в множество.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 2'''. Если найдено такое правило, что все нетерминалы, стоящие в его правой части, уже входят в множество, то добавим в множество нетерминалы, стоящие в его левой части. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 3'''. Повторим предыдущий шаг, если множество порождающих нетерминалов изменилось.&amp;lt;br&amp;gt;&lt;br /&gt;
В результате получаем множество всех порождающих нетерминалов грамматики, а все нетерминалы, не попавшие в него, являются непорождающими.&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\left| \Gamma \right|&amp;lt;/tex&amp;gt; {{---}} размер грамматики. Однако используя [[Очередь|очередь]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Модификация алгоритма с очередью===&lt;br /&gt;
Для реализации алгоритма поиска непорождающих нетерминалов будем использовать следующие структуры:&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{isGenerating[nonterm_i]}&amp;lt;/tex&amp;gt; {{---}} является ли нетерминал &amp;lt;tex&amp;gt;\mathrm{nonterm_i}&amp;lt;/tex&amp;gt; порождающим или нет,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{counter[rule_i]}&amp;lt;/tex&amp;gt; {{---}} счетчик количества нетерминалов, которые ещё не помечены порождающими, для каждого из правил,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{concernedRules[nonterm_i]}&amp;lt;/tex&amp;gt; {{---}} для каждого нетерминала &amp;lt;tex&amp;gt;\mathrm{nonterm_i}&amp;lt;/tex&amp;gt; список номеров правил, в правой части которых он встречается,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{Q}&amp;lt;/tex&amp;gt; {{---}} очередь нетерминалов, помеченных порождающими, но ещё не обработанных.&lt;br /&gt;
&lt;br /&gt;
Вначале для всех нетерминалов в &amp;lt;tex&amp;gt;\mathrm{isGenerating}&amp;lt;/tex&amp;gt; поставим &amp;lt;tex&amp;gt;false&amp;lt;/tex&amp;gt;. В &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; поставим количество нетерминалов в правой части. Нетерминалы, у которых счётчик &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; нулевой, добавим в очередь и отметим их порождающими.&amp;lt;br&amp;gt;&lt;br /&gt;
Пока в очереди есть элементы, достаём очередной нетерминал и уменьшаем &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; для всех правил из &amp;lt;tex&amp;gt;\mathrm{concernedRules}&amp;lt;/tex&amp;gt; для данного нетерминала. Если счётчик количества порождающих терминалов обнулился, то добавим нетерминал, стоящий в левой части данного правила в очередь и пометим его порождающим.&amp;lt;br&amp;gt;&lt;br /&gt;
Каждый из нетерминалов попадёт в очередь только один раз, следовательно мы пройдем по списку правил, в правой части которых он встречается, один раз. Таким образом, суммарно получаем &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
 S\rightarrow Ac\\&lt;br /&gt;
 A\rightarrow SD\\&lt;br /&gt;
 D\rightarrow aD\\&lt;br /&gt;
 A\rightarrow a    &lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
Применяя описанный алгоритм:&lt;br /&gt;
# Изначально множество порождающих нетерминалов состоит из одного элемента &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Добавим в множество нетерминал &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, так как существует правило &amp;lt;tex&amp;gt;S\rightarrow Ac&amp;lt;/tex&amp;gt;, в правой части которого стоят нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, который есть в множестве, и терминал &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# После следующего обхода правил из грамматики множество не изменится.&lt;br /&gt;
# Теперь удалим правила &amp;lt;tex&amp;gt;A\rightarrow SD&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D\rightarrow aD&amp;lt;/tex&amp;gt;, так как они содержит нетерминалы, которых нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Достижимые и недостижимые нетерминалы ==&lt;br /&gt;
===Описание===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''достижимым''' (англ. ''reachable'') в [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|КС-грамматике]] &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если существует порождение &amp;lt;tex&amp;gt;S \Rightarrow^* \alpha A \beta&amp;lt;/tex&amp;gt;. Иначе он называется '''недостижимым''' (англ. ''unreachable'').&lt;br /&gt;
}}&lt;br /&gt;
Очевидно, что если нетерминал в левой части правила является достижимым, то и все нетерминалы правой части являются достижимыми. &lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих недостижимые нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Недостижимые нетерминалы по определению не достижимы из стартового, следовательно они не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
===Алгоритм===&lt;br /&gt;
'''Шаг 0.''' Множество достижимых нетерминалов состоит из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 1.''' Если найдено правило, в левой части которого стоит нетерминал, содержащийся в множестве, добавим в множество все нетерминалы из правой части.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 2.''' Повторим предыдущий шаг, если множество порождающих нетерминалов изменилось.&amp;lt;br&amp;gt;&lt;br /&gt;
Получаем множество всех достижимых нетерминалов, а нетерминалы, не попавшие в него, являются недостижимыми.&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, однако используя [[Обход_в_глубину,_цвета_вершин|обход в глубину]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|CD\\&lt;br /&gt;
    A\rightarrow EF\\&lt;br /&gt;
    G\rightarrow AD\\&lt;br /&gt;
    C\rightarrow c&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
Применяя описанный алгоритм:&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Из &amp;lt;tex&amp;gt;S&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;C&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;. Добавим их в множество и получим  &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Множество изменилось. Переберём заново правила из грамматики. Из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; можно вывести &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt;, добавим их в множество.&lt;br /&gt;
# Снова переберём правила. Из &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; можно вывести только терминал, а &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; нету в множестве.&lt;br /&gt;
# После последнего обхода правил грамматики множество не изменилось, значит мы нашли все достижимые нетерминалы: &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D, E, F \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Теперь удалим правило &amp;lt;tex&amp;gt;G\rightarrow AD&amp;lt;/tex&amp;gt;, так как оно содержит в левой части нетерминал, которого нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Полезные и бесполезные нетерминалы ==&lt;br /&gt;
===Описание===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''полезным''' (англ. ''useful'') в КС-грамматике &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если он может участвовать в выводе, то есть существует порождение вида &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* w&amp;lt;/tex&amp;gt;. Иначе он называется '''бесполезным''' (англ. ''useless'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит бесполезных нетерминалов тогда и только тогда, когда грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит ни недостижимых нетерминалов, ни непорождающих.&lt;br /&gt;
|proof=&lt;br /&gt;
&amp;lt;tex&amp;gt;\Leftarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
:Очевидно, так как недостижимые и непорождающие нетерминалы являются бесполезными.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\Rightarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
:Рассмотрим любой нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как он достижим, существуют &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta&amp;lt;/tex&amp;gt;. Из того, что любой нетерминал является порождающим, следует, что из любой строки можно вывести строку из терминалов. Значит, существует &amp;lt;tex&amp;gt;\omega \in \Sigma ^ *&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;A&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;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих недостижимые нетерминалы, не появятся новые непорождающие нетерминалы.&lt;br /&gt;
|proof=&lt;br /&gt;
Допустим, что в грамматике появился непорождающий нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как до удаления недостижимых нетерминалов существовал вывод из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; некоторой конечной цепочки терминалов &amp;lt;tex&amp;gt;\omega&amp;lt;/tex&amp;gt;, то было удалено хотя бы какое-то одно правило из этого вывода.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;B\rightarrow\alpha&amp;lt;/tex&amp;gt; {{---}} правило, первым из удалённых применяемое в выводе &amp;lt;tex&amp;gt;A \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;. Оно могло быть удалено только в том случае, если в &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; присутствуют недостижимые нетерминалы. Но так как было выбрано первое удалённое правило из вывода, то &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; — достижим, следовательно достижимы и все нетерминалы из &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;. Значит, это правило не могло быть удалено.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
&lt;br /&gt;
1. Пусть нам дана грамматика: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|BS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
2. Удалим правила, содержащие непорождающие нетерминалы: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
3. Теперь удалим недостижимые нетерминалы:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\    &lt;br /&gt;
    A\rightarrow a&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Замечание ===&lt;br /&gt;
Шаги алгоритма нельзя менять местами. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|a \\&lt;br /&gt;
    A\rightarrow b&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все нетерминалы в этой грамматике достижимы. Однако, если удалить &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; как непорождающий, то нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; станет недостижимым.&lt;br /&gt;
== См. также  ==&lt;br /&gt;
* [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|Контекстно-свободные грамматики]]&lt;br /&gt;
* [[Нормальная_форма_Хомского|Нормальная форма Хомского]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [[wikipedia:Formal_grammar | Wikipedia {{---}} Formal grammar]]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Chomsky_normal_form Wikipedia {{---}} Chomsky normal form]&lt;br /&gt;
* ''Хопкрофт Д., Мотвани Р., Ульман Д.'' {{---}} Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. — Москва, Издательский дом «Вильямс», 2002. — 528 с. : ISBN 5-8459-0261-4 (рус.)&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Контекстно-свободные грамматики]]&lt;br /&gt;
[[Категория: Нормальные формы КС-грамматик]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55844</id>
		<title>Удаление бесполезных символов из грамматики</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55844"/>
				<updated>2016-11-12T18:25:20Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Порождающие и непорождающие нетерминалы ==&lt;br /&gt;
===Описание===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
[[Формальные_грамматики|Нетерминал]] &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''порождающим''' (англ. ''generating''), если из него может быть выведена конечная терминальная цепочка. Иначе он называется '''непорождающим'''.&lt;br /&gt;
}}&lt;br /&gt;
Очевидно, что если и только если все нетерминалы правой части правила являются порождающими, то порождающим является и нетерминал, стоящий в его левой части. &lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих непорождающие нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Непорождающие нетерминалы по определению не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Алгоритм===&lt;br /&gt;
'''Шаг 0'''. Множество порождающих нетерминалов пустое.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 1'''. Находим правила, не содержащие нетерминалов в правых частях и добавляем нетерминалы, встречающихся в левых частях таких правил, в множество.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 2'''. Если найдено такое правило, что все нетерминалы, стоящие в его правой части, уже входят в множество, то добавим в множество нетерминалы, стоящие в его левой части. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 3'''. Повторим предыдущий шаг, если множество порождающих нетерминалов изменилось.&amp;lt;br&amp;gt;&lt;br /&gt;
В результате получаем множество всех порождающих нетерминалов грамматики, а все нетерминалы, не попавшие в него, являются непорождающими.&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\left| \Gamma \right|&amp;lt;/tex&amp;gt; {{---}} размер грамматики. Однако используя [[Очередь|очередь]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Модификация алгоритма с очередью===&lt;br /&gt;
Для реализации алгоритма поиска непорождающих нетерминалов будем использовать следующие структуры:&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{isGenerating[nonterm_i]}&amp;lt;/tex&amp;gt; {{---}} является ли нетерминал &amp;lt;tex&amp;gt;\mathrm{nonterm_i}&amp;lt;/tex&amp;gt; порождающим или нет,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{counter[rule_i]}&amp;lt;/tex&amp;gt; {{---}} счетчик количества нетерминалов, которые ещё не помечены порождающими, для каждого из правил,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{concernedRules[nonterm_i]}&amp;lt;/tex&amp;gt; {{---}} для каждого нетерминала &amp;lt;tex&amp;gt;\mathrm{nonterm_i}&amp;lt;/tex&amp;gt; список номеров правил, в правой части которых он встречается,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{Q}&amp;lt;/tex&amp;gt; {{---}} очередь нетерминалов, помеченных порождающими, но ещё не обработанных.&lt;br /&gt;
&lt;br /&gt;
Вначале для всех нетерминалов в &amp;lt;tex&amp;gt;\mathrm{isGenerating}&amp;lt;/tex&amp;gt; поставим &amp;lt;tex&amp;gt;false&amp;lt;/tex&amp;gt;. В &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; поставим количество нетерминалов в правой части. Нетерминалы, у которых счётчик &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; нулевой, добавим в очередь и отметим их порождающими.&amp;lt;br&amp;gt;&lt;br /&gt;
Пока в очереди есть элементы, достаём очередной нетерминал и уменьшаем &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; для всех правил из &amp;lt;tex&amp;gt;\mathrm{concernedRules}&amp;lt;/tex&amp;gt; для данного нетерминала. Если счётчик количества порождающих терминалов обнулился, то добавим нетерминал, стоящий в левой части данного правила в очередь и пометим его порождающим.&amp;lt;br&amp;gt;&lt;br /&gt;
Каждый из нетерминалов попадёт в очередь только один раз, следовательно мы пройдем по списку правил, в правой части которых он встречается, один раз. Таким образом, суммарно получаем &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
 S\rightarrow Ac\\&lt;br /&gt;
 A\rightarrow SD\\&lt;br /&gt;
 D\rightarrow aD\\&lt;br /&gt;
 A\rightarrow a    &lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
Применяя описанный алгоритм:&lt;br /&gt;
# Изначально множество порождающих нетерминалов состоит из одного элемента &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Добавим в множество нетерминал &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, так как существует правило &amp;lt;tex&amp;gt;S\rightarrow Ac&amp;lt;/tex&amp;gt;, в правой части которого стоят нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, который есть в множестве, и терминал &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# После следующего обхода правил из грамматики множество не изменится.&lt;br /&gt;
# Теперь удалим правила &amp;lt;tex&amp;gt;A\rightarrow SD&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D\rightarrow aD&amp;lt;/tex&amp;gt;, так как они содержит нетерминалы, которых нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Достижимые и недостижимые нетерминалы ==&lt;br /&gt;
===Описание===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''достижимым''' (англ. ''reachable'') в [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|КС-грамматике]] &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если существует порождение &amp;lt;tex&amp;gt;S \Rightarrow^* \alpha A \beta&amp;lt;/tex&amp;gt;. Иначе он называется '''недостижимым''' (англ. ''unreachable'').&lt;br /&gt;
}}&lt;br /&gt;
Очевидно, что если нетерминал в левой части правила является достижимым, то и все нетерминалы правой части являются достижимыми. &lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих недостижимые нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Недостижимые нетерминалы по определению не достижимы из стартового, следовательно они не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
===Алгоритм===&lt;br /&gt;
'''Шаг 0.''' Множество достижимых нетерминалов состоит из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 1.''' Если найдено правило, в левой части которого стоит нетерминал, содержащийся в множестве, добавим в множество все нетерминалы из правой части.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 2.''' Повторим предыдущий шаг, если множество порождающих нетерминалов изменилось.&amp;lt;br&amp;gt;&lt;br /&gt;
Получаем множество всех достижимых нетерминалов, а нетерминалы, не попавшие в него, являются недостижимыми.&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, однако используя [[Обход_в_глубину,_цвета_вершин|обход в глубину]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|CD\\&lt;br /&gt;
    A\rightarrow EF\\&lt;br /&gt;
    G\rightarrow AD\\&lt;br /&gt;
    C\rightarrow c&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
Применяя описанный алгоритм:&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Из &amp;lt;tex&amp;gt;S&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;C&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;. Добавим их в множество и получим  &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Множество изменилось. Переберём заново правила из грамматики. Из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; можно вывести &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt;, добавим их в множество.&lt;br /&gt;
# Снова переберём правила. Из &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; можно вывести только терминал, а &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; нету в множестве.&lt;br /&gt;
# После последнего обхода правил грамматики множество не изменилось, значит мы нашли все достижимые нетерминалы: &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D, E, F \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Теперь удалим правило &amp;lt;tex&amp;gt;G\rightarrow AD&amp;lt;/tex&amp;gt;, так как оно содержит в левой части нетерминал, которого нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Полезные и бесполезные нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''полезным''' (англ. ''useful'') в КС-грамматике &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если он может участвовать в выводе, то есть существует порождение вида &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* w&amp;lt;/tex&amp;gt;. Иначе он называется '''бесполезным''' (англ. ''useless'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит бесполезных нетерминалов тогда и только тогда, когда грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит ни недостижимых нетерминалов, ни непорождающих.&lt;br /&gt;
|proof=&lt;br /&gt;
&amp;lt;tex&amp;gt;\Leftarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
:Очевидно, так как недостижимые и непорождающие нетерминалы являются бесполезными.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\Rightarrow&amp;lt;/tex&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
:Рассмотрим любой нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как он достижим, существуют &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta&amp;lt;/tex&amp;gt;. Из того, что любой нетерминал является порождающим, следует, что из любой строки можно вывести строку из терминалов. Значит, существует &amp;lt;tex&amp;gt;\omega \in \Sigma ^ *&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;A&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;
Допустим, что в грамматике появился непорождающий нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как до удаления недостижимых нетерминалов существовал вывод из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; некоторой конечной цепочки терминалов &amp;lt;tex&amp;gt;\omega&amp;lt;/tex&amp;gt;, то было удалено хотя бы какое-то одно правило из этого вывода.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;B\rightarrow\alpha&amp;lt;/tex&amp;gt; {{---}} правило, первым из удалённых применяемое в выводе &amp;lt;tex&amp;gt;A \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;. Оно могло быть удалено только в том случае, если в &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; присутствуют недостижимые нетерминалы. Но так как было выбрано первое удалённое правило из вывода, то &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; — достижим, следовательно достижимы и все нетерминалы из &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;. Значит, это правило не могло быть удалено.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
&lt;br /&gt;
1. Пусть нам дана грамматика: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|BS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
2. Удалим правила, содержащие непорождающие нетерминалы: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
3. Теперь удалим недостижимые нетерминалы:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\    &lt;br /&gt;
    A\rightarrow a&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Замечание ===&lt;br /&gt;
Шаги алгоритма нельзя менять местами. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|a \\&lt;br /&gt;
    A\rightarrow b&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все нетерминалы в этой грамматике достижимы. Однако, если удалить &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; как непорождающий, то нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; станет недостижимым.&lt;br /&gt;
== См. также  ==&lt;br /&gt;
* [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|Контекстно-свободные грамматики]]&lt;br /&gt;
* [[Нормальная_форма_Хомского|Нормальная форма Хомского]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [[wikipedia:Formal_grammar | Wikipedia {{---}} Formal grammar]]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Chomsky_normal_form Wikipedia {{---}} Chomsky normal form]&lt;br /&gt;
* ''Хопкрофт Д., Мотвани Р., Ульман Д.'' {{---}} Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. — Москва, Издательский дом «Вильямс», 2002. — 528 с. : ISBN 5-8459-0261-4 (рус.)&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Контекстно-свободные грамматики]]&lt;br /&gt;
[[Категория: Нормальные формы КС-грамматик]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55843</id>
		<title>Удаление бесполезных символов из грамматики</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55843"/>
				<updated>2016-11-12T18:19:53Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: /* Пример */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Порождающие и непорождающие нетерминалы ==&lt;br /&gt;
===Описание===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
[[Формальные_грамматики|Нетерминал]] &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''порождающим''' (англ. ''generating''), если из него может быть выведена конечная терминальная цепочка. Иначе он называется '''непорождающим'''.&lt;br /&gt;
}}&lt;br /&gt;
Очевидно, что если и только если все нетерминалы правой части правила являются порождающими, то порождающим является и нетерминал, стоящий в его левой части. &lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих непорождающие нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Непорождающие нетерминалы по определению не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Алгоритм===&lt;br /&gt;
'''Шаг 0'''. Множество порождающих нетерминалов пустое.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 1'''. Находим правила, не содержащие нетерминалов в правых частях и добавляем нетерминалы, встречающихся в левых частях таких правил, в множество.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 2'''. Если найдено такое правило, что все нетерминалы, стоящие в его правой части, уже входят в множество, то добавим в множество нетерминалы, стоящие в его левой части. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 3'''. Повторим предыдущий шаг, если множество порождающих нетерминалов изменилось.&amp;lt;br&amp;gt;&lt;br /&gt;
В результате получаем множество всех порождающих нетерминалов грамматики, а все нетерминалы, не попавшие в него, являются непорождающими.&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\left| \Gamma \right|&amp;lt;/tex&amp;gt; {{---}} размер грамматики. Однако используя [[Очередь|очередь]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Модификация алгоритма с очередью===&lt;br /&gt;
Для реализации алгоритма поиска непорождающих нетерминалов будем использовать следующие структуры:&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{isGenerating[nonterm_i]}&amp;lt;/tex&amp;gt; {{---}} является ли нетерминал &amp;lt;tex&amp;gt;\mathrm{nonterm_i}&amp;lt;/tex&amp;gt; порождающим или нет,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{counter[rule_i]}&amp;lt;/tex&amp;gt; {{---}} счетчик количества нетерминалов, которые ещё не помечены порождающими, для каждого из правил,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{concernedRules[nonterm_i]}&amp;lt;/tex&amp;gt; {{---}} для каждого нетерминала &amp;lt;tex&amp;gt;\mathrm{nonterm_i}&amp;lt;/tex&amp;gt; список номеров правил, в правой части которых он встречается,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{Q}&amp;lt;/tex&amp;gt; {{---}} очередь нетерминалов, помеченных порождающими, но ещё не обработанных.&lt;br /&gt;
&lt;br /&gt;
Вначале для всех нетерминалов в &amp;lt;tex&amp;gt;\mathrm{isGenerating}&amp;lt;/tex&amp;gt; поставим &amp;lt;tex&amp;gt;false&amp;lt;/tex&amp;gt;. В &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; поставим количество нетерминалов в правой части. Нетерминалы, у которых счётчик &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; нулевой, добавим в очередь и отметим их порождающими.&amp;lt;br&amp;gt;&lt;br /&gt;
Пока в очереди есть элементы, достаём очередной нетерминал и уменьшаем &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; для всех правил из &amp;lt;tex&amp;gt;\mathrm{concernedRules}&amp;lt;/tex&amp;gt; для данного нетерминала. Если счётчик количества порождающих терминалов обнулился, то добавим нетерминал, стоящий в левой части данного правила в очередь и пометим его порождающим.&amp;lt;br&amp;gt;&lt;br /&gt;
Каждый из нетерминалов попадёт в очередь только один раз, следовательно мы пройдем по списку правил, в правой части которых он встречается, один раз. Таким образом, суммарно получаем &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
 S\rightarrow Ac\\&lt;br /&gt;
 A\rightarrow SD\\&lt;br /&gt;
 D\rightarrow aD\\&lt;br /&gt;
 A\rightarrow a    &lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
Применяя описанный алгоритм:&lt;br /&gt;
# Изначально множество порождающих нетерминалов состоит из одного элемента &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Добавим в множество нетерминал &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, так как существует правило &amp;lt;tex&amp;gt;S\rightarrow Ac&amp;lt;/tex&amp;gt;, в правой части которого стоят нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, который есть в множестве, и терминал &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# После следующего обхода правил из грамматики множество не изменится.&lt;br /&gt;
# Теперь удалим правила &amp;lt;tex&amp;gt;A\rightarrow SD&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D\rightarrow aD&amp;lt;/tex&amp;gt;, так как они содержит нетерминалы, которых нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Достижимые и недостижимые нетерминалы ==&lt;br /&gt;
===Описание===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''достижимым''' (англ. ''reachable'') в [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|КС-грамматике]] &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если существует порождение &amp;lt;tex&amp;gt;S \Rightarrow^* \alpha A \beta&amp;lt;/tex&amp;gt;. Иначе он называется '''недостижимым''' (англ. ''unreachable'').&lt;br /&gt;
}}&lt;br /&gt;
Очевидно, что если нетерминал в левой части правила является достижимым, то и все нетерминалы правой части являются достижимыми. &lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих недостижимые нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Недостижимые нетерминалы по определению не достижимы из стартового, следовательно они не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
===Алгоритм===&lt;br /&gt;
'''Шаг 0.''' Множество достижимых нетерминалов состоит из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 1.''' Если найдено правило, в левой части которого стоит нетерминал, содержащийся в множестве, добавим в множество все нетерминалы из правой части.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 2.''' Повторим предыдущий шаг, если множество порождающих нетерминалов изменилось.&amp;lt;br&amp;gt;&lt;br /&gt;
Получаем множество всех достижимых нетерминалов, а нетерминалы, не попавшие в него, являются недостижимыми.&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, однако используя [[Обход_в_глубину,_цвета_вершин|обход в глубину]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|CD\\&lt;br /&gt;
    A\rightarrow EF\\&lt;br /&gt;
    G\rightarrow AD\\&lt;br /&gt;
    C\rightarrow c&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
Применяя описанный алгоритм:&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Из &amp;lt;tex&amp;gt;S&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;C&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;. Добавим их в множество и получим  &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Множество изменилось. Переберём заново правила из грамматики. Из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; можно вывести &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt;, добавим их в множество.&lt;br /&gt;
# Снова переберём правила. Из &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; можно вывести только терминал, а &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; нету в множестве.&lt;br /&gt;
# После последнего обхода правил грамматики множество не изменилось, значит мы нашли все достижимые нетерминалы: &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D, E, F \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Теперь удалим правило &amp;lt;tex&amp;gt;G\rightarrow AD&amp;lt;/tex&amp;gt;, так как оно содержит в левой части нетерминал, которого нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Полезные и бесполезные нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''полезным''' (англ. ''useful'') в КС-грамматике &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если он может участвовать в выводе, то есть существует порождение вида &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* w&amp;lt;/tex&amp;gt;. Иначе он называется '''бесполезным''' (англ. ''useless'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит бесполезных нетерминалов тогда и только тогда, когда грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит ни недостижимых нетерминалов, ни непорождающих.&lt;br /&gt;
|proof=&lt;br /&gt;
''Необходимость.'' Очевидно, так как недостижимые и непорождающие нетерминалы являются бесполезными.&lt;br /&gt;
&lt;br /&gt;
''Достаточность.'' Рассмотрим любой нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как он достижим, существуют &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta&amp;lt;/tex&amp;gt;. Из того, что любой нетерминал является порождающим, следует, что из любой строки можно вывести строку из терминалов. Значит, существует &amp;lt;tex&amp;gt;\omega \in \Sigma ^ *&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;A&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;
Допустим, что в грамматике появился непорождающий нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как до удаления недостижимых нетерминалов существовал вывод из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; некоторой конечной цепочки терминалов &amp;lt;tex&amp;gt;\omega&amp;lt;/tex&amp;gt;, то было удалено хотя бы какое-то одно правило из этого вывода.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;B\rightarrow\alpha&amp;lt;/tex&amp;gt; {{---}} правило, первым из удалённых применяемое в выводе &amp;lt;tex&amp;gt;A \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;. Оно могло быть удалено только в том случае, если в &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; присутствуют недостижимые нетерминалы. Но так как было выбрано первое удалённое правило из вывода, то &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; — достижим, следовательно достижимы и все нетерминалы из &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;. Значит, это правило не могло быть удалено.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
&lt;br /&gt;
1. Пусть нам дана грамматика: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|BS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
2. Удалим правила, содержащие непорождающие нетерминалы: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
3. Теперь удалим недостижимые нетерминалы:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\    &lt;br /&gt;
    A\rightarrow a&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Замечание ===&lt;br /&gt;
Шаги алгоритма нельзя менять местами. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|a \\&lt;br /&gt;
    A\rightarrow b&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все нетерминалы в этой грамматике достижимы. Однако, если удалить &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; как непорождающий, то нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; станет недостижимым.&lt;br /&gt;
== См. также  ==&lt;br /&gt;
* [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|Контекстно-свободные грамматики]]&lt;br /&gt;
* [[Нормальная_форма_Хомского|Нормальная форма Хомского]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [[wikipedia:Formal_grammar | Wikipedia {{---}} Formal grammar]]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Chomsky_normal_form Wikipedia {{---}} Chomsky normal form]&lt;br /&gt;
* ''Хопкрофт Д., Мотвани Р., Ульман Д.'' {{---}} Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. — Москва, Издательский дом «Вильямс», 2002. — 528 с. : ISBN 5-8459-0261-4 (рус.)&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Контекстно-свободные грамматики]]&lt;br /&gt;
[[Категория: Нормальные формы КС-грамматик]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55842</id>
		<title>Удаление бесполезных символов из грамматики</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55842"/>
				<updated>2016-11-12T18:19:36Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: /* Пример */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Порождающие и непорождающие нетерминалы ==&lt;br /&gt;
===Описание===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
[[Формальные_грамматики|Нетерминал]] &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''порождающим''' (англ. ''generating''), если из него может быть выведена конечная терминальная цепочка. Иначе он называется '''непорождающим'''.&lt;br /&gt;
}}&lt;br /&gt;
Очевидно, что если и только если все нетерминалы правой части правила являются порождающими, то порождающим является и нетерминал, стоящий в его левой части. &lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих непорождающие нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Непорождающие нетерминалы по определению не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Алгоритм===&lt;br /&gt;
'''Шаг 0'''. Множество порождающих нетерминалов пустое.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 1'''. Находим правила, не содержащие нетерминалов в правых частях и добавляем нетерминалы, встречающихся в левых частях таких правил, в множество.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 2'''. Если найдено такое правило, что все нетерминалы, стоящие в его правой части, уже входят в множество, то добавим в множество нетерминалы, стоящие в его левой части. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 3'''. Повторим предыдущий шаг, если множество порождающих нетерминалов изменилось.&amp;lt;br&amp;gt;&lt;br /&gt;
В результате получаем множество всех порождающих нетерминалов грамматики, а все нетерминалы, не попавшие в него, являются непорождающими.&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\left| \Gamma \right|&amp;lt;/tex&amp;gt; {{---}} размер грамматики. Однако используя [[Очередь|очередь]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Модификация алгоритма с очередью===&lt;br /&gt;
Для реализации алгоритма поиска непорождающих нетерминалов будем использовать следующие структуры:&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{isGenerating[nonterm_i]}&amp;lt;/tex&amp;gt; {{---}} является ли нетерминал &amp;lt;tex&amp;gt;\mathrm{nonterm_i}&amp;lt;/tex&amp;gt; порождающим или нет,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{counter[rule_i]}&amp;lt;/tex&amp;gt; {{---}} счетчик количества нетерминалов, которые ещё не помечены порождающими, для каждого из правил,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{concernedRules[nonterm_i]}&amp;lt;/tex&amp;gt; {{---}} для каждого нетерминала &amp;lt;tex&amp;gt;\mathrm{nonterm_i}&amp;lt;/tex&amp;gt; список номеров правил, в правой части которых он встречается,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{Q}&amp;lt;/tex&amp;gt; {{---}} очередь нетерминалов, помеченных порождающими, но ещё не обработанных.&lt;br /&gt;
&lt;br /&gt;
Вначале для всех нетерминалов в &amp;lt;tex&amp;gt;\mathrm{isGenerating}&amp;lt;/tex&amp;gt; поставим &amp;lt;tex&amp;gt;false&amp;lt;/tex&amp;gt;. В &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; поставим количество нетерминалов в правой части. Нетерминалы, у которых счётчик &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; нулевой, добавим в очередь и отметим их порождающими.&amp;lt;br&amp;gt;&lt;br /&gt;
Пока в очереди есть элементы, достаём очередной нетерминал и уменьшаем &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; для всех правил из &amp;lt;tex&amp;gt;\mathrm{concernedRules}&amp;lt;/tex&amp;gt; для данного нетерминала. Если счётчик количества порождающих терминалов обнулился, то добавим нетерминал, стоящий в левой части данного правила в очередь и пометим его порождающим.&amp;lt;br&amp;gt;&lt;br /&gt;
Каждый из нетерминалов попадёт в очередь только один раз, следовательно мы пройдем по списку правил, в правой части которых он встречается, один раз. Таким образом, суммарно получаем &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
 S\rightarrow Ac\\&lt;br /&gt;
 A\rightarrow SD\\&lt;br /&gt;
 D\rightarrow aD\\&lt;br /&gt;
 A\rightarrow a    &lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
Применяя описанный алгоритм:&lt;br /&gt;
# Изначально множество порождающих нетерминалов состоит из одного элемента &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Добавим в множество нетерминал &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, так как существует правило &amp;lt;tex&amp;gt;S\rightarrow Ac&amp;lt;/tex&amp;gt;, в правой части которого стоят нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, который есть в множестве, и терминал &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# После следующего обхода правил из грамматики множество не изменится.&lt;br /&gt;
# Теперь удалим правила &amp;lt;tex&amp;gt;A\rightarrow SD&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D\rightarrow aD&amp;lt;/tex&amp;gt;, так как они содержит нетерминалы, которых нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Достижимые и недостижимые нетерминалы ==&lt;br /&gt;
===Описание===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''достижимым''' (англ. ''reachable'') в [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|КС-грамматике]] &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если существует порождение &amp;lt;tex&amp;gt;S \Rightarrow^* \alpha A \beta&amp;lt;/tex&amp;gt;. Иначе он называется '''недостижимым''' (англ. ''unreachable'').&lt;br /&gt;
}}&lt;br /&gt;
Очевидно, что если нетерминал в левой части правила является достижимым, то и все нетерминалы правой части являются достижимыми. &lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих недостижимые нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Недостижимые нетерминалы по определению не достижимы из стартового, следовательно они не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
===Алгоритм===&lt;br /&gt;
'''Шаг 0.''' Множество достижимых нетерминалов состоит из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 1.''' Если найдено правило, в левой части которого стоит нетерминал, содержащийся в множестве, добавим в множество все нетерминалы из правой части.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 2.''' Повторим предыдущий шаг, если множество порождающих нетерминалов изменилось.&amp;lt;br&amp;gt;&lt;br /&gt;
Получаем множество всех достижимых нетерминалов, а нетерминалы, не попавшие в него, являются недостижимыми.&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, однако используя [[Обход_в_глубину,_цвета_вершин|обход в глубину]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|CD\\&lt;br /&gt;
    A\rightarrow EF\\&lt;br /&gt;
    G\rightarrow AD\\&lt;br /&gt;
    C\rightarrow c&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Из &amp;lt;tex&amp;gt;S&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;C&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;. Добавим их в множество и получим  &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Множество изменилось. Переберём заново правила из грамматики. Из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; можно вывести &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt;, добавим их в множество.&lt;br /&gt;
# Снова переберём правила. Из &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; можно вывести только терминал, а &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; нету в множестве.&lt;br /&gt;
# После последнего обхода правил грамматики множество не изменилось, значит мы нашли все достижимые нетерминалы: &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D, E, F \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Теперь удалим правило &amp;lt;tex&amp;gt;G\rightarrow AD&amp;lt;/tex&amp;gt;, так как оно содержит в левой части нетерминал, которого нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Полезные и бесполезные нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''полезным''' (англ. ''useful'') в КС-грамматике &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если он может участвовать в выводе, то есть существует порождение вида &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* w&amp;lt;/tex&amp;gt;. Иначе он называется '''бесполезным''' (англ. ''useless'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит бесполезных нетерминалов тогда и только тогда, когда грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит ни недостижимых нетерминалов, ни непорождающих.&lt;br /&gt;
|proof=&lt;br /&gt;
''Необходимость.'' Очевидно, так как недостижимые и непорождающие нетерминалы являются бесполезными.&lt;br /&gt;
&lt;br /&gt;
''Достаточность.'' Рассмотрим любой нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как он достижим, существуют &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta&amp;lt;/tex&amp;gt;. Из того, что любой нетерминал является порождающим, следует, что из любой строки можно вывести строку из терминалов. Значит, существует &amp;lt;tex&amp;gt;\omega \in \Sigma ^ *&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;A&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;
Допустим, что в грамматике появился непорождающий нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как до удаления недостижимых нетерминалов существовал вывод из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; некоторой конечной цепочки терминалов &amp;lt;tex&amp;gt;\omega&amp;lt;/tex&amp;gt;, то было удалено хотя бы какое-то одно правило из этого вывода.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;B\rightarrow\alpha&amp;lt;/tex&amp;gt; {{---}} правило, первым из удалённых применяемое в выводе &amp;lt;tex&amp;gt;A \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;. Оно могло быть удалено только в том случае, если в &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; присутствуют недостижимые нетерминалы. Но так как было выбрано первое удалённое правило из вывода, то &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; — достижим, следовательно достижимы и все нетерминалы из &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;. Значит, это правило не могло быть удалено.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
&lt;br /&gt;
1. Пусть нам дана грамматика: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|BS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
2. Удалим правила, содержащие непорождающие нетерминалы: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
3. Теперь удалим недостижимые нетерминалы:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\    &lt;br /&gt;
    A\rightarrow a&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Замечание ===&lt;br /&gt;
Шаги алгоритма нельзя менять местами. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|a \\&lt;br /&gt;
    A\rightarrow b&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все нетерминалы в этой грамматике достижимы. Однако, если удалить &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; как непорождающий, то нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; станет недостижимым.&lt;br /&gt;
== См. также  ==&lt;br /&gt;
* [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|Контекстно-свободные грамматики]]&lt;br /&gt;
* [[Нормальная_форма_Хомского|Нормальная форма Хомского]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [[wikipedia:Formal_grammar | Wikipedia {{---}} Formal grammar]]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Chomsky_normal_form Wikipedia {{---}} Chomsky normal form]&lt;br /&gt;
* ''Хопкрофт Д., Мотвани Р., Ульман Д.'' {{---}} Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. — Москва, Издательский дом «Вильямс», 2002. — 528 с. : ISBN 5-8459-0261-4 (рус.)&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Контекстно-свободные грамматики]]&lt;br /&gt;
[[Категория: Нормальные формы КС-грамматик]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55841</id>
		<title>Удаление бесполезных символов из грамматики</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55841"/>
				<updated>2016-11-12T18:18:59Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: /* Модификация алгоритма с очередью */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Порождающие и непорождающие нетерминалы ==&lt;br /&gt;
===Описание===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
[[Формальные_грамматики|Нетерминал]] &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''порождающим''' (англ. ''generating''), если из него может быть выведена конечная терминальная цепочка. Иначе он называется '''непорождающим'''.&lt;br /&gt;
}}&lt;br /&gt;
Очевидно, что если и только если все нетерминалы правой части правила являются порождающими, то порождающим является и нетерминал, стоящий в его левой части. &lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих непорождающие нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Непорождающие нетерминалы по определению не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Алгоритм===&lt;br /&gt;
'''Шаг 0'''. Множество порождающих нетерминалов пустое.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 1'''. Находим правила, не содержащие нетерминалов в правых частях и добавляем нетерминалы, встречающихся в левых частях таких правил, в множество.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 2'''. Если найдено такое правило, что все нетерминалы, стоящие в его правой части, уже входят в множество, то добавим в множество нетерминалы, стоящие в его левой части. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 3'''. Повторим предыдущий шаг, если множество порождающих нетерминалов изменилось.&amp;lt;br&amp;gt;&lt;br /&gt;
В результате получаем множество всех порождающих нетерминалов грамматики, а все нетерминалы, не попавшие в него, являются непорождающими.&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\left| \Gamma \right|&amp;lt;/tex&amp;gt; {{---}} размер грамматики. Однако используя [[Очередь|очередь]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Модификация алгоритма с очередью===&lt;br /&gt;
Для реализации алгоритма поиска непорождающих нетерминалов будем использовать следующие структуры:&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{isGenerating[nonterm_i]}&amp;lt;/tex&amp;gt; {{---}} является ли нетерминал &amp;lt;tex&amp;gt;\mathrm{nonterm_i}&amp;lt;/tex&amp;gt; порождающим или нет,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{counter[rule_i]}&amp;lt;/tex&amp;gt; {{---}} счетчик количества нетерминалов, которые ещё не помечены порождающими, для каждого из правил,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{concernedRules[nonterm_i]}&amp;lt;/tex&amp;gt; {{---}} для каждого нетерминала &amp;lt;tex&amp;gt;\mathrm{nonterm_i}&amp;lt;/tex&amp;gt; список номеров правил, в правой части которых он встречается,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{Q}&amp;lt;/tex&amp;gt; {{---}} очередь нетерминалов, помеченных порождающими, но ещё не обработанных.&lt;br /&gt;
&lt;br /&gt;
Вначале для всех нетерминалов в &amp;lt;tex&amp;gt;\mathrm{isGenerating}&amp;lt;/tex&amp;gt; поставим &amp;lt;tex&amp;gt;false&amp;lt;/tex&amp;gt;. В &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; поставим количество нетерминалов в правой части. Нетерминалы, у которых счётчик &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; нулевой, добавим в очередь и отметим их порождающими.&amp;lt;br&amp;gt;&lt;br /&gt;
Пока в очереди есть элементы, достаём очередной нетерминал и уменьшаем &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; для всех правил из &amp;lt;tex&amp;gt;\mathrm{concernedRules}&amp;lt;/tex&amp;gt; для данного нетерминала. Если счётчик количества порождающих терминалов обнулился, то добавим нетерминал, стоящий в левой части данного правила в очередь и пометим его порождающим.&amp;lt;br&amp;gt;&lt;br /&gt;
Каждый из нетерминалов попадёт в очередь только один раз, следовательно мы пройдем по списку правил, в правой части которых он встречается, один раз. Таким образом, суммарно получаем &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
 S\rightarrow Ac\\&lt;br /&gt;
 A\rightarrow SD\\&lt;br /&gt;
 D\rightarrow aD\\&lt;br /&gt;
 A\rightarrow a    &lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Изначально множество порождающих нетерминалов состоит из одного элемента &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Добавим в множество нетерминал &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, так как существует правило &amp;lt;tex&amp;gt;S\rightarrow Ac&amp;lt;/tex&amp;gt;, в правой части которого стоят нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, который есть в множестве, и терминал &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# После следующего обхода правил из грамматики множество не изменится.&lt;br /&gt;
# Теперь удалим правила &amp;lt;tex&amp;gt;A\rightarrow SD&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D\rightarrow aD&amp;lt;/tex&amp;gt;, так как они содержит нетерминалы, которых нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Достижимые и недостижимые нетерминалы ==&lt;br /&gt;
===Описание===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''достижимым''' (англ. ''reachable'') в [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|КС-грамматике]] &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если существует порождение &amp;lt;tex&amp;gt;S \Rightarrow^* \alpha A \beta&amp;lt;/tex&amp;gt;. Иначе он называется '''недостижимым''' (англ. ''unreachable'').&lt;br /&gt;
}}&lt;br /&gt;
Очевидно, что если нетерминал в левой части правила является достижимым, то и все нетерминалы правой части являются достижимыми. &lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих недостижимые нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Недостижимые нетерминалы по определению не достижимы из стартового, следовательно они не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
===Алгоритм===&lt;br /&gt;
'''Шаг 0.''' Множество достижимых нетерминалов состоит из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 1.''' Если найдено правило, в левой части которого стоит нетерминал, содержащийся в множестве, добавим в множество все нетерминалы из правой части.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 2.''' Повторим предыдущий шаг, если множество порождающих нетерминалов изменилось.&amp;lt;br&amp;gt;&lt;br /&gt;
Получаем множество всех достижимых нетерминалов, а нетерминалы, не попавшие в него, являются недостижимыми.&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, однако используя [[Обход_в_глубину,_цвета_вершин|обход в глубину]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|CD\\&lt;br /&gt;
    A\rightarrow EF\\&lt;br /&gt;
    G\rightarrow AD\\&lt;br /&gt;
    C\rightarrow c&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Из &amp;lt;tex&amp;gt;S&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;C&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;. Добавим их в множество и получим  &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Множество изменилось. Переберём заново правила из грамматики. Из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; можно вывести &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt;, добавим их в множество.&lt;br /&gt;
# Снова переберём правила. Из &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; можно вывести только терминал, а &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; нету в множестве.&lt;br /&gt;
# После последнего обхода правил грамматики множество не изменилось, значит мы нашли все достижимые нетерминалы: &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D, E, F \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Теперь удалим правило &amp;lt;tex&amp;gt;G\rightarrow AD&amp;lt;/tex&amp;gt;, так как оно содержит в левой части нетерминал, которого нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Полезные и бесполезные нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''полезным''' (англ. ''useful'') в КС-грамматике &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если он может участвовать в выводе, то есть существует порождение вида &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* w&amp;lt;/tex&amp;gt;. Иначе он называется '''бесполезным''' (англ. ''useless'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит бесполезных нетерминалов тогда и только тогда, когда грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит ни недостижимых нетерминалов, ни непорождающих.&lt;br /&gt;
|proof=&lt;br /&gt;
''Необходимость.'' Очевидно, так как недостижимые и непорождающие нетерминалы являются бесполезными.&lt;br /&gt;
&lt;br /&gt;
''Достаточность.'' Рассмотрим любой нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как он достижим, существуют &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta&amp;lt;/tex&amp;gt;. Из того, что любой нетерминал является порождающим, следует, что из любой строки можно вывести строку из терминалов. Значит, существует &amp;lt;tex&amp;gt;\omega \in \Sigma ^ *&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;A&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;
Допустим, что в грамматике появился непорождающий нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как до удаления недостижимых нетерминалов существовал вывод из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; некоторой конечной цепочки терминалов &amp;lt;tex&amp;gt;\omega&amp;lt;/tex&amp;gt;, то было удалено хотя бы какое-то одно правило из этого вывода.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;B\rightarrow\alpha&amp;lt;/tex&amp;gt; {{---}} правило, первым из удалённых применяемое в выводе &amp;lt;tex&amp;gt;A \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;. Оно могло быть удалено только в том случае, если в &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; присутствуют недостижимые нетерминалы. Но так как было выбрано первое удалённое правило из вывода, то &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; — достижим, следовательно достижимы и все нетерминалы из &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;. Значит, это правило не могло быть удалено.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
&lt;br /&gt;
1. Пусть нам дана грамматика: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|BS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
2. Удалим правила, содержащие непорождающие нетерминалы: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
3. Теперь удалим недостижимые нетерминалы:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\    &lt;br /&gt;
    A\rightarrow a&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Замечание ===&lt;br /&gt;
Шаги алгоритма нельзя менять местами. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|a \\&lt;br /&gt;
    A\rightarrow b&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все нетерминалы в этой грамматике достижимы. Однако, если удалить &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; как непорождающий, то нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; станет недостижимым.&lt;br /&gt;
== См. также  ==&lt;br /&gt;
* [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|Контекстно-свободные грамматики]]&lt;br /&gt;
* [[Нормальная_форма_Хомского|Нормальная форма Хомского]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [[wikipedia:Formal_grammar | Wikipedia {{---}} Formal grammar]]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Chomsky_normal_form Wikipedia {{---}} Chomsky normal form]&lt;br /&gt;
* ''Хопкрофт Д., Мотвани Р., Ульман Д.'' {{---}} Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. — Москва, Издательский дом «Вильямс», 2002. — 528 с. : ISBN 5-8459-0261-4 (рус.)&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Контекстно-свободные грамматики]]&lt;br /&gt;
[[Категория: Нормальные формы КС-грамматик]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55840</id>
		<title>Удаление бесполезных символов из грамматики</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55840"/>
				<updated>2016-11-12T18:18:07Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: /* Достижимые и недостижимые нетерминалы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Порождающие и непорождающие нетерминалы ==&lt;br /&gt;
===Описание===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
[[Формальные_грамматики|Нетерминал]] &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''порождающим''' (англ. ''generating''), если из него может быть выведена конечная терминальная цепочка. Иначе он называется '''непорождающим'''.&lt;br /&gt;
}}&lt;br /&gt;
Очевидно, что если и только если все нетерминалы правой части правила являются порождающими, то порождающим является и нетерминал, стоящий в его левой части. &lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих непорождающие нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Непорождающие нетерминалы по определению не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Алгоритм===&lt;br /&gt;
'''Шаг 0'''. Множество порождающих нетерминалов пустое.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 1'''. Находим правила, не содержащие нетерминалов в правых частях и добавляем нетерминалы, встречающихся в левых частях таких правил, в множество.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 2'''. Если найдено такое правило, что все нетерминалы, стоящие в его правой части, уже входят в множество, то добавим в множество нетерминалы, стоящие в его левой части. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 3'''. Повторим предыдущий шаг, если множество порождающих нетерминалов изменилось.&amp;lt;br&amp;gt;&lt;br /&gt;
В результате получаем множество всех порождающих нетерминалов грамматики, а все нетерминалы, не попавшие в него, являются непорождающими.&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\left| \Gamma \right|&amp;lt;/tex&amp;gt; {{---}} размер грамматики. Однако используя [[Очередь|очередь]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Модификация алгоритма с очередью===&lt;br /&gt;
Для реализации алгоритма поиска непорождающих нетерминалов будем использовать следующие структуры:&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{isGenerating[nonterm_i]}&amp;lt;/tex&amp;gt; {{---}} является ли нетерминал &amp;lt;tex&amp;gt;nonterm_i&amp;lt;/tex&amp;gt; порождающим или нет,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{counter[rule_i]}&amp;lt;/tex&amp;gt; {{---}} счетчик количества нетерминалов, которые ещё не помечены порождающими, для каждого из правил,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{concernedRules[nonterm_i]}&amp;lt;/tex&amp;gt; {{---}} для каждого нетерминала &amp;lt;tex&amp;gt;nonterm_i&amp;lt;/tex&amp;gt; список номеров правил, в правой части которых он встречается,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{Q}&amp;lt;/tex&amp;gt; {{---}} очередь нетерминалов, помеченных порождающими, но ещё не обработанных.&lt;br /&gt;
&lt;br /&gt;
Вначале для всех нетерминалов в &amp;lt;tex&amp;gt;\mathrm{isGenerating}&amp;lt;/tex&amp;gt; поставим &amp;lt;tex&amp;gt;false&amp;lt;/tex&amp;gt;. В &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; поставим количество нетерминалов в правой части. Нетерминалы, у которых счётчик &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; нулевой, добавим в очередь и отметим их порождающими.&amp;lt;br&amp;gt;&lt;br /&gt;
Пока в очереди есть элементы, достаём очередной нетерминал и уменьшаем &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; для всех правил из &amp;lt;tex&amp;gt;\mathrm{concernedRules}&amp;lt;/tex&amp;gt; для данного нетерминала. Если счётчик количества порождающих терминалов обнулился, то добавим нетерминал, стоящий в левой части данного правила в очередь и пометим его порождающим.&amp;lt;br&amp;gt;&lt;br /&gt;
Каждый из нетерминалов попадёт в очередь только один раз, следовательно мы пройдем по списку правил, в правой части которых он встречается, один раз. Таким образом, суммарно получаем &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
 S\rightarrow Ac\\&lt;br /&gt;
 A\rightarrow SD\\&lt;br /&gt;
 D\rightarrow aD\\&lt;br /&gt;
 A\rightarrow a    &lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Изначально множество порождающих нетерминалов состоит из одного элемента &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Добавим в множество нетерминал &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, так как существует правило &amp;lt;tex&amp;gt;S\rightarrow Ac&amp;lt;/tex&amp;gt;, в правой части которого стоят нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, который есть в множестве, и терминал &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# После следующего обхода правил из грамматики множество не изменится.&lt;br /&gt;
# Теперь удалим правила &amp;lt;tex&amp;gt;A\rightarrow SD&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D\rightarrow aD&amp;lt;/tex&amp;gt;, так как они содержит нетерминалы, которых нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Достижимые и недостижимые нетерминалы ==&lt;br /&gt;
===Описание===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''достижимым''' (англ. ''reachable'') в [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|КС-грамматике]] &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если существует порождение &amp;lt;tex&amp;gt;S \Rightarrow^* \alpha A \beta&amp;lt;/tex&amp;gt;. Иначе он называется '''недостижимым''' (англ. ''unreachable'').&lt;br /&gt;
}}&lt;br /&gt;
Очевидно, что если нетерминал в левой части правила является достижимым, то и все нетерминалы правой части являются достижимыми. &lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих недостижимые нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Недостижимые нетерминалы по определению не достижимы из стартового, следовательно они не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
===Алгоритм===&lt;br /&gt;
'''Шаг 0.''' Множество достижимых нетерминалов состоит из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 1.''' Если найдено правило, в левой части которого стоит нетерминал, содержащийся в множестве, добавим в множество все нетерминалы из правой части.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 2.''' Повторим предыдущий шаг, если множество порождающих нетерминалов изменилось.&amp;lt;br&amp;gt;&lt;br /&gt;
Получаем множество всех достижимых нетерминалов, а нетерминалы, не попавшие в него, являются недостижимыми.&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, однако используя [[Обход_в_глубину,_цвета_вершин|обход в глубину]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|CD\\&lt;br /&gt;
    A\rightarrow EF\\&lt;br /&gt;
    G\rightarrow AD\\&lt;br /&gt;
    C\rightarrow c&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Из &amp;lt;tex&amp;gt;S&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;C&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;. Добавим их в множество и получим  &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Множество изменилось. Переберём заново правила из грамматики. Из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; можно вывести &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt;, добавим их в множество.&lt;br /&gt;
# Снова переберём правила. Из &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; можно вывести только терминал, а &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; нету в множестве.&lt;br /&gt;
# После последнего обхода правил грамматики множество не изменилось, значит мы нашли все достижимые нетерминалы: &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D, E, F \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Теперь удалим правило &amp;lt;tex&amp;gt;G\rightarrow AD&amp;lt;/tex&amp;gt;, так как оно содержит в левой части нетерминал, которого нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Полезные и бесполезные нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''полезным''' (англ. ''useful'') в КС-грамматике &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если он может участвовать в выводе, то есть существует порождение вида &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* w&amp;lt;/tex&amp;gt;. Иначе он называется '''бесполезным''' (англ. ''useless'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит бесполезных нетерминалов тогда и только тогда, когда грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит ни недостижимых нетерминалов, ни непорождающих.&lt;br /&gt;
|proof=&lt;br /&gt;
''Необходимость.'' Очевидно, так как недостижимые и непорождающие нетерминалы являются бесполезными.&lt;br /&gt;
&lt;br /&gt;
''Достаточность.'' Рассмотрим любой нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как он достижим, существуют &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta&amp;lt;/tex&amp;gt;. Из того, что любой нетерминал является порождающим, следует, что из любой строки можно вывести строку из терминалов. Значит, существует &amp;lt;tex&amp;gt;\omega \in \Sigma ^ *&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;A&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;
Допустим, что в грамматике появился непорождающий нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как до удаления недостижимых нетерминалов существовал вывод из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; некоторой конечной цепочки терминалов &amp;lt;tex&amp;gt;\omega&amp;lt;/tex&amp;gt;, то было удалено хотя бы какое-то одно правило из этого вывода.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;B\rightarrow\alpha&amp;lt;/tex&amp;gt; {{---}} правило, первым из удалённых применяемое в выводе &amp;lt;tex&amp;gt;A \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;. Оно могло быть удалено только в том случае, если в &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; присутствуют недостижимые нетерминалы. Но так как было выбрано первое удалённое правило из вывода, то &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; — достижим, следовательно достижимы и все нетерминалы из &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;. Значит, это правило не могло быть удалено.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
&lt;br /&gt;
1. Пусть нам дана грамматика: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|BS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
2. Удалим правила, содержащие непорождающие нетерминалы: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
3. Теперь удалим недостижимые нетерминалы:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\    &lt;br /&gt;
    A\rightarrow a&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Замечание ===&lt;br /&gt;
Шаги алгоритма нельзя менять местами. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|a \\&lt;br /&gt;
    A\rightarrow b&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все нетерминалы в этой грамматике достижимы. Однако, если удалить &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; как непорождающий, то нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; станет недостижимым.&lt;br /&gt;
== См. также  ==&lt;br /&gt;
* [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|Контекстно-свободные грамматики]]&lt;br /&gt;
* [[Нормальная_форма_Хомского|Нормальная форма Хомского]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [[wikipedia:Formal_grammar | Wikipedia {{---}} Formal grammar]]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Chomsky_normal_form Wikipedia {{---}} Chomsky normal form]&lt;br /&gt;
* ''Хопкрофт Д., Мотвани Р., Ульман Д.'' {{---}} Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. — Москва, Издательский дом «Вильямс», 2002. — 528 с. : ISBN 5-8459-0261-4 (рус.)&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Контекстно-свободные грамматики]]&lt;br /&gt;
[[Категория: Нормальные формы КС-грамматик]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55839</id>
		<title>Удаление бесполезных символов из грамматики</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55839"/>
				<updated>2016-11-12T18:14:20Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: /* Порождающие и непорождающие нетерминалы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Порождающие и непорождающие нетерминалы ==&lt;br /&gt;
===Описание===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
[[Формальные_грамматики|Нетерминал]] &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''порождающим''' (англ. ''generating''), если из него может быть выведена конечная терминальная цепочка. Иначе он называется '''непорождающим'''.&lt;br /&gt;
}}&lt;br /&gt;
Очевидно, что если и только если все нетерминалы правой части правила являются порождающими, то порождающим является и нетерминал, стоящий в его левой части. &lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих непорождающие нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Непорождающие нетерминалы по определению не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Алгоритм===&lt;br /&gt;
'''Шаг 0'''. Множество порождающих нетерминалов пустое.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 1'''. Находим правила, не содержащие нетерминалов в правых частях и добавляем нетерминалы, встречающихся в левых частях таких правил, в множество.&amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 2'''. Если найдено такое правило, что все нетерминалы, стоящие в его правой части, уже входят в множество, то добавим в множество нетерминалы, стоящие в его левой части. &amp;lt;br&amp;gt;&lt;br /&gt;
'''Шаг 3'''. Повторим предыдущий шаг, если множество порождающих нетерминалов изменилось.&amp;lt;br&amp;gt;&lt;br /&gt;
В результате получаем множество всех порождающих нетерминалов грамматики, а все нетерминалы, не попавшие в него, являются непорождающими.&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\left| \Gamma \right|&amp;lt;/tex&amp;gt; {{---}} размер грамматики. Однако используя [[Очередь|очередь]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Модификация алгоритма с очередью===&lt;br /&gt;
Для реализации алгоритма поиска непорождающих нетерминалов будем использовать следующие структуры:&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{isGenerating[nonterm_i]}&amp;lt;/tex&amp;gt; {{---}} является ли нетерминал &amp;lt;tex&amp;gt;nonterm_i&amp;lt;/tex&amp;gt; порождающим или нет,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{counter[rule_i]}&amp;lt;/tex&amp;gt; {{---}} счетчик количества нетерминалов, которые ещё не помечены порождающими, для каждого из правил,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{concernedRules[nonterm_i]}&amp;lt;/tex&amp;gt; {{---}} для каждого нетерминала &amp;lt;tex&amp;gt;nonterm_i&amp;lt;/tex&amp;gt; список номеров правил, в правой части которых он встречается,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{Q}&amp;lt;/tex&amp;gt; {{---}} очередь нетерминалов, помеченных порождающими, но ещё не обработанных.&lt;br /&gt;
&lt;br /&gt;
Вначале для всех нетерминалов в &amp;lt;tex&amp;gt;\mathrm{isGenerating}&amp;lt;/tex&amp;gt; поставим &amp;lt;tex&amp;gt;false&amp;lt;/tex&amp;gt;. В &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; поставим количество нетерминалов в правой части. Нетерминалы, у которых счётчик &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; нулевой, добавим в очередь и отметим их порождающими.&amp;lt;br&amp;gt;&lt;br /&gt;
Пока в очереди есть элементы, достаём очередной нетерминал и уменьшаем &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; для всех правил из &amp;lt;tex&amp;gt;\mathrm{concernedRules}&amp;lt;/tex&amp;gt; для данного нетерминала. Если счётчик количества порождающих терминалов обнулился, то добавим нетерминал, стоящий в левой части данного правила в очередь и пометим его порождающим.&amp;lt;br&amp;gt;&lt;br /&gt;
Каждый из нетерминалов попадёт в очередь только один раз, следовательно мы пройдем по списку правил, в правой части которых он встречается, один раз. Таким образом, суммарно получаем &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
 S\rightarrow Ac\\&lt;br /&gt;
 A\rightarrow SD\\&lt;br /&gt;
 D\rightarrow aD\\&lt;br /&gt;
 A\rightarrow a    &lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Изначально множество порождающих нетерминалов состоит из одного элемента &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Добавим в множество нетерминал &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, так как существует правило &amp;lt;tex&amp;gt;S\rightarrow Ac&amp;lt;/tex&amp;gt;, в правой части которого стоят нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, который есть в множестве, и терминал &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# После следующего обхода правил из грамматики множество не изменится.&lt;br /&gt;
# Теперь удалим правила &amp;lt;tex&amp;gt;A\rightarrow SD&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D\rightarrow aD&amp;lt;/tex&amp;gt;, так как они содержит нетерминалы, которых нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Достижимые и недостижимые нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''достижимым''' (англ. ''reachable'') в [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|КС-грамматике]] &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если существует порождение &amp;lt;tex&amp;gt;S \Rightarrow^* \alpha A \beta&amp;lt;/tex&amp;gt;. Иначе он называется '''недостижимым''' (англ. ''unreachable'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Очевидно, что если нетерминал в левой части правила является достижимым, то и все нетерминалы правой части являются достижимыми. Найти недостижимые нетерминалы можно с помощью следующей процедуры.&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Если найдено правило, в левой части которого стоит нетерминал, содержащийся в множестве, добавить в множество все нетерминалы из правой части.&lt;br /&gt;
# Если на шаге 2 множество изменилось, повторить шаг 2.&lt;br /&gt;
# Получено множество всех достижимых нетерминалов, а нетерминалы, не попавшие в него, являются недостижимыми.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих недостижимые нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Недостижимые нетерминалы по определению не достижимы из стартового, следовательно они не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, однако используя [[Обход_в_глубину,_цвета_вершин|обход в глубину]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|CD\\&lt;br /&gt;
    A\rightarrow EF\\&lt;br /&gt;
    G\rightarrow AD\\&lt;br /&gt;
    C\rightarrow c&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Из &amp;lt;tex&amp;gt;S&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;C&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;. Добавим их в множество и получим  &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Множество изменилось. Переберём заново правила из грамматики. Из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; можно вывести &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt;, добавим их в множество.&lt;br /&gt;
# Снова переберём правила. Из &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; можно вывести только терминал, а &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; нету в множестве.&lt;br /&gt;
# После последнего обхода правил грамматики множество не изменилось, значит мы нашли все достижимые нетерминалы: &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D, E, F \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Теперь удалим правило &amp;lt;tex&amp;gt;G\rightarrow AD&amp;lt;/tex&amp;gt;, так как оно содержит в левой части нетерминал, которого нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Полезные и бесполезные нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''полезным''' (англ. ''useful'') в КС-грамматике &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если он может участвовать в выводе, то есть существует порождение вида &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* w&amp;lt;/tex&amp;gt;. Иначе он называется '''бесполезным''' (англ. ''useless'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит бесполезных нетерминалов тогда и только тогда, когда грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит ни недостижимых нетерминалов, ни непорождающих.&lt;br /&gt;
|proof=&lt;br /&gt;
''Необходимость.'' Очевидно, так как недостижимые и непорождающие нетерминалы являются бесполезными.&lt;br /&gt;
&lt;br /&gt;
''Достаточность.'' Рассмотрим любой нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как он достижим, существуют &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta&amp;lt;/tex&amp;gt;. Из того, что любой нетерминал является порождающим, следует, что из любой строки можно вывести строку из терминалов. Значит, существует &amp;lt;tex&amp;gt;\omega \in \Sigma ^ *&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;A&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;
Допустим, что в грамматике появился непорождающий нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как до удаления недостижимых нетерминалов существовал вывод из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; некоторой конечной цепочки терминалов &amp;lt;tex&amp;gt;\omega&amp;lt;/tex&amp;gt;, то было удалено хотя бы какое-то одно правило из этого вывода.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;B\rightarrow\alpha&amp;lt;/tex&amp;gt; {{---}} правило, первым из удалённых применяемое в выводе &amp;lt;tex&amp;gt;A \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;. Оно могло быть удалено только в том случае, если в &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; присутствуют недостижимые нетерминалы. Но так как было выбрано первое удалённое правило из вывода, то &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; — достижим, следовательно достижимы и все нетерминалы из &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;. Значит, это правило не могло быть удалено.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
&lt;br /&gt;
1. Пусть нам дана грамматика: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|BS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
2. Удалим правила, содержащие непорождающие нетерминалы: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
3. Теперь удалим недостижимые нетерминалы:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\    &lt;br /&gt;
    A\rightarrow a&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Замечание ===&lt;br /&gt;
Шаги алгоритма нельзя менять местами. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|a \\&lt;br /&gt;
    A\rightarrow b&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все нетерминалы в этой грамматике достижимы. Однако, если удалить &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; как непорождающий, то нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; станет недостижимым.&lt;br /&gt;
== См. также  ==&lt;br /&gt;
* [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|Контекстно-свободные грамматики]]&lt;br /&gt;
* [[Нормальная_форма_Хомского|Нормальная форма Хомского]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [[wikipedia:Formal_grammar | Wikipedia {{---}} Formal grammar]]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Chomsky_normal_form Wikipedia {{---}} Chomsky normal form]&lt;br /&gt;
* ''Хопкрофт Д., Мотвани Р., Ульман Д.'' {{---}} Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. — Москва, Издательский дом «Вильямс», 2002. — 528 с. : ISBN 5-8459-0261-4 (рус.)&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Контекстно-свободные грамматики]]&lt;br /&gt;
[[Категория: Нормальные формы КС-грамматик]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55838</id>
		<title>Алгоритм Бржозовского</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55838"/>
				<updated>2016-11-12T17:54:08Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Задача&lt;br /&gt;
|definition = &lt;br /&gt;
Пусть дан [[Детерминированные_конечные_автоматы|автомат]] &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;. Требуется построить автомат &amp;lt;tex&amp;gt;\mathcal{A}_{min}&amp;lt;/tex&amp;gt; с наименьшим количеством состояний, распознающий тот же язык, что и &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; {{---}} состояние автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q, s \in Q, T \subset Q, \delta : Q \times \Sigma \to Q \rangle&amp;lt;/tex&amp;gt;. &lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Правым языком''' (англ. ''right language'') называется язык &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;, распознаваемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; является уникальным начальным состоянием.&lt;br /&gt;
 }}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Левым языком''' (англ. ''left language'') называется язык &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, распознаваемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; является уникальным терминальным состоянием.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
Таким образом, допустимые слова языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, проходящие через состояние &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;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;y&amp;lt;/tex&amp;gt; из левого языка &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;. Тогда множество слов &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt; {{---}} [[Контексты_и_синтаксические_моноиды|правый контекст]] слова &amp;lt;tex&amp;gt;y&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;
|about=1&lt;br /&gt;
|statement=&lt;br /&gt;
Автомат является детерминированным тогда и только тогда, когда левые языки его состояний попарно не пересекаются.&lt;br /&gt;
|proof=Рассмотрим состояния &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 \neq q'&amp;lt;/tex&amp;gt;) в ДКА. Пусть левые языки этих состояний пересекаются, то есть &amp;lt;tex&amp;gt;L_g(q) \cap L_g(q') = \{ w \}&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;По окончании процесса допуска слова &amp;lt;tex&amp;gt;w&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;w&amp;lt;/tex&amp;gt;, а значит &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} НКА. Получаем противоречие.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратное слово''' (англ. ''reverse of the word'') &amp;lt;tex&amp;gt;r(u)&amp;lt;/tex&amp;gt; для слова &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; определяется следующим образом: &amp;lt;tex&amp;gt;r(\varepsilon) = \varepsilon&amp;lt;/tex&amp;gt; и если &amp;lt;tex&amp;gt;u = u_1 u_2 u_3 \dotsc u_p&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;r(u) = v_1 v_2 v_3 \dotsc v_p&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_i = u_{p - i + 1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный язык''' (англ. ''reverse of the language'') для языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} язык &amp;lt;tex&amp;gt;r(L) = \{ u \mid r(u) \in L \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный автомат''' (англ. ''reverse of the automaton'') для автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q , S , T , \delta \rangle&amp;lt;/tex&amp;gt; {{---}} автомат &amp;lt;tex&amp;gt;r(\mathcal{A}) = \langle \Sigma , Q , T , I , r(\delta) \rangle&amp;lt;/tex&amp;gt;, полученный из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; сменой местами начальных и конечных состояний и сменой направлений переходов.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=&lt;br /&gt;
Если &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; распознает язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt; распознает &amp;lt;tex&amp;gt;r(L)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=3&lt;br /&gt;
|statement=&lt;br /&gt;
Если левый язык состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, тогда его левый язык в &amp;lt;tex&amp;gt;r(A)&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;. Аналогично для правого языка &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q , I , T , \delta \rangle&amp;lt;/tex&amp;gt; {{---}} [[Недетерминированные_конечные_автоматы|НКА]].&amp;lt;br&amp;gt;Тогда детерминированный автомат &amp;lt;tex&amp;gt;d(\mathcal{A}) = \langle \Sigma , Q' , \{ i' \} , T' , \delta' \rangle&amp;lt;/tex&amp;gt; определяется следующим образом:&lt;br /&gt;
* Детерминированному состоянию соответствует множество недетерминированных состояний: для каждого &amp;lt;tex&amp;gt;q' \in Q'&amp;lt;/tex&amp;gt; имеем &amp;lt;tex&amp;gt;q' \subseteq Q&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* Начальное состояние в &amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} множество из &amp;lt;tex&amp;gt;I&amp;lt;/tex&amp;gt; начальных состояний автомата &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* Состояние в детерминированном автомате является терминальным тогда и только тогда, когда оно содержится хотя бы в одном недетерминированном состоянии,&lt;br /&gt;
* Пусть &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; {{---}} состояние детерминированного автомата и &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; – символ из &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;. Если переход из &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; по символу &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; определен, тогда, по построению: &amp;lt;tex&amp;gt;\delta'(q', a) = \bigcup\limits_{q \in q'}{ \delta(q, a)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=4&lt;br /&gt;
|statement=&lt;br /&gt;
Правый язык состояния &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; эквивалентен объединению правых языков состояний &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; автомата &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, принадлежащих множеству &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Левое отношение'''  (англ. ''left quotient'') регулярного языка &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;\Sigma^{*}&amp;lt;/tex&amp;gt; {{---}} язык &amp;lt;tex&amp;gt;u^{-1}L = \{ v \in X^{*} \mid uv \in L \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Минимальный автомат &amp;lt;tex&amp;gt;\mathcal{A}_{L}&amp;lt;/tex&amp;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;
* начальное состояние {{---}} &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* терминальные состояния {{---}} множество отношений, содержащих пустое слово,&lt;br /&gt;
* функция перехода &amp;lt;tex&amp;gt;\delta(u^{-1}L, x) = (ux)^{-1}L&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Автомат &amp;lt;tex&amp;gt;\mathcal{A}_L&amp;lt;/tex&amp;gt; уникален с точностью до изоморфизма и имеет минимальное количество состояний. &lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=5&lt;br /&gt;
|statement=&lt;br /&gt;
Детерминированный автомат минимален тогда и только тогда, когда правые языки его состояний различны и все состояния достижимы.&lt;br /&gt;
|proof=&lt;br /&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 \neq q'&amp;lt;/tex&amp;gt;) в ДКА. Пусть их правые языки &amp;lt;tex&amp;gt;L_d(q) = L_d(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;br&amp;gt;&lt;br /&gt;
Если состояние &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; недостижимо из начального состояния &amp;lt;tex&amp;gt;s&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;
===Описание===&lt;br /&gt;
Алгоритм минимизации конечных [[Детерминированные конечные автоматы|автоматов]] Бржозовского (Janusz A. (John) Brzozowski) выделяется, по крайней мере, следующими качествами:&lt;br /&gt;
* Он элегантен и весьма оригинален.&lt;br /&gt;
* Он эффективен.&lt;br /&gt;
* Он работает даже с [[Недетерминированные конечные автоматы|недетерминированными конечными автоматами]].&lt;br /&gt;
&lt;br /&gt;
Введём следующие обозначения:&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} конечный автомат,&lt;br /&gt;
*&amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} детерминизированный автомат для &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
*&amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} обратный автомат для &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
*&amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} результат &amp;lt;tex&amp;gt;d(r(\mathcal{A}))&amp;lt;/tex&amp;gt;. Аналогично для &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about=Бржозовский, 1962&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} автомат (необязательно детерминированный), распознающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Минимальный детерминированный автомат &amp;lt;tex&amp;gt;\mathcal{A}_L&amp;lt;/tex&amp;gt; может быть вычислен следующим образом: &amp;lt;tex&amp;gt;\mathcal{A}_L = drdr(\mathcal{A})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
По построению автомат &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; детерминированный. Согласно утверждению 2, он распознает язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt; &lt;br /&gt;
Покажем, что все правые языки &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; различны. Из утверждения 1, левые языки &amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt; попарно не пересекаются. Из утверждения 3, правые языки &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt; являются левыми языками &amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt;. Таким образом, они попарно не пересекаются. Согласно утверждению 4, правый язык &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} объединение правых языков &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Поскольку правые языки &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt; попарно не пересекаются, все правые языки &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; различны. &lt;br /&gt;
Так как все правые языки &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; различны, согласно утверждению 5 автомат &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; минимальный. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Пример работы===&lt;br /&gt;
# Исходный [[Недетерминированные конечные автоматы|НКА]] &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Fa.png|Исходный НКА]]&lt;br /&gt;
# Первый шаг, &amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Rfa.png|Первый шаг]]&lt;br /&gt;
# Второй шаг, &amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Drfa.png|Второй шаг]]&amp;lt;br&amp;gt;В детерминизированных автоматах состояния переименованы, так что &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; всегда является начальным состоянием.&lt;br /&gt;
# Третий шаг, &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Rdrfa.png|Третий шаг]]&amp;lt;br&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;
# Заключительный шаг, &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Drdrfa.png|Заключительный шаг]]&lt;br /&gt;
&lt;br /&gt;
== Заключение ==&lt;br /&gt;
Самым эффективным алгоритмом минимизации принято считать [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]], который, как и прочие традиционные алгоритмы, работает только с [[Детерминированные_конечные_автоматы|ДКА]]. Его асимптотическое время выполнения зависит от логарифма исходных данных. С другой стороны очевидно, что алгоритм Бржозовского в худшем случае будет обладать экспоненциальным временем выполнения, ведь этого требует процедура детерминизации, выполняемая дважды. На практике же наблюдается парадокс, алгоритм Бржозовского во многих случаях опережает прочие подходы к минимизации, включая и [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]]. В работе&amp;lt;ref&amp;gt;[http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=A511A421C93DF66BDCC32A0E133D1F99?doi=10.1.1.59.8276&amp;amp;rep=rep1&amp;amp;type=pdf Deian Tabakov, Moshe Y. Vardi. Experimental evaluation of classical automata constructions]&amp;lt;/ref&amp;gt;, сравнивающей оба алгоритма, показано, что алгоритм Бржозовского оказывается эффективнее [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритма Хопкрофта]] для автоматов с большим числом переходов.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Минимизация ДКА, алгоритм за O(n^2) с построением пар различимых состояний]]&lt;br /&gt;
*[[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))]]&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [https://pdfs.semanticscholar.org/f3be/b5e5825e6eedaab7f382341c9dd9c2ab33fa.pdf J.-M. Champarnaud, A. Khorsi, T. Paranthoen {{---}} Split and join for minimizing: Brzozowski's algorithm]&lt;br /&gt;
* [http://sovietov.com/txt/minfa/minfa.html Пётр Советов {{---}} Алгоритм Бржозовского для минимизации конечного автомата]&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55837</id>
		<title>Алгоритм Бржозовского</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55837"/>
				<updated>2016-11-12T17:38:11Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: /* Описание */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Задача&lt;br /&gt;
|definition = &lt;br /&gt;
Пусть дан [[Детерминированные_конечные_автоматы|автомат]] &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;. Требуется построить автомат &amp;lt;tex&amp;gt;\mathcal{A}_{min}&amp;lt;/tex&amp;gt; с наименьшим количеством состояний, распознающий тот же язык, что и &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; {{---}} состояние автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q, s \in Q, T \subset Q, \delta : Q \times \Sigma \to Q \rangle&amp;lt;/tex&amp;gt;. &lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Правым языком''' (англ. ''right language'') называется язык &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;, распознаваемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; является уникальным начальным состоянием.&lt;br /&gt;
 }}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Левым языком''' (англ. ''left language'') называется язык &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, распознаваемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; является уникальным терминальным состоянием.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
Таким образом, допустимые слова языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, проходящие через состояние &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;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;y&amp;lt;/tex&amp;gt; из левого языка &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;. Тогда множество слов &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt; {{---}} [[Контексты_и_синтаксические_моноиды|правый контекст]] слова &amp;lt;tex&amp;gt;y&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;
|about=1&lt;br /&gt;
|statement=&lt;br /&gt;
Автомат является детерминированным тогда и только тогда, когда левые языки его состояний попарно не пересекаются.&lt;br /&gt;
|proof=Рассмотрим состояния &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 \neq q'&amp;lt;/tex&amp;gt;) в ДКА. Пусть левые языки этих состояний пересекаются, то есть &amp;lt;tex&amp;gt;L_g(q) \cap L_g(q') = \{ w \}&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;По окончании процесса допуска слова &amp;lt;tex&amp;gt;w&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;w&amp;lt;/tex&amp;gt;, а значит &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} НКА. Получаем противоречие.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратное слово''' (англ. ''reverse of the word'') &amp;lt;tex&amp;gt;r(u)&amp;lt;/tex&amp;gt; для слова &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; определяется следующим образом: &amp;lt;tex&amp;gt;r(\varepsilon) = \varepsilon&amp;lt;/tex&amp;gt; и если &amp;lt;tex&amp;gt;u = u_1 u_2 u_3 \dotsc u_p&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;r(u) = v_1 v_2 v_3 \dotsc v_p&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_i = u_{p - i + 1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный язык''' (англ. ''reverse of the language'') для языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} язык &amp;lt;tex&amp;gt;r(L) = \{ u \mid r(u) \in L \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный автомат''' (англ. ''reverse of the automaton'') для автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q , S , T , \delta \rangle&amp;lt;/tex&amp;gt; {{---}} автомат &amp;lt;tex&amp;gt;r(\mathcal{A}) = \langle \Sigma , Q , T , I , r(\delta) \rangle&amp;lt;/tex&amp;gt;, полученный из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; сменой местами начальных и конечных состояний и сменой направлений переходов.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=&lt;br /&gt;
Если &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; распознает язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt; распознает &amp;lt;tex&amp;gt;r(L)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=3&lt;br /&gt;
|statement=&lt;br /&gt;
Если левый язык состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, тогда его левый язык в &amp;lt;tex&amp;gt;r(A)&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;. Аналогично для правого языка &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q , I , T , \delta \rangle&amp;lt;/tex&amp;gt; {{---}} [[Недетерминированные_конечные_автоматы|НКА]].&amp;lt;br&amp;gt;Тогда детерминированный автомат &amp;lt;tex&amp;gt;d(\mathcal{A}) = \langle \Sigma , Q' , \{ i' \} , T' , \delta' \rangle&amp;lt;/tex&amp;gt; определяется следующим образом:&lt;br /&gt;
* Детерминированному состоянию соответствует множество недетерминированных состояний: для каждого &amp;lt;tex&amp;gt;q' \in Q'&amp;lt;/tex&amp;gt; имеем &amp;lt;tex&amp;gt;q' \subseteq Q&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* Начальное состояние в &amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} множество из &amp;lt;tex&amp;gt;I&amp;lt;/tex&amp;gt; начальных состояний автомата &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* Состояние в детерминированном автомате является терминальным тогда и только тогда, когда оно содержится хотя бы в одном недетерминированном состоянии,&lt;br /&gt;
* Пусть &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; {{---}} состояние детерминированного автомата и &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; – символ из &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;. Если переход из &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; по символу &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; определен, тогда, по построению: &amp;lt;tex&amp;gt;\delta'(q', a) = \bigcup\limits_{q \in q'}{ \delta(q, a)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=4&lt;br /&gt;
|statement=&lt;br /&gt;
Правый язык состояния &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; эквивалентен объединению правых языков состояний &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; автомата &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, принадлежащих множеству &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Левое отношение'''  (англ. ''left quotient'') регулярного языка &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;\Sigma^{*}&amp;lt;/tex&amp;gt; {{---}} язык &amp;lt;tex&amp;gt;u^{-1}L = \{ v \in X^{*} \mid uv \in L \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Минимальный автомат &amp;lt;tex&amp;gt;\mathcal{A}_{L}&amp;lt;/tex&amp;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;
* начальное состояние {{---}} &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* терминальные состояния {{---}} множество отношений, содержащих пустое слово,&lt;br /&gt;
* функция перехода &amp;lt;tex&amp;gt;\delta(u^{-1}L, x) = (ux)^{-1}L&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Автомат &amp;lt;tex&amp;gt;\mathcal{A}_L&amp;lt;/tex&amp;gt; уникален с точностью до изоморфизма и имеет минимальное количество состояний. &lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=5&lt;br /&gt;
|statement=&lt;br /&gt;
Детерминированный полный достижимый автомат минимален тогда и только тогда, когда правые языки его состояний различны.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Алгоритм==&lt;br /&gt;
===Описание===&lt;br /&gt;
Алгоритм минимизации конечных [[Детерминированные конечные автоматы|автоматов]] Бржозовского (Janusz A. (John) Brzozowski) выделяется, по крайней мере, следующими качествами:&lt;br /&gt;
* Он элегантен и весьма оригинален.&lt;br /&gt;
* Он эффективен.&lt;br /&gt;
* Он работает даже с [[Недетерминированные конечные автоматы|недетерминированными конечными автоматами]].&lt;br /&gt;
&lt;br /&gt;
Введём следующие обозначения:&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} конечный автомат,&lt;br /&gt;
*&amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} детерминизированный автомат для &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
*&amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} обратный автомат для &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
*&amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} результат &amp;lt;tex&amp;gt;d(r(\mathcal{A}))&amp;lt;/tex&amp;gt;. Аналогично для &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about=Бржозовский, 1962&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} автомат (необязательно детерминированный), распознающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Минимальный детерминированный автомат &amp;lt;tex&amp;gt;\mathcal{A}_L&amp;lt;/tex&amp;gt; может быть вычислен следующим образом: &amp;lt;tex&amp;gt;\mathcal{A}_L = drdr(\mathcal{A})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
По построению автомат &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; детерминированный. Согласно утверждению 2, он распознает язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt; &lt;br /&gt;
Покажем, что все правые языки &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; различны. Из утверждения 1, левые языки &amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt; попарно не пересекаются. Из утверждения 3, правые языки &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt; являются левыми языками &amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt;. Таким образом, они попарно не пересекаются. Согласно утверждению 4, правый язык &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} объединение правых языков &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Поскольку правые языки &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt; попарно не пересекаются, все правые языки &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; различны. &lt;br /&gt;
Так как все правые языки &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; различны, согласно утверждению 5 автомат &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; минимальный. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Пример работы===&lt;br /&gt;
# Исходный [[Недетерминированные конечные автоматы|НКА]] &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Fa.png|Исходный НКА]]&lt;br /&gt;
# Первый шаг, &amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Rfa.png|Первый шаг]]&lt;br /&gt;
# Второй шаг, &amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Drfa.png|Второй шаг]]&amp;lt;br&amp;gt;В детерминизированных автоматах состояния переименованы, так что &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; всегда является начальным состоянием.&lt;br /&gt;
# Третий шаг, &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Rdrfa.png|Третий шаг]]&amp;lt;br&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;
# Заключительный шаг, &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Drdrfa.png|Заключительный шаг]]&lt;br /&gt;
&lt;br /&gt;
== Заключение ==&lt;br /&gt;
Самым эффективным алгоритмом минимизации принято считать [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]], который, как и прочие традиционные алгоритмы, работает только с [[Детерминированные_конечные_автоматы|ДКА]]. Его асимптотическое время выполнения зависит от логарифма исходных данных. С другой стороны очевидно, что алгоритм Бржозовского в худшем случае будет обладать экспоненциальным временем выполнения, ведь этого требует процедура детерминизации, выполняемая дважды. На практике же наблюдается парадокс, алгоритм Бржозовского во многих случаях опережает прочие подходы к минимизации, включая и [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]]. В работе&amp;lt;ref&amp;gt;[http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=A511A421C93DF66BDCC32A0E133D1F99?doi=10.1.1.59.8276&amp;amp;rep=rep1&amp;amp;type=pdf Deian Tabakov, Moshe Y. Vardi. Experimental evaluation of classical automata constructions]&amp;lt;/ref&amp;gt;, сравнивающей оба алгоритма, показано, что алгоритм Бржозовского оказывается эффективнее [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритма Хопкрофта]] для автоматов с большим числом переходов.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Минимизация ДКА, алгоритм за O(n^2) с построением пар различимых состояний]]&lt;br /&gt;
*[[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))]]&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [https://pdfs.semanticscholar.org/f3be/b5e5825e6eedaab7f382341c9dd9c2ab33fa.pdf J.-M. Champarnaud, A. Khorsi, T. Paranthoen {{---}} Split and join for minimizing: Brzozowski's algorithm]&lt;br /&gt;
* [http://sovietov.com/txt/minfa/minfa.html Пётр Советов {{---}} Алгоритм Бржозовского для минимизации конечного автомата]&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55836</id>
		<title>Алгоритм Бржозовского</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55836"/>
				<updated>2016-11-12T17:06:17Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Задача&lt;br /&gt;
|definition = &lt;br /&gt;
Пусть дан [[Детерминированные_конечные_автоматы|автомат]] &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;. Требуется построить автомат &amp;lt;tex&amp;gt;\mathcal{A}_{min}&amp;lt;/tex&amp;gt; с наименьшим количеством состояний, распознающий тот же язык, что и &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; {{---}} состояние автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q, s \in Q, T \subset Q, \delta : Q \times \Sigma \to Q \rangle&amp;lt;/tex&amp;gt;. &lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Правым языком''' (англ. ''right language'') называется язык &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;, распознаваемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; является уникальным начальным состоянием.&lt;br /&gt;
 }}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Левым языком''' (англ. ''left language'') называется язык &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, распознаваемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; является уникальным терминальным состоянием.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
Таким образом, допустимые слова языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, проходящие через состояние &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;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;y&amp;lt;/tex&amp;gt; из левого языка &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;. Тогда множество слов &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt; {{---}} [[Контексты_и_синтаксические_моноиды|правый контекст]] слова &amp;lt;tex&amp;gt;y&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;
|about=1&lt;br /&gt;
|statement=&lt;br /&gt;
Автомат является детерминированным тогда и только тогда, когда левые языки его состояний попарно не пересекаются.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратное слово''' (англ. ''reverse of the word'') &amp;lt;tex&amp;gt;r(u)&amp;lt;/tex&amp;gt; для слова &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; определяется следующим образом: &amp;lt;tex&amp;gt;r(\varepsilon) = \varepsilon&amp;lt;/tex&amp;gt; и если &amp;lt;tex&amp;gt;u = u_1 u_2 u_3 \dotsc u_p&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;r(u) = v_1 v_2 v_3 \dotsc v_p&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_i = u_{p - i + 1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный язык''' (англ. ''reverse of the language'') для языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} язык &amp;lt;tex&amp;gt;r(L) = \{ u \mid r(u) \in L \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный автомат''' (англ. ''reverse of the automaton'') для автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q , S , T , \delta \rangle&amp;lt;/tex&amp;gt; {{---}} автомат &amp;lt;tex&amp;gt;r(\mathcal{A}) = \langle \Sigma , Q , T , I , r(\delta) \rangle&amp;lt;/tex&amp;gt;, полученный из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; сменой местами начальных и конечных состояний и сменой направлений переходов.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=&lt;br /&gt;
Если &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; распознает язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt; распознает &amp;lt;tex&amp;gt;r(L)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=3&lt;br /&gt;
|statement=&lt;br /&gt;
Если левый язык состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, тогда его левый язык в &amp;lt;tex&amp;gt;r(A)&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;. Аналогично для правого языка &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q , I , T , \delta \rangle&amp;lt;/tex&amp;gt; {{---}} [[Недетерминированные_конечные_автоматы|НКА]].&amp;lt;br&amp;gt;Тогда детерминированный автомат &amp;lt;tex&amp;gt;d(\mathcal{A}) = \langle \Sigma , Q' , \{ i' \} , T' , \delta' \rangle&amp;lt;/tex&amp;gt; определяется следующим образом:&lt;br /&gt;
* Детерминированному состоянию соответствует множество недетерминированных состояний: для каждого &amp;lt;tex&amp;gt;q' \in Q'&amp;lt;/tex&amp;gt; имеем &amp;lt;tex&amp;gt;q' \subseteq Q&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* Начальное состояние в &amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} множество из &amp;lt;tex&amp;gt;I&amp;lt;/tex&amp;gt; начальных состояний автомата &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* Состояние в детерминированном автомате является терминальным тогда и только тогда, когда оно содержится хотя бы в одном недетерминированном состоянии,&lt;br /&gt;
* Пусть &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; {{---}} состояние детерминированного автомата и &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; – символ из &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;. Если переход из &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; по символу &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; определен, тогда, по построению: &amp;lt;tex&amp;gt;\delta'(q', a) = \bigcup\limits_{q \in q'}{ \delta(q, a)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=4&lt;br /&gt;
|statement=&lt;br /&gt;
Правый язык состояния &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; эквивалентен объединению правых языков состояний &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; автомата &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, принадлежащих множеству &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Левое отношение'''  (англ. ''left quotient'') регулярного языка &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;\Sigma^{*}&amp;lt;/tex&amp;gt; {{---}} язык &amp;lt;tex&amp;gt;u^{-1}L = \{ v \in X^{*} \mid uv \in L \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Минимальный автомат &amp;lt;tex&amp;gt;\mathcal{A}_{L}&amp;lt;/tex&amp;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;
* начальное состояние {{---}} &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* терминальные состояния {{---}} множество отношений, содержащих пустое слово,&lt;br /&gt;
* функция перехода &amp;lt;tex&amp;gt;\delta(u^{-1}L, x) = (ux)^{-1}L&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Автомат &amp;lt;tex&amp;gt;\mathcal{A}_L&amp;lt;/tex&amp;gt; уникален с точностью до изоморфизма и имеет минимальное количество состояний. &lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=5&lt;br /&gt;
|statement=&lt;br /&gt;
Детерминированный полный достижимый автомат минимален тогда и только тогда, когда правые языки его состояний различны.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Алгоритм==&lt;br /&gt;
===Описание===&lt;br /&gt;
Алгоритм минимизации конечных [[Детерминированные конечные автоматы|автоматов]] Бржозовского (Janusz A. (John) Brzozowski) выделяется, по крайней мере, следующими качествами:&lt;br /&gt;
* Он элегантен и весьма оригинален.&lt;br /&gt;
* Он эффективен.&lt;br /&gt;
* Он работает даже с [[Недетерминированные конечные автоматы|недетерминированными конечными автоматами]].&lt;br /&gt;
&lt;br /&gt;
Введём следующие обозначения:&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} конечный автомат,&lt;br /&gt;
*&amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} детерминизированный автомат для &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
*&amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} обратный автомат для &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
*&amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} результат &amp;lt;tex&amp;gt;d(r(\mathcal{A}))&amp;lt;/tex&amp;gt;. Аналогично для &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about=Бржозовский, 1962&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} автомат (необязательно детерминированный), распознающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Минимальный детерминированный автомат &amp;lt;tex&amp;gt;\mathcal{A}_L&amp;lt;/tex&amp;gt; может быть вычислен следующим образом: &amp;lt;tex&amp;gt;\mathcal{A}_L = drdr(\mathcal{A})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
По построению автомат &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; детерминированный. Согласно утверждению 2, он распознает язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt; &lt;br /&gt;
Покажем, что все правые языки &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; различны. Из утверждения 1, левые языки &amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt; попарно не пересекаются. Из утверждения 3, правые языки &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt; являются левыми языками &amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt;. Таким образом, они попарно не пересекаются. Согласно утверждению 4, правый язык &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} объединение правых языков &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Поскольку правые языки &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt; попарно не пересекаются, все правые языки &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; различны. &lt;br /&gt;
Так как все правые языки &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; различны, согласно утверждению 5 автомат &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; минимальный. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Пример работы===&lt;br /&gt;
# Исходный [[Недетерминированные конечные автоматы|НКА]] &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Fa.png|Исходный НКА]]&lt;br /&gt;
# Первый шаг, &amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Rfa.png|Первый шаг]]&lt;br /&gt;
# Второй шаг, &amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Drfa.png|Второй шаг]]&amp;lt;br&amp;gt;В детерминизированных автоматах состояния переименованы, так что &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; всегда является начальным состоянием.&lt;br /&gt;
# Третий шаг, &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Rdrfa.png|Третий шаг]]&amp;lt;br&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;
# Заключительный шаг, &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Drdrfa.png|Заключительный шаг]]&lt;br /&gt;
&lt;br /&gt;
== Заключение ==&lt;br /&gt;
Самым эффективным алгоритмом минимизации принято считать [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]], который, как и прочие традиционные алгоритмы, работает только с [[Детерминированные_конечные_автоматы|ДКА]]. Его асимптотическое время выполнения зависит от логарифма исходных данных. С другой стороны очевидно, что алгоритм Бржозовского в худшем случае будет обладать экспоненциальным временем выполнения, ведь этого требует процедура детерминизации, выполняемая дважды. На практике же наблюдается парадокс, алгоритм Бржозовского во многих случаях опережает прочие подходы к минимизации, включая и [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]]. В работе&amp;lt;ref&amp;gt;[http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=A511A421C93DF66BDCC32A0E133D1F99?doi=10.1.1.59.8276&amp;amp;rep=rep1&amp;amp;type=pdf Deian Tabakov, Moshe Y. Vardi. Experimental evaluation of classical automata constructions]&amp;lt;/ref&amp;gt;, сравнивающей оба алгоритма, показано, что алгоритм Бржозовского оказывается эффективнее [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритма Хопкрофта]] для автоматов с большим числом переходов.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Минимизация ДКА, алгоритм за O(n^2) с построением пар различимых состояний]]&lt;br /&gt;
*[[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))]]&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [https://pdfs.semanticscholar.org/f3be/b5e5825e6eedaab7f382341c9dd9c2ab33fa.pdf J.-M. Champarnaud, A. Khorsi, T. Paranthoen {{---}} Split and join for minimizing: Brzozowski's algorithm]&lt;br /&gt;
* [http://sovietov.com/txt/minfa/minfa.html Пётр Советов {{---}} Алгоритм Бржозовского для минимизации конечного автомата]&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55835</id>
		<title>Алгоритм Бржозовского</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55835"/>
				<updated>2016-11-12T16:59:48Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: /* Описание */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Задача&lt;br /&gt;
|definition = &lt;br /&gt;
Пусть дан [[Детерминированные_конечные_автоматы|автомат]] &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;. Требуется построить автомат &amp;lt;tex&amp;gt;\mathcal{A}_{min}&amp;lt;/tex&amp;gt; с наименьшим количеством состояний, распознающий тот же язык, что и &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; {{---}} состояние автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q, s \in Q, T \subset Q, \delta : Q \times \Sigma \to Q \rangle&amp;lt;/tex&amp;gt;. &lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Правым языком''' (англ. ''right language'') называется язык &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;, распознаваемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; является уникальным начальным состоянием.&lt;br /&gt;
 }}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Левым языком''' (англ. ''left language'') называется язык &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, распознаваемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; является уникальным терминальным состоянием.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
Таким образом, допустимые слова языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, проходящие через состояние &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;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;y&amp;lt;/tex&amp;gt; из левого языка &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;. Тогда множество слов &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt; {{---}} [[Контексты_и_синтаксические_моноиды|правый контекст]] слова &amp;lt;tex&amp;gt;y&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;
|about=1&lt;br /&gt;
|statement=&lt;br /&gt;
Автомат является детерминированным тогда и только тогда, когда левые языки его состояний попарно не пересекаются.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратное слово''' &amp;lt;tex&amp;gt;r(u)&amp;lt;/tex&amp;gt; для слова &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; определяется следующим образом: &amp;lt;tex&amp;gt;r(\varepsilon) = \varepsilon&amp;lt;/tex&amp;gt; и если &amp;lt;tex&amp;gt;u = u_1 u_2 u_3 \dotsc u_p&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;r(u) = v_1 v_2 v_3 \dotsc v_p&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_i = u_{p - i + 1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный язык''' для языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} язык &amp;lt;tex&amp;gt;r(L) = \{ u \mid r(u) \in L \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный автомат''' для автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q , S , T , \delta \rangle&amp;lt;/tex&amp;gt; {{---}} автомат &amp;lt;tex&amp;gt;r(\mathcal{A}) = \langle \Sigma , Q , T , I , r(\delta) \rangle&amp;lt;/tex&amp;gt;, полученный из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; сменой местами начальных и конечных состояний и сменой направлений переходов.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=&lt;br /&gt;
Если &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; распознает язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt; распознает &amp;lt;tex&amp;gt;r(L)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=3&lt;br /&gt;
|statement=&lt;br /&gt;
Если левый язык состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, тогда его левый язык в &amp;lt;tex&amp;gt;r(A)&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;. Аналогично для правого языка &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q , I , T , \delta \rangle&amp;lt;/tex&amp;gt; {{---}} [[Недетерминированные_конечные_автоматы|НКА]].&amp;lt;br&amp;gt;Тогда детерминированный автомат &amp;lt;tex&amp;gt;d(\mathcal{A}) = \langle \Sigma , Q' , \{ i' \} , T' , \delta' \rangle&amp;lt;/tex&amp;gt; определяется следующим образом:&lt;br /&gt;
* Детерминированному состоянию соответствует множество недетерминированных состояний: для каждого &amp;lt;tex&amp;gt;q' \in Q'&amp;lt;/tex&amp;gt; имеем &amp;lt;tex&amp;gt;q' \subseteq Q&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* Начальное состояние в &amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} множество из &amp;lt;tex&amp;gt;I&amp;lt;/tex&amp;gt; начальных состояний автомата &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* Состояние в детерминированном автомате является терминальным тогда и только тогда, когда оно содержится хотя бы в одном недетерминированном состоянии,&lt;br /&gt;
* Пусть &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; {{---}} состояние детерминированного автомата и &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; – символ из &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;. Если переход из &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; по символу &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; определен, тогда, по построению: &amp;lt;tex&amp;gt;\delta'(q', a) = \bigcup\limits_{q \in q'}{ \delta(q, a)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=4&lt;br /&gt;
|statement=&lt;br /&gt;
Правый язык состояния &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; эквивалентен объединению правых языков состояний &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; автомата &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, принадлежащих множеству &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Левое отношение'''  (англ. ''left quotient'') регулярного языка &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;\Sigma^{*}&amp;lt;/tex&amp;gt; {{---}} язык &amp;lt;tex&amp;gt;u^{-1}L = \{ v \in X^{*} \mid uv \in L \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Минимальный автомат &amp;lt;tex&amp;gt;\mathcal{A}_{L}&amp;lt;/tex&amp;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;
* начальное состояние {{---}} &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* терминальные состояния {{---}} множество отношений, содержащих пустое слово,&lt;br /&gt;
* функция перехода &amp;lt;tex&amp;gt;\delta(u^{-1}L, x) = (ux)^{-1}L&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Автомат &amp;lt;tex&amp;gt;\mathcal{A}_L&amp;lt;/tex&amp;gt; уникален с точностью до изоморфизма и имеет минимальное количество состояний. &lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=5&lt;br /&gt;
|statement=&lt;br /&gt;
Детерминированный полный достижимый автомат минимален тогда и только тогда, когда правые языки его состояний различны.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Алгоритм==&lt;br /&gt;
===Описание===&lt;br /&gt;
Алгоритм минимизации конечных [[Детерминированные конечные автоматы|автоматов]] Бржозовского (Janusz A. (John) Brzozowski) выделяется, по крайней мере, следующими качествами:&lt;br /&gt;
* Он элегантен и весьма оригинален.&lt;br /&gt;
* Он эффективен.&lt;br /&gt;
* Он работает даже с [[Недетерминированные конечные автоматы|недетерминированными конечными автоматами]].&lt;br /&gt;
&lt;br /&gt;
Введём следующие обозначения:&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} конечный автомат,&lt;br /&gt;
*&amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} детерминизированный автомат для &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
*&amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} обратный автомат для &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
*&amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} результат &amp;lt;tex&amp;gt;d(r(\mathcal{A}))&amp;lt;/tex&amp;gt;. Аналогично для &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about=Бржозовский, 1962&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} автомат (необязательно детерминированный), распознающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Минимальный детерминированный автомат &amp;lt;tex&amp;gt;\mathcal{A}_L&amp;lt;/tex&amp;gt; может быть вычислен следующим образом: &amp;lt;tex&amp;gt;\mathcal{A}_L = drdr(\mathcal{A})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
По построению автомат &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; детерминированный. Согласно утверждению 2, он распознает язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt; &lt;br /&gt;
Покажем, что все правые языки &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; различны. Из утверждения 1, левые языки &amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt; попарно не пересекаются. Из утверждения 3, правые языки &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt; являются левыми языками &amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt;. Таким образом, они попарно не пересекаются. Согласно утверждению 4, правый язык &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} объединение правых языков &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Поскольку правые языки &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt; попарно не пересекаются, все правые языки &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; различны. &lt;br /&gt;
Так как все правые языки &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; различны, согласно утверждению 5 автомат &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; минимальный. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Пример работы===&lt;br /&gt;
# Исходный [[Недетерминированные конечные автоматы|НКА]] &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Fa.png|Исходный НКА]]&lt;br /&gt;
# Первый шаг, &amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Rfa.png|Первый шаг]]&lt;br /&gt;
# Второй шаг, &amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Drfa.png|Второй шаг]]&amp;lt;br&amp;gt;В детерминизированных автоматах состояния переименованы, так что &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; всегда является начальным состоянием.&lt;br /&gt;
# Третий шаг, &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Rdrfa.png|Третий шаг]]&amp;lt;br&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;
# Заключительный шаг, &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Drdrfa.png|Заключительный шаг]]&lt;br /&gt;
&lt;br /&gt;
== Заключение ==&lt;br /&gt;
Самым эффективным алгоритмом минимизации принято считать [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]], который, как и прочие традиционные алгоритмы, работает только с [[Детерминированные_конечные_автоматы|ДКА]]. Его асимптотическое время выполнения зависит от логарифма исходных данных. С другой стороны очевидно, что алгоритм Бржозовского в худшем случае будет обладать экспоненциальным временем выполнения, ведь этого требует процедура детерминизации, выполняемая дважды. На практике же наблюдается парадокс, алгоритм Бржозовского во многих случаях опережает прочие подходы к минимизации, включая и [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]]. В работе&amp;lt;ref&amp;gt;[http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=A511A421C93DF66BDCC32A0E133D1F99?doi=10.1.1.59.8276&amp;amp;rep=rep1&amp;amp;type=pdf Deian Tabakov, Moshe Y. Vardi. Experimental evaluation of classical automata constructions]&amp;lt;/ref&amp;gt;, сравнивающей оба алгоритма, показано, что алгоритм Бржозовского оказывается эффективнее [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритма Хопкрофта]] для автоматов с большим числом переходов.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Минимизация ДКА, алгоритм за O(n^2) с построением пар различимых состояний]]&lt;br /&gt;
*[[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))]]&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [https://pdfs.semanticscholar.org/f3be/b5e5825e6eedaab7f382341c9dd9c2ab33fa.pdf J.-M. Champarnaud, A. Khorsi, T. Paranthoen {{---}} Split and join for minimizing: Brzozowski's algorithm]&lt;br /&gt;
* [http://sovietov.com/txt/minfa/minfa.html Пётр Советов {{---}} Алгоритм Бржозовского для минимизации конечного автомата]&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55769</id>
		<title>Алгоритм Бржозовского</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55769"/>
				<updated>2016-11-05T22:46:09Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: /* Описание */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Задача&lt;br /&gt;
|definition = &lt;br /&gt;
Пусть дан [[Детерминированные_конечные_автоматы|автомат]] &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;. Требуется построить автомат &amp;lt;tex&amp;gt;\mathcal{A}_{min}&amp;lt;/tex&amp;gt; с наименьшим количеством состояний, распознающий тот же язык, что и &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; {{---}} состояние автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q, s \in Q, T \subset Q, \delta : Q \times \Sigma \to Q \rangle&amp;lt;/tex&amp;gt;. &lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Правым языком''' (англ. ''right language'') называется язык &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;, распознаваемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; является уникальным начальным состоянием.&lt;br /&gt;
 }}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Левым языком''' (англ. ''left language'') называется язык &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, распознаваемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; является уникальным терминальным состоянием.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=1&lt;br /&gt;
|statement=&lt;br /&gt;
Автомат является детерминированным тогда и только тогда, когда левые языки его состояний попарно не пересекаются.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратное слово''' &amp;lt;tex&amp;gt;r(u)&amp;lt;/tex&amp;gt; для слова &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; определяется следующим образом: &amp;lt;tex&amp;gt;r(\varepsilon) = \varepsilon&amp;lt;/tex&amp;gt; и если &amp;lt;tex&amp;gt;u = u_1 u_2 u_3 \dotsc u_p&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;r(u) = v_1 v_2 v_3 \dotsc v_p&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_i = u_{p - i + 1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный язык''' для языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} язык &amp;lt;tex&amp;gt;r(L) = \{ u \mid r(u) \in L \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный автомат''' для автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q , S , T , \delta \rangle&amp;lt;/tex&amp;gt; {{---}} автомат &amp;lt;tex&amp;gt;r(\mathcal{A}) = \langle \Sigma , Q , T , I , r(\delta) \rangle&amp;lt;/tex&amp;gt;, полученный из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; сменой местами начальных и конечных состояний и сменой направлений переходов.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=&lt;br /&gt;
Если &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; распознает язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt; распознает &amp;lt;tex&amp;gt;r(L)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=3&lt;br /&gt;
|statement=&lt;br /&gt;
Если левый язык состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, тогда его левый язык в &amp;lt;tex&amp;gt;r(A)&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;. Аналогично для правого языка &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q , I , T , \delta \rangle&amp;lt;/tex&amp;gt; {{---}} [[Недетерминированные_конечные_автоматы|НКА]].&amp;lt;br&amp;gt;Тогда детерминированный автомат &amp;lt;tex&amp;gt;d(\mathcal{A}) = \langle \Sigma , Q' , \{ i' \} , T' , \delta' \rangle&amp;lt;/tex&amp;gt; определяется следующим образом:&lt;br /&gt;
* Детерминированному состоянию соответствует множество недетерминированных состояний: для каждого &amp;lt;tex&amp;gt;q' \in Q'&amp;lt;/tex&amp;gt; имеем &amp;lt;tex&amp;gt;q' \subseteq Q&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* Начальное состояние в &amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} множество из &amp;lt;tex&amp;gt;I&amp;lt;/tex&amp;gt; начальных состояний автомата &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* Состояние в детерминированном автомате является терминальным тогда и только тогда, когда оно содержится хотя бы в одном недетерминированном состоянии,&lt;br /&gt;
* Пусть &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; {{---}} состояние детерминированного автомата и &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; – символ из &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;. Если переход из &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; по символу &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; определен, тогда, по построению: &amp;lt;tex&amp;gt;\delta'(q', a) = \bigcup\limits_{q \in q'}{ \delta(q, a)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=4&lt;br /&gt;
|statement=&lt;br /&gt;
Правый язык состояния &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; эквивалентен объединению правых языков состояний &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; автомата &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, принадлежащих множеству &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Левое отношение'''  (англ. ''left quotient'') регулярного языка &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;\Sigma^{*}&amp;lt;/tex&amp;gt; {{---}} язык &amp;lt;tex&amp;gt;u^{-1}L = \{ v \in X^{*} \mid uv \in L \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Минимальный автомат &amp;lt;tex&amp;gt;\mathcal{A}_{L}&amp;lt;/tex&amp;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;
* начальное состояние {{---}} &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* терминальные состояния {{---}} множество отношений, содержащих пустое слово,&lt;br /&gt;
* функция перехода &amp;lt;tex&amp;gt;\delta(u^{-1}L, x) = (ux)^{-1}L&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Автомат &amp;lt;tex&amp;gt;\mathcal{A}_L&amp;lt;/tex&amp;gt; уникален с точностью до изоморфизма и имеет минимальное количество состояний. &lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=5&lt;br /&gt;
|statement=&lt;br /&gt;
Детерминированный полный достижимый автомат минимален тогда и только тогда, когда правые языки его состояний различны.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Алгоритм==&lt;br /&gt;
===Описание===&lt;br /&gt;
Алгоритм минимизации конечных [[Детерминированные конечные автоматы|автоматов]] Бржозовского (Janusz A. (John) Brzozowski) выделяется, по крайней мере, следующими качествами:&lt;br /&gt;
* Он элегантен и весьма оригинален.&lt;br /&gt;
* Он эффективен.&lt;br /&gt;
* Он работает даже с [[Недетерминированные конечные автоматы|недетерминированными конечными автоматами]].&lt;br /&gt;
&lt;br /&gt;
Введём следующие обозначения:&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} конечный автомат,&lt;br /&gt;
*&amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} детерминизированный автомат для &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
*&amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} обратный автомат для &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
*&amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} результат &amp;lt;tex&amp;gt;d(r(\mathcal{A}))&amp;lt;/tex&amp;gt;. Аналогично для &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about=Бржозовский, 1962&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} автомат (необязательно детерминированный), распознающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Минимальный детерминированный автомат &amp;lt;tex&amp;gt;\mathcal{A}_L&amp;lt;/tex&amp;gt; может быть вычислен следующим образом: &amp;lt;tex&amp;gt;\mathcal{A}_L = drdr(\mathcal{A})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
По построению автомат &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; детерминированный. Согласно утверждению 2, он распознает язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt; &lt;br /&gt;
Покажем, что все правые языки &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; различны. Из утверждения 1, левые языки &amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt; попарно не пересекаются. Из утверждения 3, правые языки &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt; являются левыми языками &amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt;. Таким образом, они попарно не пересекаются. Согласно утверждению 4, правый язык &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} объединение правых языков &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Поскольку правые языки &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt; попарно не пересекаются, все правые языки &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; различны. &lt;br /&gt;
Так как все правые языки &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; различны, согласно утверждению 5 автомат &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; минимальный. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Пример работы===&lt;br /&gt;
# Исходный [[Недетерминированные конечные автоматы|НКА]] &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Fa.png|Исходный НКА]]&lt;br /&gt;
# Первый шаг, &amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Rfa.png|Первый шаг]]&lt;br /&gt;
# Второй шаг, &amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Drfa.png|Второй шаг]]&amp;lt;br&amp;gt;В детерминизированных автоматах состояния переименованы, так что &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; всегда является начальным состоянием.&lt;br /&gt;
# Третий шаг, &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Rdrfa.png|Третий шаг]]&amp;lt;br&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;
# Заключительный шаг, &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Drdrfa.png|Заключительный шаг]]&lt;br /&gt;
&lt;br /&gt;
== Заключение ==&lt;br /&gt;
Самым эффективным алгоритмом минимизации принято считать [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]], который, как и прочие традиционные алгоритмы, работает только с [[Детерминированные_конечные_автоматы|ДКА]]. Его асимптотическое время выполнения зависит от логарифма исходных данных. С другой стороны очевидно, что алгоритм Бржозовского в худшем случае будет обладать экспоненциальным временем выполнения, ведь этого требует процедура детерминизации, выполняемая дважды. На практике же наблюдается парадокс, алгоритм Бржозовского во многих случаях опережает прочие подходы к минимизации, включая и [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]]. В работе&amp;lt;ref&amp;gt;[http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=A511A421C93DF66BDCC32A0E133D1F99?doi=10.1.1.59.8276&amp;amp;rep=rep1&amp;amp;type=pdf Deian Tabakov, Moshe Y. Vardi. Experimental evaluation of classical automata constructions]&amp;lt;/ref&amp;gt;, сравнивающей оба алгоритма, показано, что алгоритм Бржозовского оказывается эффективнее [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритма Хопкрофта]] для автоматов с большим числом переходов.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Минимизация ДКА, алгоритм за O(n^2) с построением пар различимых состояний]]&lt;br /&gt;
*[[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))]]&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [https://pdfs.semanticscholar.org/f3be/b5e5825e6eedaab7f382341c9dd9c2ab33fa.pdf J.-M. Champarnaud, A. Khorsi, T. Paranthoen {{---}} Split and join for minimizing: Brzozowski's algorithm]&lt;br /&gt;
* [http://sovietov.com/txt/minfa/minfa.html Пётр Советов {{---}} Алгоритм Бржозовского для минимизации конечного автомата]&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55768</id>
		<title>Удаление бесполезных символов из грамматики</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55768"/>
				<updated>2016-11-05T22:42:30Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: /* Источники информации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Порождающие и непорождающие нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
[[Формальные_грамматики|Нетерминал]] &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''порождающим''' (англ. ''generating''), если из него может быть выведена конечная терминальная цепочка. Иначе он называется '''непорождающим'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Очевидно, что если и только если все нетерминалы правой части правила являются порождающими, то порождающим является и нетерминал, стоящий в его левой части. Это позволяет обнаружить непорождающие нетерминалы с помощью следующей процедуры:&lt;br /&gt;
# Найти правила, не содержащие нетерминалов в правых частях. Составить множество нетерминалов, встречающихся в левых частях таких правил.&lt;br /&gt;
# Если найдено такое правило, что все нетерминалы, стоящие в его правой части, уже входят в множество, то добавить в множество нетерминалы, стоящие в его левой части.&lt;br /&gt;
# Если на шаге 2 множество изменилось, повторить шаг 2.&lt;br /&gt;
# Получено множество всех порождающих нетерминалов грамматики, а все нетерминалы, не попавшие в него, являются непорождающими.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих непорождающие нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Непорождающие нетерминалы по определению не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\left| \Gamma \right|&amp;lt;/tex&amp;gt; {{---}} размер грамматики. Однако используя [[Очередь|очередь]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Модификация алгоритма с очередью===&lt;br /&gt;
Для реализации алгоритма поиска непорождающих нетерминалов будем использовать следующие структуры:&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{isGenerating[nonterm_i]}&amp;lt;/tex&amp;gt; {{---}} является ли нетерминал &amp;lt;tex&amp;gt;nonterm_i&amp;lt;/tex&amp;gt; порождающим или нет,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{counter[rule_i]}&amp;lt;/tex&amp;gt; {{---}} счетчик количества нетерминалов, которые ещё не помечены порождающими, для каждого из правил,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{concernedRules[nonterm_i]}&amp;lt;/tex&amp;gt; {{---}} для каждого нетерминала &amp;lt;tex&amp;gt;nonterm_i&amp;lt;/tex&amp;gt; список номеров правил, в правой части которых он встречается,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{Q}&amp;lt;/tex&amp;gt; {{---}} очередь нетерминалов, помеченных порождающими, но ещё не обработанных.&lt;br /&gt;
&lt;br /&gt;
Вначале для всех нетерминалов в &amp;lt;tex&amp;gt;\mathrm{isGenerating}&amp;lt;/tex&amp;gt; поставим &amp;lt;tex&amp;gt;false&amp;lt;/tex&amp;gt;. В &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; поставим количество нетерминалов в правой части. Нетерминалы, у которых счётчик &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; нулевой, добавим в очередь и отметим их порождающими.&amp;lt;br&amp;gt;&lt;br /&gt;
Пока в очереди есть элементы, достаём очередной нетерминал и уменьшаем &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; для всех правил из &amp;lt;tex&amp;gt;\mathrm{concernedRules}&amp;lt;/tex&amp;gt; для данного нетерминала. Если счётчик количества порождающих терминалов обнулился, то добавим нетерминал, стоящий в левой части данного правила в очередь и пометим его порождающим.&amp;lt;br&amp;gt;&lt;br /&gt;
Каждый из нетерминалов попадёт в очередь только один раз, следовательно мы пройдем по списку правил, в правой части которых он встречается, один раз. Таким образом, суммарно получаем &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
 S\rightarrow Ac\\&lt;br /&gt;
 A\rightarrow SD\\&lt;br /&gt;
 D\rightarrow aD\\&lt;br /&gt;
 A\rightarrow a    &lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Изначально множество порождающих нетерминалов состоит из одного элемента &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Добавим в множество нетерминал &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, так как существует правило &amp;lt;tex&amp;gt;S\rightarrow Ac&amp;lt;/tex&amp;gt;, в правой части которого стоят нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, который есть в множестве, и терминал &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# После следующего обхода правил из грамматики множество не изменится.&lt;br /&gt;
# Теперь удалим правила &amp;lt;tex&amp;gt;A\rightarrow SD&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D\rightarrow aD&amp;lt;/tex&amp;gt;, так как они содержит нетерминалы, которых нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Достижимые и недостижимые нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''достижимым''' (англ. ''reachable'') в [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|КС-грамматике]] &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если существует порождение &amp;lt;tex&amp;gt;S \Rightarrow^* \alpha A \beta&amp;lt;/tex&amp;gt;. Иначе он называется '''недостижимым''' (англ. ''unreachable'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Очевидно, что если нетерминал в левой части правила является достижимым, то и все нетерминалы правой части являются достижимыми. Найти недостижимые нетерминалы можно с помощью следующей процедуры.&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Если найдено правило, в левой части которого стоит нетерминал, содержащийся в множестве, добавить в множество все нетерминалы из правой части.&lt;br /&gt;
# Если на шаге 2 множество изменилось, повторить шаг 2.&lt;br /&gt;
# Получено множество всех достижимых нетерминалов, а нетерминалы, не попавшие в него, являются недостижимыми.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих недостижимые нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Недостижимые нетерминалы по определению не достижимы из стартового, следовательно они не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, однако используя [[Обход_в_глубину,_цвета_вершин|обход в глубину]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|CD\\&lt;br /&gt;
    A\rightarrow EF\\&lt;br /&gt;
    G\rightarrow AD\\&lt;br /&gt;
    C\rightarrow c&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Из &amp;lt;tex&amp;gt;S&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;C&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;. Добавим их в множество и получим  &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Множество изменилось. Переберём заново правила из грамматики. Из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; можно вывести &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt;, добавим их в множество.&lt;br /&gt;
# Снова переберём правила. Из &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; можно вывести только терминал, а &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; нету в множестве.&lt;br /&gt;
# После последнего обхода правил грамматики множество не изменилось, значит мы нашли все достижимые нетерминалы: &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D, E, F \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Теперь удалим правило &amp;lt;tex&amp;gt;G\rightarrow AD&amp;lt;/tex&amp;gt;, так как оно содержит в левой части нетерминал, которого нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Полезные и бесполезные нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''полезным''' (англ. ''useful'') в КС-грамматике &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если он может участвовать в выводе, то есть существует порождение вида &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* w&amp;lt;/tex&amp;gt;. Иначе он называется '''бесполезным''' (англ. ''useless'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит бесполезных нетерминалов тогда и только тогда, когда грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит ни недостижимых нетерминалов, ни непорождающих.&lt;br /&gt;
|proof=&lt;br /&gt;
''Необходимость.'' Очевидно, так как недостижимые и непорождающие нетерминалы являются бесполезными.&lt;br /&gt;
&lt;br /&gt;
''Достаточность.'' Рассмотрим любой нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как он достижим, существуют &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta&amp;lt;/tex&amp;gt;. Из того, что любой нетерминал является порождающим, следует, что из любой строки можно вывести строку из терминалов. Значит, существует &amp;lt;tex&amp;gt;\omega \in \Sigma ^ *&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;A&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;
Допустим, что в грамматике появился непорождающий нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как до удаления недостижимых нетерминалов существовал вывод из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; некоторой конечной цепочки терминалов &amp;lt;tex&amp;gt;\omega&amp;lt;/tex&amp;gt;, то было удалено хотя бы какое-то одно правило из этого вывода.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;B\rightarrow\alpha&amp;lt;/tex&amp;gt; {{---}} правило, первым из удалённых применяемое в выводе &amp;lt;tex&amp;gt;A \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;. Оно могло быть удалено только в том случае, если в &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; присутствуют недостижимые нетерминалы. Но так как было выбрано первое удалённое правило из вывода, то &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; — достижим, следовательно достижимы и все нетерминалы из &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;. Значит, это правило не могло быть удалено.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
&lt;br /&gt;
1. Пусть нам дана грамматика: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|BS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
2. Удалим правила, содержащие непорождающие нетерминалы: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
3. Теперь удалим недостижимые нетерминалы:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\    &lt;br /&gt;
    A\rightarrow a&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Замечание ===&lt;br /&gt;
Шаги алгоритма нельзя менять местами. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|a \\&lt;br /&gt;
    A\rightarrow b&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все нетерминалы в этой грамматике достижимы. Однако, если удалить &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; как непорождающий, то нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; станет недостижимым.&lt;br /&gt;
== См. также  ==&lt;br /&gt;
* [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|Контекстно-свободные грамматики]]&lt;br /&gt;
* [[Нормальная_форма_Хомского|Нормальная форма Хомского]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [[wikipedia:Formal_grammar | Wikipedia {{---}} Formal grammar]]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Chomsky_normal_form Wikipedia {{---}} Chomsky normal form]&lt;br /&gt;
* ''Хопкрофт Д., Мотвани Р., Ульман Д.'' {{---}} Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. — Москва, Издательский дом «Вильямс», 2002. — 528 с. : ISBN 5-8459-0261-4 (рус.)&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Контекстно-свободные грамматики]]&lt;br /&gt;
[[Категория: Нормальные формы КС-грамматик]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55767</id>
		<title>Удаление бесполезных символов из грамматики</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55767"/>
				<updated>2016-11-05T22:29:44Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: /* Модификация алгоритма с очередью */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Порождающие и непорождающие нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
[[Формальные_грамматики|Нетерминал]] &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''порождающим''' (англ. ''generating''), если из него может быть выведена конечная терминальная цепочка. Иначе он называется '''непорождающим'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Очевидно, что если и только если все нетерминалы правой части правила являются порождающими, то порождающим является и нетерминал, стоящий в его левой части. Это позволяет обнаружить непорождающие нетерминалы с помощью следующей процедуры:&lt;br /&gt;
# Найти правила, не содержащие нетерминалов в правых частях. Составить множество нетерминалов, встречающихся в левых частях таких правил.&lt;br /&gt;
# Если найдено такое правило, что все нетерминалы, стоящие в его правой части, уже входят в множество, то добавить в множество нетерминалы, стоящие в его левой части.&lt;br /&gt;
# Если на шаге 2 множество изменилось, повторить шаг 2.&lt;br /&gt;
# Получено множество всех порождающих нетерминалов грамматики, а все нетерминалы, не попавшие в него, являются непорождающими.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих непорождающие нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Непорождающие нетерминалы по определению не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\left| \Gamma \right|&amp;lt;/tex&amp;gt; {{---}} размер грамматики. Однако используя [[Очередь|очередь]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Модификация алгоритма с очередью===&lt;br /&gt;
Для реализации алгоритма поиска непорождающих нетерминалов будем использовать следующие структуры:&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{isGenerating[nonterm_i]}&amp;lt;/tex&amp;gt; {{---}} является ли нетерминал &amp;lt;tex&amp;gt;nonterm_i&amp;lt;/tex&amp;gt; порождающим или нет,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{counter[rule_i]}&amp;lt;/tex&amp;gt; {{---}} счетчик количества нетерминалов, которые ещё не помечены порождающими, для каждого из правил,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{concernedRules[nonterm_i]}&amp;lt;/tex&amp;gt; {{---}} для каждого нетерминала &amp;lt;tex&amp;gt;nonterm_i&amp;lt;/tex&amp;gt; список номеров правил, в правой части которых он встречается,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{Q}&amp;lt;/tex&amp;gt; {{---}} очередь нетерминалов, помеченных порождающими, но ещё не обработанных.&lt;br /&gt;
&lt;br /&gt;
Вначале для всех нетерминалов в &amp;lt;tex&amp;gt;\mathrm{isGenerating}&amp;lt;/tex&amp;gt; поставим &amp;lt;tex&amp;gt;false&amp;lt;/tex&amp;gt;. В &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; поставим количество нетерминалов в правой части. Нетерминалы, у которых счётчик &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; нулевой, добавим в очередь и отметим их порождающими.&amp;lt;br&amp;gt;&lt;br /&gt;
Пока в очереди есть элементы, достаём очередной нетерминал и уменьшаем &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; для всех правил из &amp;lt;tex&amp;gt;\mathrm{concernedRules}&amp;lt;/tex&amp;gt; для данного нетерминала. Если счётчик количества порождающих терминалов обнулился, то добавим нетерминал, стоящий в левой части данного правила в очередь и пометим его порождающим.&amp;lt;br&amp;gt;&lt;br /&gt;
Каждый из нетерминалов попадёт в очередь только один раз, следовательно мы пройдем по списку правил, в правой части которых он встречается, один раз. Таким образом, суммарно получаем &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
 S\rightarrow Ac\\&lt;br /&gt;
 A\rightarrow SD\\&lt;br /&gt;
 D\rightarrow aD\\&lt;br /&gt;
 A\rightarrow a    &lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Изначально множество порождающих нетерминалов состоит из одного элемента &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Добавим в множество нетерминал &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, так как существует правило &amp;lt;tex&amp;gt;S\rightarrow Ac&amp;lt;/tex&amp;gt;, в правой части которого стоят нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, который есть в множестве, и терминал &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# После следующего обхода правил из грамматики множество не изменится.&lt;br /&gt;
# Теперь удалим правила &amp;lt;tex&amp;gt;A\rightarrow SD&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D\rightarrow aD&amp;lt;/tex&amp;gt;, так как они содержит нетерминалы, которых нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Достижимые и недостижимые нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''достижимым''' (англ. ''reachable'') в [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|КС-грамматике]] &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если существует порождение &amp;lt;tex&amp;gt;S \Rightarrow^* \alpha A \beta&amp;lt;/tex&amp;gt;. Иначе он называется '''недостижимым''' (англ. ''unreachable'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Очевидно, что если нетерминал в левой части правила является достижимым, то и все нетерминалы правой части являются достижимыми. Найти недостижимые нетерминалы можно с помощью следующей процедуры.&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Если найдено правило, в левой части которого стоит нетерминал, содержащийся в множестве, добавить в множество все нетерминалы из правой части.&lt;br /&gt;
# Если на шаге 2 множество изменилось, повторить шаг 2.&lt;br /&gt;
# Получено множество всех достижимых нетерминалов, а нетерминалы, не попавшие в него, являются недостижимыми.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих недостижимые нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Недостижимые нетерминалы по определению не достижимы из стартового, следовательно они не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, однако используя [[Обход_в_глубину,_цвета_вершин|обход в глубину]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|CD\\&lt;br /&gt;
    A\rightarrow EF\\&lt;br /&gt;
    G\rightarrow AD\\&lt;br /&gt;
    C\rightarrow c&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Из &amp;lt;tex&amp;gt;S&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;C&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;. Добавим их в множество и получим  &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Множество изменилось. Переберём заново правила из грамматики. Из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; можно вывести &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt;, добавим их в множество.&lt;br /&gt;
# Снова переберём правила. Из &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; можно вывести только терминал, а &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; нету в множестве.&lt;br /&gt;
# После последнего обхода правил грамматики множество не изменилось, значит мы нашли все достижимые нетерминалы: &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D, E, F \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Теперь удалим правило &amp;lt;tex&amp;gt;G\rightarrow AD&amp;lt;/tex&amp;gt;, так как оно содержит в левой части нетерминал, которого нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Полезные и бесполезные нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''полезным''' (англ. ''useful'') в КС-грамматике &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если он может участвовать в выводе, то есть существует порождение вида &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* w&amp;lt;/tex&amp;gt;. Иначе он называется '''бесполезным''' (англ. ''useless'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит бесполезных нетерминалов тогда и только тогда, когда грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит ни недостижимых нетерминалов, ни непорождающих.&lt;br /&gt;
|proof=&lt;br /&gt;
''Необходимость.'' Очевидно, так как недостижимые и непорождающие нетерминалы являются бесполезными.&lt;br /&gt;
&lt;br /&gt;
''Достаточность.'' Рассмотрим любой нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как он достижим, существуют &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta&amp;lt;/tex&amp;gt;. Из того, что любой нетерминал является порождающим, следует, что из любой строки можно вывести строку из терминалов. Значит, существует &amp;lt;tex&amp;gt;\omega \in \Sigma ^ *&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;A&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;
Допустим, что в грамматике появился непорождающий нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как до удаления недостижимых нетерминалов существовал вывод из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; некоторой конечной цепочки терминалов &amp;lt;tex&amp;gt;\omega&amp;lt;/tex&amp;gt;, то было удалено хотя бы какое-то одно правило из этого вывода.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;B\rightarrow\alpha&amp;lt;/tex&amp;gt; {{---}} правило, первым из удалённых применяемое в выводе &amp;lt;tex&amp;gt;A \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;. Оно могло быть удалено только в том случае, если в &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; присутствуют недостижимые нетерминалы. Но так как было выбрано первое удалённое правило из вывода, то &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; — достижим, следовательно достижимы и все нетерминалы из &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;. Значит, это правило не могло быть удалено.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
&lt;br /&gt;
1. Пусть нам дана грамматика: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|BS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
2. Удалим правила, содержащие непорождающие нетерминалы: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
3. Теперь удалим недостижимые нетерминалы:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\    &lt;br /&gt;
    A\rightarrow a&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Замечание ===&lt;br /&gt;
Шаги алгоритма нельзя менять местами. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|a \\&lt;br /&gt;
    A\rightarrow b&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все нетерминалы в этой грамматике достижимы. Однако, если удалить &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; как непорождающий, то нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; станет недостижимым.&lt;br /&gt;
== См. также  ==&lt;br /&gt;
* [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|Контекстно-свободные грамматики]]&lt;br /&gt;
* [[Нормальная_форма_Хомского|Нормальная форма Хомского]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [[wikipedia:Formal_grammar | Wikipedia {{---}} Formal grammar]]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Chomsky_normal_form Wikipedia {{---}} Chomsky normal form]&lt;br /&gt;
* ''Хопкрофт Д., Мотвани Р., Ульман Д.'' {{---}} Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. — Москва, Издательский дом «Вильямс», 2002. — 528 с. : ISBN 5-8459-0261-4 (рус.)&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Контекстно-свободные грамматики]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55766</id>
		<title>Удаление бесполезных символов из грамматики</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55766"/>
				<updated>2016-11-05T22:29:11Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Порождающие и непорождающие нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
[[Формальные_грамматики|Нетерминал]] &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''порождающим''' (англ. ''generating''), если из него может быть выведена конечная терминальная цепочка. Иначе он называется '''непорождающим'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Очевидно, что если и только если все нетерминалы правой части правила являются порождающими, то порождающим является и нетерминал, стоящий в его левой части. Это позволяет обнаружить непорождающие нетерминалы с помощью следующей процедуры:&lt;br /&gt;
# Найти правила, не содержащие нетерминалов в правых частях. Составить множество нетерминалов, встречающихся в левых частях таких правил.&lt;br /&gt;
# Если найдено такое правило, что все нетерминалы, стоящие в его правой части, уже входят в множество, то добавить в множество нетерминалы, стоящие в его левой части.&lt;br /&gt;
# Если на шаге 2 множество изменилось, повторить шаг 2.&lt;br /&gt;
# Получено множество всех порождающих нетерминалов грамматики, а все нетерминалы, не попавшие в него, являются непорождающими.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих непорождающие нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Непорождающие нетерминалы по определению не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\left| \Gamma \right|&amp;lt;/tex&amp;gt; {{---}} размер грамматики. Однако используя [[Очередь|очередь]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Модификация алгоритма с очередью===&lt;br /&gt;
Для реализации алгоритма поиска непорождающих нетерминалом будем использовать следующие структуры:&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{isGenerating[nonterm_i]}&amp;lt;/tex&amp;gt; {{---}} является ли нетерминал &amp;lt;tex&amp;gt;nonterm_i&amp;lt;/tex&amp;gt; порождающим или нет,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{counter[rule_i]}&amp;lt;/tex&amp;gt; {{---}} счетчик количества нетерминалов, которые ещё не помечены порождающими, для каждого из правил,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{concernedRules[nonterm_i]}&amp;lt;/tex&amp;gt; {{---}} для каждого нетерминала &amp;lt;tex&amp;gt;nonterm_i&amp;lt;/tex&amp;gt; список номеров правил, в правой части которых он встречается,&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{Q}&amp;lt;/tex&amp;gt; {{---}} очередь нетерминалов, помеченных порождающими, но ещё не обработанных.&lt;br /&gt;
&lt;br /&gt;
Вначале для всех нетерминалов в &amp;lt;tex&amp;gt;\mathrm{isGenerating}&amp;lt;/tex&amp;gt; поставим &amp;lt;tex&amp;gt;false&amp;lt;/tex&amp;gt;. В &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; поставим количество нетерминалов в правой части. Нетерминалы, у которых счётчик &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; нулевой, добавим в очередь и отметим их порождающими.&amp;lt;br&amp;gt;&lt;br /&gt;
Пока в очереди есть элементы, достаём очередной нетерминал и уменьшаем &amp;lt;tex&amp;gt;\mathrm{counter}&amp;lt;/tex&amp;gt; для всех правил из &amp;lt;tex&amp;gt;\mathrm{concernedRules}&amp;lt;/tex&amp;gt; для данного нетерминала. Если счётчик количества порождающих терминалов обнулился, то добавим нетерминал, стоящий в левой части данного правила в очередь и пометим его порождающим.&amp;lt;br&amp;gt;&lt;br /&gt;
Каждый из нетерминалов попадёт в очередь только один раз, следовательно мы пройдем по списку правил, в правой части которых он встречается, один раз. Таким образом, суммарно получаем &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
 S\rightarrow Ac\\&lt;br /&gt;
 A\rightarrow SD\\&lt;br /&gt;
 D\rightarrow aD\\&lt;br /&gt;
 A\rightarrow a    &lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Изначально множество порождающих нетерминалов состоит из одного элемента &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Добавим в множество нетерминал &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, так как существует правило &amp;lt;tex&amp;gt;S\rightarrow Ac&amp;lt;/tex&amp;gt;, в правой части которого стоят нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, который есть в множестве, и терминал &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# После следующего обхода правил из грамматики множество не изменится.&lt;br /&gt;
# Теперь удалим правила &amp;lt;tex&amp;gt;A\rightarrow SD&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D\rightarrow aD&amp;lt;/tex&amp;gt;, так как они содержит нетерминалы, которых нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Достижимые и недостижимые нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''достижимым''' (англ. ''reachable'') в [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|КС-грамматике]] &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если существует порождение &amp;lt;tex&amp;gt;S \Rightarrow^* \alpha A \beta&amp;lt;/tex&amp;gt;. Иначе он называется '''недостижимым''' (англ. ''unreachable'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Очевидно, что если нетерминал в левой части правила является достижимым, то и все нетерминалы правой части являются достижимыми. Найти недостижимые нетерминалы можно с помощью следующей процедуры.&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Если найдено правило, в левой части которого стоит нетерминал, содержащийся в множестве, добавить в множество все нетерминалы из правой части.&lt;br /&gt;
# Если на шаге 2 множество изменилось, повторить шаг 2.&lt;br /&gt;
# Получено множество всех достижимых нетерминалов, а нетерминалы, не попавшие в него, являются недостижимыми.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих недостижимые нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Недостижимые нетерминалы по определению не достижимы из стартового, следовательно они не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, однако используя [[Обход_в_глубину,_цвета_вершин|обход в глубину]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|CD\\&lt;br /&gt;
    A\rightarrow EF\\&lt;br /&gt;
    G\rightarrow AD\\&lt;br /&gt;
    C\rightarrow c&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Из &amp;lt;tex&amp;gt;S&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;C&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;. Добавим их в множество и получим  &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Множество изменилось. Переберём заново правила из грамматики. Из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; можно вывести &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt;, добавим их в множество.&lt;br /&gt;
# Снова переберём правила. Из &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; можно вывести только терминал, а &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; нету в множестве.&lt;br /&gt;
# После последнего обхода правил грамматики множество не изменилось, значит мы нашли все достижимые нетерминалы: &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D, E, F \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Теперь удалим правило &amp;lt;tex&amp;gt;G\rightarrow AD&amp;lt;/tex&amp;gt;, так как оно содержит в левой части нетерминал, которого нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Полезные и бесполезные нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''полезным''' (англ. ''useful'') в КС-грамматике &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если он может участвовать в выводе, то есть существует порождение вида &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* w&amp;lt;/tex&amp;gt;. Иначе он называется '''бесполезным''' (англ. ''useless'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит бесполезных нетерминалов тогда и только тогда, когда грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит ни недостижимых нетерминалов, ни непорождающих.&lt;br /&gt;
|proof=&lt;br /&gt;
''Необходимость.'' Очевидно, так как недостижимые и непорождающие нетерминалы являются бесполезными.&lt;br /&gt;
&lt;br /&gt;
''Достаточность.'' Рассмотрим любой нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как он достижим, существуют &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta&amp;lt;/tex&amp;gt;. Из того, что любой нетерминал является порождающим, следует, что из любой строки можно вывести строку из терминалов. Значит, существует &amp;lt;tex&amp;gt;\omega \in \Sigma ^ *&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;A&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;
Допустим, что в грамматике появился непорождающий нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как до удаления недостижимых нетерминалов существовал вывод из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; некоторой конечной цепочки терминалов &amp;lt;tex&amp;gt;\omega&amp;lt;/tex&amp;gt;, то было удалено хотя бы какое-то одно правило из этого вывода.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;B\rightarrow\alpha&amp;lt;/tex&amp;gt; {{---}} правило, первым из удалённых применяемое в выводе &amp;lt;tex&amp;gt;A \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;. Оно могло быть удалено только в том случае, если в &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; присутствуют недостижимые нетерминалы. Но так как было выбрано первое удалённое правило из вывода, то &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; — достижим, следовательно достижимы и все нетерминалы из &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;. Значит, это правило не могло быть удалено.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
&lt;br /&gt;
1. Пусть нам дана грамматика: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|BS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
2. Удалим правила, содержащие непорождающие нетерминалы: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
3. Теперь удалим недостижимые нетерминалы:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\    &lt;br /&gt;
    A\rightarrow a&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Замечание ===&lt;br /&gt;
Шаги алгоритма нельзя менять местами. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|a \\&lt;br /&gt;
    A\rightarrow b&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все нетерминалы в этой грамматике достижимы. Однако, если удалить &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; как непорождающий, то нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; станет недостижимым.&lt;br /&gt;
== См. также  ==&lt;br /&gt;
* [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|Контекстно-свободные грамматики]]&lt;br /&gt;
* [[Нормальная_форма_Хомского|Нормальная форма Хомского]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [[wikipedia:Formal_grammar | Wikipedia {{---}} Formal grammar]]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Chomsky_normal_form Wikipedia {{---}} Chomsky normal form]&lt;br /&gt;
* ''Хопкрофт Д., Мотвани Р., Ульман Д.'' {{---}} Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. — Москва, Издательский дом «Вильямс», 2002. — 528 с. : ISBN 5-8459-0261-4 (рус.)&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Контекстно-свободные грамматики]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55673</id>
		<title>Удаление бесполезных символов из грамматики</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55673"/>
				<updated>2016-10-29T18:01:36Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: /* Время работы алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Порождающие и непорождающие нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
[[Формальные_грамматики|Нетерминал]] &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''порождающим''' (англ. ''generating''), если из него может быть выведена конечная терминальная цепочка. Иначе он называется '''непорождающим'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Очевидно, что если и только если все нетерминалы правой части правила являются порождающими, то порождающим является и нетерминал, стоящий в его левой части. Это позволяет обнаружить непорождающие нетерминалы с помощью следующей процедуры:&lt;br /&gt;
# Найти правила, не содержащие нетерминалов в правых частях. Составить множество нетерминалов, встречающихся в левых частях таких правил.&lt;br /&gt;
# Если найдено такое правило, что все нетерминалы, стоящие в его правой части, уже входят в множество, то добавить в множество нетерминалы, стоящие в его левой части.&lt;br /&gt;
# Если на шаге 2 множество изменилось, повторить шаг 2.&lt;br /&gt;
# Получено множество всех порождающих нетерминалов грамматики, а все нетерминалы, не попавшие в него, являются непорождающими.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих непорождающие нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Непорождающие нетерминалы по определению не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\left| \Gamma \right|&amp;lt;/tex&amp;gt; {{---}} размер грамматики. Однако используя [[Очередь|очередь]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
 S\rightarrow Ac\\&lt;br /&gt;
 A\rightarrow SD\\&lt;br /&gt;
 D\rightarrow aD\\&lt;br /&gt;
 A\rightarrow a    &lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Изначально множество порождающих нетерминалов состоит из одного элемента &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Добавим в множество нетерминал &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, так как существует правило &amp;lt;tex&amp;gt;S\rightarrow Ac&amp;lt;/tex&amp;gt;, в правой части которого стоят нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, который есть в множестве, и терминал &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# После следующего обхода правил из грамматики множество не изменится.&lt;br /&gt;
# Теперь удалим правила &amp;lt;tex&amp;gt;A\rightarrow SD&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D\rightarrow aD&amp;lt;/tex&amp;gt;, так как они содержит нетерминалы, которых нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Достижимые и недостижимые нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''достижимым''' (англ. ''reachable'') в [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|КС-грамматике]] &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если существует порождение &amp;lt;tex&amp;gt;S \Rightarrow^* \alpha A \beta&amp;lt;/tex&amp;gt;. Иначе он называется '''недостижимым''' (англ. ''unreachable'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Очевидно, что если нетерминал в левой части правила является достижимым, то и все нетерминалы правой части являются достижимыми. Найти недостижимые нетерминалы можно с помощью следующей процедуры.&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Если найдено правило, в левой части которого стоит нетерминал, содержащийся в множестве, добавить в множество все нетерминалы из правой части.&lt;br /&gt;
# Если на шаге 2 множество изменилось, повторить шаг 2.&lt;br /&gt;
# Получено множество всех достижимых нетерминалов, а нетерминалы, не попавшие в него, являются недостижимыми.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих недостижимые нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Недостижимые нетерминалы по определению не достижимы из стартового, следовательно они не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, однако используя [[Обход_в_глубину,_цвета_вершин|обход в глубину]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|CD\\&lt;br /&gt;
    A\rightarrow EF\\&lt;br /&gt;
    G\rightarrow AD\\&lt;br /&gt;
    C\rightarrow c&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Из &amp;lt;tex&amp;gt;S&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;C&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;. Добавим их в множество и получим  &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Множество изменилось. Переберём заново правила из грамматики. Из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; можно вывести &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt;, добавим их в множество.&lt;br /&gt;
# Снова переберём правила. Из &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; можно вывести только терминал, а &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; нету в множестве.&lt;br /&gt;
# После последнего обхода правил грамматики множество не изменилось, значит мы нашли все достижимые нетерминалы: &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D, E, F \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Теперь удалим правило &amp;lt;tex&amp;gt;G\rightarrow AD&amp;lt;/tex&amp;gt;, так как оно содержит в левой части нетерминал, которого нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Полезные и бесполезные нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''полезным''' (англ. ''useful'') в КС-грамматике &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если он может участвовать в выводе, то есть существует порождение вида &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* w&amp;lt;/tex&amp;gt;. Иначе он называется '''бесполезным''' (англ. ''useless'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит бесполезных нетерминалов тогда и только тогда, когда грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит ни недостижимых нетерминалов, ни непорождающих.&lt;br /&gt;
|proof=&lt;br /&gt;
''Необходимость.'' Очевидно, так как недостижимые и непорождающие нетерминалы являются бесполезными.&lt;br /&gt;
&lt;br /&gt;
''Достаточность.'' Рассмотрим любой нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как он достижим, существуют &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta&amp;lt;/tex&amp;gt;. Из того, что любой нетерминал является порождающим, следует, что из любой строки можно вывести строку из терминалов. Значит, существует &amp;lt;tex&amp;gt;\omega \in \Sigma ^ *&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;A&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;
Допустим, что в грамматике появился непорождающий нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как до удаления недостижимых нетерминалов существовал вывод из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; некоторой конечной цепочки терминалов &amp;lt;tex&amp;gt;\omega&amp;lt;/tex&amp;gt;, то было удалено хотя бы какое-то одно правило из этого вывода.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;B\rightarrow\alpha&amp;lt;/tex&amp;gt; {{---}} правило, первым из удалённых применяемое в выводе &amp;lt;tex&amp;gt;A \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;. Оно могло быть удалено только в том случае, если в &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; присутствуют недостижимые нетерминалы. Но так как было выбрано первое удалённое правило из вывода, то &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; — достижим, следовательно достижимы и все нетерминалы из &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;. Значит, это правило не могло быть удалено.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
&lt;br /&gt;
1. Пусть нам дана грамматика: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|BS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
2. Удалим правила, содержащие непорождающие нетерминалы: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
3. Теперь удалим недостижимые нетерминалы:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\    &lt;br /&gt;
    A\rightarrow a&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Замечание ===&lt;br /&gt;
Шаги алгоритма нельзя менять местами. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|a \\&lt;br /&gt;
    A\rightarrow b&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все нетерминалы в этой грамматике достижимы. Однако, если удалить &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; как непорождающий, то нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; станет недостижимым.&lt;br /&gt;
== См. также  ==&lt;br /&gt;
* [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|Контекстно-свободные грамматики]]&lt;br /&gt;
* [[Нормальная_форма_Хомского|Нормальная форма Хомского]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [[wikipedia:Formal_grammar | Wikipedia {{---}} Formal grammar]]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Chomsky_normal_form Wikipedia {{---}} Chomsky normal form]&lt;br /&gt;
* ''Хопкрофт Д., Мотвани Р., Ульман Д.'' {{---}} Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. — Москва, Издательский дом «Вильямс», 2002. — 528 с. : ISBN 5-8459-0261-4 (рус.)&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Контекстно-свободные грамматики]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55669</id>
		<title>Удаление бесполезных символов из грамматики</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55669"/>
				<updated>2016-10-29T17:52:09Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: /* Порождающие и непорождающие нетерминалы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Порождающие и непорождающие нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
[[Формальные_грамматики|Нетерминал]] &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''порождающим''' (англ. ''generating''), если из него может быть выведена конечная терминальная цепочка. Иначе он называется '''непорождающим'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Очевидно, что если и только если все нетерминалы правой части правила являются порождающими, то порождающим является и нетерминал, стоящий в его левой части. Это позволяет обнаружить непорождающие нетерминалы с помощью следующей процедуры:&lt;br /&gt;
# Найти правила, не содержащие нетерминалов в правых частях. Составить множество нетерминалов, встречающихся в левых частях таких правил.&lt;br /&gt;
# Если найдено такое правило, что все нетерминалы, стоящие в его правой части, уже входят в множество, то добавить в множество нетерминалы, стоящие в его левой части.&lt;br /&gt;
# Если на шаге 2 множество изменилось, повторить шаг 2.&lt;br /&gt;
# Получено множество всех порождающих нетерминалов грамматики, а все нетерминалы, не попавшие в него, являются непорождающими.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих непорождающие нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Непорождающие нетерминалы по определению не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, однако используя [[Очередь|очередь]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
 S\rightarrow Ac\\&lt;br /&gt;
 A\rightarrow SD\\&lt;br /&gt;
 D\rightarrow aD\\&lt;br /&gt;
 A\rightarrow a    &lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Изначально множество порождающих нетерминалов состоит из одного элемента &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Добавим в множество нетерминал &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, так как существует правило &amp;lt;tex&amp;gt;S\rightarrow Ac&amp;lt;/tex&amp;gt;, в правой части которого стоят нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, который есть в множестве, и терминал &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# После следующего обхода правил из грамматики множество не изменится.&lt;br /&gt;
# Теперь удалим правила &amp;lt;tex&amp;gt;A\rightarrow SD&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D\rightarrow aD&amp;lt;/tex&amp;gt;, так как они содержит нетерминалы, которых нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Достижимые и недостижимые нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''достижимым''' (англ. ''reachable'') в [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|КС-грамматике]] &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если существует порождение &amp;lt;tex&amp;gt;S \Rightarrow^* \alpha A \beta&amp;lt;/tex&amp;gt;. Иначе он называется '''недостижимым''' (англ. ''unreachable'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Очевидно, что если нетерминал в левой части правила является достижимым, то и все нетерминалы правой части являются достижимыми. Найти недостижимые нетерминалы можно с помощью следующей процедуры.&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Если найдено правило, в левой части которого стоит нетерминал, содержащийся в множестве, добавить в множество все нетерминалы из правой части.&lt;br /&gt;
# Если на шаге 2 множество изменилось, повторить шаг 2.&lt;br /&gt;
# Получено множество всех достижимых нетерминалов, а нетерминалы, не попавшие в него, являются недостижимыми.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих недостижимые нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Недостижимые нетерминалы по определению не достижимы из стартового, следовательно они не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, однако используя [[Обход_в_глубину,_цвета_вершин|обход в глубину]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|CD\\&lt;br /&gt;
    A\rightarrow EF\\&lt;br /&gt;
    G\rightarrow AD\\&lt;br /&gt;
    C\rightarrow c&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Из &amp;lt;tex&amp;gt;S&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;C&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;. Добавим их в множество и получим  &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Множество изменилось. Переберём заново правила из грамматики. Из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; можно вывести &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt;, добавим их в множество.&lt;br /&gt;
# Снова переберём правила. Из &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; можно вывести только терминал, а &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; нету в множестве.&lt;br /&gt;
# После последнего обхода правил грамматики множество не изменилось, значит мы нашли все достижимые нетерминалы: &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D, E, F \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Теперь удалим правило &amp;lt;tex&amp;gt;G\rightarrow AD&amp;lt;/tex&amp;gt;, так как оно содержит в левой части нетерминал, которого нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Полезные и бесполезные нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''полезным''' (англ. ''useful'') в КС-грамматике &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если он может участвовать в выводе, то есть существует порождение вида &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* w&amp;lt;/tex&amp;gt;. Иначе он называется '''бесполезным''' (англ. ''useless'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит бесполезных нетерминалов тогда и только тогда, когда грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит ни недостижимых нетерминалов, ни непорождающих.&lt;br /&gt;
|proof=&lt;br /&gt;
''Необходимость.'' Очевидно, так как недостижимые и непорождающие нетерминалы являются бесполезными.&lt;br /&gt;
&lt;br /&gt;
''Достаточность.'' Рассмотрим любой нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как он достижим, существуют &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta&amp;lt;/tex&amp;gt;. Из того, что любой нетерминал является порождающим, следует, что из любой строки можно вывести строку из терминалов. Значит, существует &amp;lt;tex&amp;gt;\omega \in \Sigma ^ *&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;A&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;
Допустим, что в грамматике появился непорождающий нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как до удаления недостижимых нетерминалов существовал вывод из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; некоторой конечной цепочки терминалов &amp;lt;tex&amp;gt;\omega&amp;lt;/tex&amp;gt;, то было удалено хотя бы какое-то одно правило из этого вывода.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;B\rightarrow\alpha&amp;lt;/tex&amp;gt; {{---}} правило, первым из удалённых применяемое в выводе &amp;lt;tex&amp;gt;A \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;. Оно могло быть удалено только в том случае, если в &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; присутствуют недостижимые нетерминалы. Но так как было выбрано первое удалённое правило из вывода, то &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; — достижим, следовательно достижимы и все нетерминалы из &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;. Значит, это правило не могло быть удалено.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
&lt;br /&gt;
1. Пусть нам дана грамматика: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|BS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
2. Удалим правила, содержащие непорождающие нетерминалы: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
3. Теперь удалим недостижимые нетерминалы:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\    &lt;br /&gt;
    A\rightarrow a&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Замечание ===&lt;br /&gt;
Шаги алгоритма нельзя менять местами. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|a \\&lt;br /&gt;
    A\rightarrow b&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все нетерминалы в этой грамматике достижимы. Однако, если удалить &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; как непорождающий, то нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; станет недостижимым.&lt;br /&gt;
== См. также  ==&lt;br /&gt;
* [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|Контекстно-свободные грамматики]]&lt;br /&gt;
* [[Нормальная_форма_Хомского|Нормальная форма Хомского]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [[wikipedia:Formal_grammar | Wikipedia {{---}} Formal grammar]]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Chomsky_normal_form Wikipedia {{---}} Chomsky normal form]&lt;br /&gt;
* ''Хопкрофт Д., Мотвани Р., Ульман Д.'' {{---}} Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. — Москва, Издательский дом «Вильямс», 2002. — 528 с. : ISBN 5-8459-0261-4 (рус.)&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Контекстно-свободные грамматики]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55668</id>
		<title>Удаление бесполезных символов из грамматики</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55668"/>
				<updated>2016-10-29T17:43:32Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Порождающие и непорождающие нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
[[Формальные_грамматики|Нетерминал]] &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''порождающим''' (англ. ''generating''), если из него может быть выведена конечная терминальная цепочка. Иначе он называется '''непорождающим'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Очевидно, что если и только если все нетерминалы правой части правила являются порождающими, то порождающим является и нетерминал, стоящий в его левой части. Это позволяет обнаружить непорождающие нетерминалы с помощью следующей процедуры.&lt;br /&gt;
# Найти правила, не содержащие нетерминалов в правых частях. Составить множество нетерминалов, встречающихся в левых частях таких правил.&lt;br /&gt;
# Если найдено такое правило, что все нетерминалы, стоящие в его правой части, уже входят в множество, то добавить в множество нетерминалы, стоящие в его левой части.&lt;br /&gt;
# Если на шаге 2 множество изменилось, повторить шаг 2.&lt;br /&gt;
# Получено множество всех порождающих нетерминалов грамматики, а все нетерминалы, не попавшие в него, являются непорождающими.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих непорождающие нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Непорождающие нетерминалы по определению не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, однако используя [[Очередь|очередь]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
 S\rightarrow Ac\\&lt;br /&gt;
 A\rightarrow SD\\&lt;br /&gt;
 D\rightarrow aD\\&lt;br /&gt;
 A\rightarrow a    &lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Изначально множество порождающих нетерминалов состоит из одного элемента &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Добавим в множество нетерминал &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, так как существует правило &amp;lt;tex&amp;gt;S\rightarrow Ac&amp;lt;/tex&amp;gt;, в правой части которого стоят нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, который есть в множестве, и терминал &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# После следующего обхода правил из грамматики множество не изменится.&lt;br /&gt;
# Теперь удалим правила &amp;lt;tex&amp;gt;A\rightarrow SD&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D\rightarrow aD&amp;lt;/tex&amp;gt;, так как они содержит нетерминалы, которых нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Достижимые и недостижимые нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''достижимым''' (англ. ''reachable'') в [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|КС-грамматике]] &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если существует порождение &amp;lt;tex&amp;gt;S \Rightarrow^* \alpha A \beta&amp;lt;/tex&amp;gt;. Иначе он называется '''недостижимым''' (англ. ''unreachable'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Очевидно, что если нетерминал в левой части правила является достижимым, то и все нетерминалы правой части являются достижимыми. Найти недостижимые нетерминалы можно с помощью следующей процедуры.&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Если найдено правило, в левой части которого стоит нетерминал, содержащийся в множестве, добавить в множество все нетерминалы из правой части.&lt;br /&gt;
# Если на шаге 2 множество изменилось, повторить шаг 2.&lt;br /&gt;
# Получено множество всех достижимых нетерминалов, а нетерминалы, не попавшие в него, являются недостижимыми.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих недостижимые нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Недостижимые нетерминалы по определению не достижимы из стартового, следовательно они не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, однако используя [[Обход_в_глубину,_цвета_вершин|обход в глубину]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|CD\\&lt;br /&gt;
    A\rightarrow EF\\&lt;br /&gt;
    G\rightarrow AD\\&lt;br /&gt;
    C\rightarrow c&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Из &amp;lt;tex&amp;gt;S&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;C&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;. Добавим их в множество и получим  &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Множество изменилось. Переберём заново правила из грамматики. Из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; можно вывести &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt;, добавим их в множество.&lt;br /&gt;
# Снова переберём правила. Из &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; можно вывести только терминал, а &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; нету в множестве.&lt;br /&gt;
# После последнего обхода правил грамматики множество не изменилось, значит мы нашли все достижимые нетерминалы: &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D, E, F \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Теперь удалим правило &amp;lt;tex&amp;gt;G\rightarrow AD&amp;lt;/tex&amp;gt;, так как оно содержит в левой части нетерминал, которого нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Полезные и бесполезные нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''полезным''' (англ. ''useful'') в КС-грамматике &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если он может участвовать в выводе, то есть существует порождение вида &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* w&amp;lt;/tex&amp;gt;. Иначе он называется '''бесполезным''' (англ. ''useless'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит бесполезных нетерминалов тогда и только тогда, когда грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит ни недостижимых нетерминалов, ни непорождающих.&lt;br /&gt;
|proof=&lt;br /&gt;
''Необходимость.'' Очевидно, так как недостижимые и непорождающие нетерминалы являются бесполезными.&lt;br /&gt;
&lt;br /&gt;
''Достаточность.'' Рассмотрим любой нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как он достижим, существуют &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta&amp;lt;/tex&amp;gt;. Из того, что любой нетерминал является порождающим, следует, что из любой строки можно вывести строку из терминалов. Значит, существует &amp;lt;tex&amp;gt;\omega \in \Sigma ^ *&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;A&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;
Допустим, что в грамматике появился непорождающий нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как до удаления недостижимых нетерминалов существовал вывод из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; некоторой конечной цепочки терминалов &amp;lt;tex&amp;gt;\omega&amp;lt;/tex&amp;gt;, то было удалено хотя бы какое-то одно правило из этого вывода.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;B\rightarrow\alpha&amp;lt;/tex&amp;gt; {{---}} правило, первым из удалённых применяемое в выводе &amp;lt;tex&amp;gt;A \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;. Оно могло быть удалено только в том случае, если в &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; присутствуют недостижимые нетерминалы. Но так как было выбрано первое удалённое правило из вывода, то &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; — достижим, следовательно достижимы и все нетерминалы из &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;. Значит, это правило не могло быть удалено.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
&lt;br /&gt;
1. Пусть нам дана грамматика: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|BS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
2. Удалим правила, содержащие непорождающие нетерминалы: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
3. Теперь удалим недостижимые нетерминалы:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\    &lt;br /&gt;
    A\rightarrow a&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Замечание ===&lt;br /&gt;
Шаги алгоритма нельзя менять местами. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|a \\&lt;br /&gt;
    A\rightarrow b&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все нетерминалы в этой грамматике достижимы. Однако, если удалить &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; как непорождающий, то нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; станет недостижимым.&lt;br /&gt;
== См. также  ==&lt;br /&gt;
* [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|Контекстно-свободные грамматики]]&lt;br /&gt;
* [[Нормальная_форма_Хомского|Нормальная форма Хомского]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [[wikipedia:Formal_grammar | Wikipedia {{---}} Formal grammar]]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Chomsky_normal_form Wikipedia {{---}} Chomsky normal form]&lt;br /&gt;
* ''Хопкрофт Д., Мотвани Р., Ульман Д.'' {{---}} Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. — Москва, Издательский дом «Вильямс», 2002. — 528 с. : ISBN 5-8459-0261-4 (рус.)&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Контекстно-свободные грамматики]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55667</id>
		<title>Удаление бесполезных символов из грамматики</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55667"/>
				<updated>2016-10-29T17:30:00Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: /* Достижимые и недостижимые нетерминалы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Порождающие и непорождающие нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
[[Формальные_грамматики|Нетерминал]] &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''порождающим''' (англ. ''generating''), если из него может быть выведена конечная терминальная цепочка. Иначе он называется '''непорождающим'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Очевидно, что если и только если все нетерминалы правой части правила являются порождающими, то порождающим является и нетерминал, стоящий в его левой части. Это позволяет обнаружить непорождающие нетерминалы с помощью следующей процедуры.&lt;br /&gt;
# Найти правила, не содержащие нетерминалов в правых частях. Составить множество нетерминалов, встречающихся в левых частях таких правил.&lt;br /&gt;
# Если найдено такое правило, что все нетерминалы, стоящие в его правой части, уже входят в множество, то добавить в множество нетерминалы, стоящие в его левой части.&lt;br /&gt;
# Если на шаге 2 множество изменилось, повторить шаг 2.&lt;br /&gt;
# Получено множество всех порождающих нетерминалов грамматики, а все нетерминалы, не попавшие в него, являются непорождающими.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих непорождающие нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Непорождающие нетерминалы по определению не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, однако используя [[Очередь|очередь]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
 S\rightarrow Ac\\&lt;br /&gt;
 A\rightarrow SD\\&lt;br /&gt;
 D\rightarrow aD\\&lt;br /&gt;
 A\rightarrow a    &lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Изначально множество порождающих нетерминалов состоит из одного элемента &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Добавим в множество нетерминал &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, так как существует правило &amp;lt;tex&amp;gt;S\rightarrow Ac&amp;lt;/tex&amp;gt;, в правой части которого стоят нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, который есть в множестве, и терминал &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# После следующего обхода правил из грамматики множество не изменится.&lt;br /&gt;
# Теперь удалим правила &amp;lt;tex&amp;gt;A\rightarrow SD&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D\rightarrow aD&amp;lt;/tex&amp;gt;, так как они содержит нетерминалы, которых нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Достижимые и недостижимые нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''достижимым''' (англ. ''reachable'') в [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|КС-грамматике]] &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если существует порождение &amp;lt;tex&amp;gt;S \Rightarrow^* \alpha A \beta&amp;lt;/tex&amp;gt;. Иначе он называется '''недостижимым''' (англ. ''unreachable'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Очевидно, что если нетерминал в левой части правила является достижимым, то и все нетерминалы правой части являются достижимыми. Найти недостижимые нетерминалы можно с помощью следующей процедуры.&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Если найдено правило, в левой части которого стоит нетерминал, содержащийся в множестве, добавить в множество все нетерминалы из правой части.&lt;br /&gt;
# Если на шаге 2 множество изменилось, повторить шаг 2.&lt;br /&gt;
# Получено множество всех достижимых нетерминалов, а нетерминалы, не попавшие в него, являются недостижимыми.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих недостижимые нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Недостижимые нетерминалы по определению не достижимы из стартового, следовательно они не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, однако используя [[Обход_в_глубину,_цвета_вершин|обход в глубину]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|CD\\&lt;br /&gt;
    A\rightarrow EF\\&lt;br /&gt;
    G\rightarrow AD\\&lt;br /&gt;
    C\rightarrow c&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Из &amp;lt;tex&amp;gt;S&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;C&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;. Добавим их в множество и получим  &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Множество изменилось. Переберём заново правила из грамматики. Из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; можно вывести &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt;, добавим их в множество.&lt;br /&gt;
# Снова переберём правила. Из &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; можно вывести только терминал, а &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; нету в множестве.&lt;br /&gt;
# После последнего обхода правил грамматики множество не изменилось, значит мы нашли все достижимые нетерминалы: &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D, E, F \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Теперь удалим правило &amp;lt;tex&amp;gt;G\rightarrow AD&amp;lt;/tex&amp;gt;, так как оно содержит в левой части нетерминал, которого нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Полезные и бесполезные нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''полезным''' (англ. ''useful'') в КС-грамматике &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если он может участвовать в выводе, то есть существует порождение вида &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* w&amp;lt;/tex&amp;gt;. Иначе он называется '''бесполезным''' (англ. ''useless'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит бесполезных нетерминалов тогда и только тогда, когда грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит ни недостижимых нетерминалов, ни непорождающих.&lt;br /&gt;
|proof=&lt;br /&gt;
''Необходимость.'' Очевидно, так как недостижимые и непорождающие нетерминалы являются бесполезными.&lt;br /&gt;
&lt;br /&gt;
''Достаточность.'' Рассмотрим любой нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как он достижим, существуют &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta&amp;lt;/tex&amp;gt;. Из того, что любой нетерминал является порождающим, следует, что из любой строки можно вывести строку из терминалов. Значит, существует &amp;lt;tex&amp;gt;\omega \in \Sigma ^ *&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;A&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;
Допустим, что в грамматике появился непорождающий нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как до удаления недостижимых нетерминалов существовал вывод из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; некоторой конечной цепочки терминалов &amp;lt;tex&amp;gt;\omega&amp;lt;/tex&amp;gt;, то было удалено хотя бы какое-то одно правило из этого вывода.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;B\rightarrow\alpha&amp;lt;/tex&amp;gt; {{---}} правило, первым из удалённых применяемое в выводе &amp;lt;tex&amp;gt;A \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;. Оно могло быть удалено только в том случае, если в &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; присутствуют недостижимые нетерминалы. Но так как было выбрано первое удалённое правило из вывода, то &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; — достижим, следовательно достижимы и все нетерминалы из &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;. Значит, это правило не могло быть удалено.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
&lt;br /&gt;
Пусть нам дана грамматика: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|BS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Удалим правила, содержащие непорождающие нетерминалы: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь удалим недостижимые нетерминалы:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\    &lt;br /&gt;
    A\rightarrow a&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Замечание ===&lt;br /&gt;
Шаги алгоритма нельзя менять местами. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|a \\&lt;br /&gt;
    A\rightarrow b&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все нетерминалы в этой грамматике достижимы. Однако, если удалить &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; как непорождающий, то нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; станет недостижимым.&lt;br /&gt;
== См. также  ==&lt;br /&gt;
* [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|Контекстно-свободные грамматики]]&lt;br /&gt;
* [[Нормальная_форма_Хомского|Нормальная форма Хомского]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [[wikipedia:Formal_grammar | Wikipedia {{---}} Formal grammar]]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Chomsky_normal_form Wikipedia {{---}} Chomsky normal form]&lt;br /&gt;
* ''Хопкрофт Д., Мотвани Р., Ульман Д.'' {{---}} Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. — Москва, Издательский дом «Вильямс», 2002. — 528 с. : ISBN 5-8459-0261-4 (рус.)&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Контекстно-свободные грамматики]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55666</id>
		<title>Удаление бесполезных символов из грамматики</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55666"/>
				<updated>2016-10-29T17:27:40Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: /* Порождающие и непорождающие нетерминалы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Порождающие и непорождающие нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
[[Формальные_грамматики|Нетерминал]] &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''порождающим''' (англ. ''generating''), если из него может быть выведена конечная терминальная цепочка. Иначе он называется '''непорождающим'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Очевидно, что если и только если все нетерминалы правой части правила являются порождающими, то порождающим является и нетерминал, стоящий в его левой части. Это позволяет обнаружить непорождающие нетерминалы с помощью следующей процедуры.&lt;br /&gt;
# Найти правила, не содержащие нетерминалов в правых частях. Составить множество нетерминалов, встречающихся в левых частях таких правил.&lt;br /&gt;
# Если найдено такое правило, что все нетерминалы, стоящие в его правой части, уже входят в множество, то добавить в множество нетерминалы, стоящие в его левой части.&lt;br /&gt;
# Если на шаге 2 множество изменилось, повторить шаг 2.&lt;br /&gt;
# Получено множество всех порождающих нетерминалов грамматики, а все нетерминалы, не попавшие в него, являются непорождающими.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих непорождающие нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Непорождающие нетерминалы по определению не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, однако используя [[Очередь|очередь]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
 S\rightarrow Ac\\&lt;br /&gt;
 A\rightarrow SD\\&lt;br /&gt;
 D\rightarrow aD\\&lt;br /&gt;
 A\rightarrow a    &lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Изначально множество порождающих нетерминалов состоит из одного элемента &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Добавим в множество нетерминал &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, так как существует правило &amp;lt;tex&amp;gt;S\rightarrow Ac&amp;lt;/tex&amp;gt;, в правой части которого стоят нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, который есть в множестве, и терминал &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# После следующего обхода правил из грамматики множество не изменится.&lt;br /&gt;
# Теперь удалим правила &amp;lt;tex&amp;gt;A\rightarrow SD&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D\rightarrow aD&amp;lt;/tex&amp;gt;, так как они содержит нетерминалы, которых нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Достижимые и недостижимые нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''достижимым''' (англ. ''reachable'') в КС-грамматике &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если существует порождение &amp;lt;tex&amp;gt;S \Rightarrow^* \alpha A \beta&amp;lt;/tex&amp;gt;. Иначе он называется '''недостижимым''' (англ. ''unreachable'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Очевидно, что если нетерминал в левой части правила является достижимым, то и все нетерминалы правой части являются достижимыми. Найти недостижимые нетерминалы можно с помощью следующей процедуры.&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Если найдено правило, в левой части которого стоит нетерминал, содержащийся в множестве, добавить в множество все нетерминалы из правой части.&lt;br /&gt;
# Если на шаге 2 множество изменилось, повторить шаг 2.&lt;br /&gt;
# Получено множество всех достижимых нетерминалов, а нетерминалы, не попавшие в него, являются недостижимыми.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих недостижимые нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Недостижимые нетерминалы по определению не достижимы из стартового, следовательно они не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, однако используя [[Обход_в_глубину,_цвета_вершин|обход в глубину]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|CD\\&lt;br /&gt;
    A\rightarrow EF\\&lt;br /&gt;
    G\rightarrow AD\\&lt;br /&gt;
    C\rightarrow c&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Из &amp;lt;tex&amp;gt;S&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;C&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;. Добавим их в множество и получим  &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Множество изменилось. Переберём заново правила из грамматики. Из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; можно вывести &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt;, добавим их в множество.&lt;br /&gt;
# Снова переберём правила. Из &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; можно вывести только терминал, а &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; нету в множестве.&lt;br /&gt;
# После последнего обхода правил грамматики множество не изменилось, значит мы нашли все достижимые нетерминалы: &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D, E, F \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Теперь удалим правило &amp;lt;tex&amp;gt;G\rightarrow AD&amp;lt;/tex&amp;gt;, так как оно содержит в левой части нетерминал, которого нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Полезные и бесполезные нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''полезным''' (англ. ''useful'') в КС-грамматике &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если он может участвовать в выводе, то есть существует порождение вида &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* w&amp;lt;/tex&amp;gt;. Иначе он называется '''бесполезным''' (англ. ''useless'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит бесполезных нетерминалов тогда и только тогда, когда грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит ни недостижимых нетерминалов, ни непорождающих.&lt;br /&gt;
|proof=&lt;br /&gt;
''Необходимость.'' Очевидно, так как недостижимые и непорождающие нетерминалы являются бесполезными.&lt;br /&gt;
&lt;br /&gt;
''Достаточность.'' Рассмотрим любой нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как он достижим, существуют &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta&amp;lt;/tex&amp;gt;. Из того, что любой нетерминал является порождающим, следует, что из любой строки можно вывести строку из терминалов. Значит, существует &amp;lt;tex&amp;gt;\omega \in \Sigma ^ *&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;A&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;
Допустим, что в грамматике появился непорождающий нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как до удаления недостижимых нетерминалов существовал вывод из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; некоторой конечной цепочки терминалов &amp;lt;tex&amp;gt;\omega&amp;lt;/tex&amp;gt;, то было удалено хотя бы какое-то одно правило из этого вывода.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;B\rightarrow\alpha&amp;lt;/tex&amp;gt; {{---}} правило, первым из удалённых применяемое в выводе &amp;lt;tex&amp;gt;A \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;. Оно могло быть удалено только в том случае, если в &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; присутствуют недостижимые нетерминалы. Но так как было выбрано первое удалённое правило из вывода, то &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; — достижим, следовательно достижимы и все нетерминалы из &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;. Значит, это правило не могло быть удалено.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
&lt;br /&gt;
Пусть нам дана грамматика: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|BS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Удалим правила, содержащие непорождающие нетерминалы: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь удалим недостижимые нетерминалы:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\    &lt;br /&gt;
    A\rightarrow a&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Замечание ===&lt;br /&gt;
Шаги алгоритма нельзя менять местами. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|a \\&lt;br /&gt;
    A\rightarrow b&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все нетерминалы в этой грамматике достижимы. Однако, если удалить &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; как непорождающий, то нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; станет недостижимым.&lt;br /&gt;
== См. также  ==&lt;br /&gt;
* [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|Контекстно-свободные грамматики]]&lt;br /&gt;
* [[Нормальная_форма_Хомского|Нормальная форма Хомского]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [[wikipedia:Formal_grammar | Wikipedia {{---}} Formal grammar]]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Chomsky_normal_form Wikipedia {{---}} Chomsky normal form]&lt;br /&gt;
* ''Хопкрофт Д., Мотвани Р., Ульман Д.'' {{---}} Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. — Москва, Издательский дом «Вильямс», 2002. — 528 с. : ISBN 5-8459-0261-4 (рус.)&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Контекстно-свободные грамматики]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55665</id>
		<title>Удаление бесполезных символов из грамматики</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55665"/>
				<updated>2016-10-29T17:21:50Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: /* Литература */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Порождающие и непорождающие нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''порождающим''' (англ. ''generating''), если из него может быть выведена конечная терминальная цепочка. Иначе он называется '''непорождающим'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Очевидно, что если и только если все нетерминалы правой части правила являются порождающими, то порождающим является и нетерминал, стоящий в его левой части. Это позволяет обнаружить непорождающие нетерминалы с помощью следующей процедуры.&lt;br /&gt;
# Найти правила, не содержащие нетерминалов в правых частях. Составить множество нетерминалов, встречающихся в левых частях таких правил.&lt;br /&gt;
# Если найдено такое правило, что все нетерминалы, стоящие в его правой части, уже входят в множество, то добавить в множество нетерминалы, стоящие в его левой части.&lt;br /&gt;
# Если на шаге 2 множество изменилось, повторить шаг 2.&lt;br /&gt;
# Получено множество всех порождающих нетерминалов грамматики, а все нетерминалы, не попавшие в него, являются непорождающими.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих непорождающие нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Непорождающие нетерминалы по определению не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, однако используя [[Очередь|очередь]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
 S\rightarrow Ac\\&lt;br /&gt;
 A\rightarrow SD\\&lt;br /&gt;
 D\rightarrow aD\\&lt;br /&gt;
 A\rightarrow a    &lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Изначально множество порождающих нетерминалов состоит из одного элемента &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Добавим в множество нетерминал &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, так как существует правило &amp;lt;tex&amp;gt;S\rightarrow Ac&amp;lt;/tex&amp;gt;, в правой части которого стоят нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, который есть в множестве, и терминал &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# После следующего обхода правил из грамматики множество не изменится.&lt;br /&gt;
# Теперь удалим правила &amp;lt;tex&amp;gt;A\rightarrow SD&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D\rightarrow aD&amp;lt;/tex&amp;gt;, так как они содержит нетерминалы, которых нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Достижимые и недостижимые нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''достижимым''' (англ. ''reachable'') в КС-грамматике &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если существует порождение &amp;lt;tex&amp;gt;S \Rightarrow^* \alpha A \beta&amp;lt;/tex&amp;gt;. Иначе он называется '''недостижимым''' (англ. ''unreachable'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Очевидно, что если нетерминал в левой части правила является достижимым, то и все нетерминалы правой части являются достижимыми. Найти недостижимые нетерминалы можно с помощью следующей процедуры.&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Если найдено правило, в левой части которого стоит нетерминал, содержащийся в множестве, добавить в множество все нетерминалы из правой части.&lt;br /&gt;
# Если на шаге 2 множество изменилось, повторить шаг 2.&lt;br /&gt;
# Получено множество всех достижимых нетерминалов, а нетерминалы, не попавшие в него, являются недостижимыми.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих недостижимые нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Недостижимые нетерминалы по определению не достижимы из стартового, следовательно они не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, однако используя [[Обход_в_глубину,_цвета_вершин|обход в глубину]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|CD\\&lt;br /&gt;
    A\rightarrow EF\\&lt;br /&gt;
    G\rightarrow AD\\&lt;br /&gt;
    C\rightarrow c&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Из &amp;lt;tex&amp;gt;S&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;C&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;. Добавим их в множество и получим  &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Множество изменилось. Переберём заново правила из грамматики. Из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; можно вывести &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt;, добавим их в множество.&lt;br /&gt;
# Снова переберём правила. Из &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; можно вывести только терминал, а &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; нету в множестве.&lt;br /&gt;
# После последнего обхода правил грамматики множество не изменилось, значит мы нашли все достижимые нетерминалы: &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D, E, F \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Теперь удалим правило &amp;lt;tex&amp;gt;G\rightarrow AD&amp;lt;/tex&amp;gt;, так как оно содержит в левой части нетерминал, которого нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Полезные и бесполезные нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''полезным''' (англ. ''useful'') в КС-грамматике &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если он может участвовать в выводе, то есть существует порождение вида &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* w&amp;lt;/tex&amp;gt;. Иначе он называется '''бесполезным''' (англ. ''useless'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит бесполезных нетерминалов тогда и только тогда, когда грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит ни недостижимых нетерминалов, ни непорождающих.&lt;br /&gt;
|proof=&lt;br /&gt;
''Необходимость.'' Очевидно, так как недостижимые и непорождающие нетерминалы являются бесполезными.&lt;br /&gt;
&lt;br /&gt;
''Достаточность.'' Рассмотрим любой нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как он достижим, существуют &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta&amp;lt;/tex&amp;gt;. Из того, что любой нетерминал является порождающим, следует, что из любой строки можно вывести строку из терминалов. Значит, существует &amp;lt;tex&amp;gt;\omega \in \Sigma ^ *&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;A&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;
Допустим, что в грамматике появился непорождающий нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как до удаления недостижимых нетерминалов существовал вывод из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; некоторой конечной цепочки терминалов &amp;lt;tex&amp;gt;\omega&amp;lt;/tex&amp;gt;, то было удалено хотя бы какое-то одно правило из этого вывода.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;B\rightarrow\alpha&amp;lt;/tex&amp;gt; {{---}} правило, первым из удалённых применяемое в выводе &amp;lt;tex&amp;gt;A \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;. Оно могло быть удалено только в том случае, если в &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; присутствуют недостижимые нетерминалы. Но так как было выбрано первое удалённое правило из вывода, то &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; — достижим, следовательно достижимы и все нетерминалы из &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;. Значит, это правило не могло быть удалено.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
&lt;br /&gt;
Пусть нам дана грамматика: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|BS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Удалим правила, содержащие непорождающие нетерминалы: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь удалим недостижимые нетерминалы:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\    &lt;br /&gt;
    A\rightarrow a&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Замечание ===&lt;br /&gt;
Шаги алгоритма нельзя менять местами. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|a \\&lt;br /&gt;
    A\rightarrow b&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все нетерминалы в этой грамматике достижимы. Однако, если удалить &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; как непорождающий, то нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; станет недостижимым.&lt;br /&gt;
== См. также  ==&lt;br /&gt;
* [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|Контекстно-свободные грамматики]]&lt;br /&gt;
* [[Нормальная_форма_Хомского|Нормальная форма Хомского]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [[wikipedia:Formal_grammar | Wikipedia {{---}} Formal grammar]]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Chomsky_normal_form Wikipedia {{---}} Chomsky normal form]&lt;br /&gt;
* ''Хопкрофт Д., Мотвани Р., Ульман Д.'' {{---}} Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. — Москва, Издательский дом «Вильямс», 2002. — 528 с. : ISBN 5-8459-0261-4 (рус.)&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Контекстно-свободные грамматики]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55664</id>
		<title>Удаление бесполезных символов из грамматики</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55664"/>
				<updated>2016-10-29T17:18:27Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Порождающие и непорождающие нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''порождающим''' (англ. ''generating''), если из него может быть выведена конечная терминальная цепочка. Иначе он называется '''непорождающим'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Очевидно, что если и только если все нетерминалы правой части правила являются порождающими, то порождающим является и нетерминал, стоящий в его левой части. Это позволяет обнаружить непорождающие нетерминалы с помощью следующей процедуры.&lt;br /&gt;
# Найти правила, не содержащие нетерминалов в правых частях. Составить множество нетерминалов, встречающихся в левых частях таких правил.&lt;br /&gt;
# Если найдено такое правило, что все нетерминалы, стоящие в его правой части, уже входят в множество, то добавить в множество нетерминалы, стоящие в его левой части.&lt;br /&gt;
# Если на шаге 2 множество изменилось, повторить шаг 2.&lt;br /&gt;
# Получено множество всех порождающих нетерминалов грамматики, а все нетерминалы, не попавшие в него, являются непорождающими.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих непорождающие нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Непорождающие нетерминалы по определению не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, однако используя [[Очередь|очередь]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
 S\rightarrow Ac\\&lt;br /&gt;
 A\rightarrow SD\\&lt;br /&gt;
 D\rightarrow aD\\&lt;br /&gt;
 A\rightarrow a    &lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Изначально множество порождающих нетерминалов состоит из одного элемента &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Добавим в множество нетерминал &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, так как существует правило &amp;lt;tex&amp;gt;S\rightarrow Ac&amp;lt;/tex&amp;gt;, в правой части которого стоят нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, который есть в множестве, и терминал &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# После следующего обхода правил из грамматики множество не изменится.&lt;br /&gt;
# Теперь удалим правила &amp;lt;tex&amp;gt;A\rightarrow SD&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D\rightarrow aD&amp;lt;/tex&amp;gt;, так как они содержит нетерминалы, которых нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Достижимые и недостижимые нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''достижимым''' (англ. ''reachable'') в КС-грамматике &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если существует порождение &amp;lt;tex&amp;gt;S \Rightarrow^* \alpha A \beta&amp;lt;/tex&amp;gt;. Иначе он называется '''недостижимым''' (англ. ''unreachable'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Очевидно, что если нетерминал в левой части правила является достижимым, то и все нетерминалы правой части являются достижимыми. Найти недостижимые нетерминалы можно с помощью следующей процедуры.&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Если найдено правило, в левой части которого стоит нетерминал, содержащийся в множестве, добавить в множество все нетерминалы из правой части.&lt;br /&gt;
# Если на шаге 2 множество изменилось, повторить шаг 2.&lt;br /&gt;
# Получено множество всех достижимых нетерминалов, а нетерминалы, не попавшие в него, являются недостижимыми.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих недостижимые нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Недостижимые нетерминалы по определению не достижимы из стартового, следовательно они не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, однако используя [[Обход_в_глубину,_цвета_вершин|обход в глубину]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим следующую грамматику:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|CD\\&lt;br /&gt;
    A\rightarrow EF\\&lt;br /&gt;
    G\rightarrow AD\\&lt;br /&gt;
    C\rightarrow c&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Из &amp;lt;tex&amp;gt;S&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;C&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;. Добавим их в множество и получим  &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Множество изменилось. Переберём заново правила из грамматики. Из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; можно вывести &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt;, добавим их в множество.&lt;br /&gt;
# Снова переберём правила. Из &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; можно вывести только терминал, а &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; нету в множестве.&lt;br /&gt;
# После последнего обхода правил грамматики множество не изменилось, значит мы нашли все достижимые нетерминалы: &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D, E, F \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Теперь удалим правило &amp;lt;tex&amp;gt;G\rightarrow AD&amp;lt;/tex&amp;gt;, так как оно содержит в левой части нетерминал, которого нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Полезные и бесполезные нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''полезным''' (англ. ''useful'') в КС-грамматике &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если он может участвовать в выводе, то есть существует порождение вида &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* w&amp;lt;/tex&amp;gt;. Иначе он называется '''бесполезным''' (англ. ''useless'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит бесполезных нетерминалов тогда и только тогда, когда грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит ни недостижимых нетерминалов, ни непорождающих.&lt;br /&gt;
|proof=&lt;br /&gt;
''Необходимость.'' Очевидно, так как недостижимые и непорождающие нетерминалы являются бесполезными.&lt;br /&gt;
&lt;br /&gt;
''Достаточность.'' Рассмотрим любой нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как он достижим, существуют &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta&amp;lt;/tex&amp;gt;. Из того, что любой нетерминал является порождающим, следует, что из любой строки можно вывести строку из терминалов. Значит, существует &amp;lt;tex&amp;gt;\omega \in \Sigma ^ *&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;A&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;
Допустим, что в грамматике появился непорождающий нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как до удаления недостижимых нетерминалов существовал вывод из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; некоторой конечной цепочки терминалов &amp;lt;tex&amp;gt;\omega&amp;lt;/tex&amp;gt;, то было удалено хотя бы какое-то одно правило из этого вывода.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;B\rightarrow\alpha&amp;lt;/tex&amp;gt; {{---}} правило, первым из удалённых применяемое в выводе &amp;lt;tex&amp;gt;A \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;. Оно могло быть удалено только в том случае, если в &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; присутствуют недостижимые нетерминалы. Но так как было выбрано первое удалённое правило из вывода, то &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; — достижим, следовательно достижимы и все нетерминалы из &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;. Значит, это правило не могло быть удалено.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
&lt;br /&gt;
Пусть нам дана грамматика: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|BS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Удалим правила, содержащие непорождающие нетерминалы: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь удалим недостижимые нетерминалы:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AS|s \\    &lt;br /&gt;
    A\rightarrow a&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Замечание ===&lt;br /&gt;
Шаги алгоритма нельзя менять местами. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим следующую грамматику: &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
    S\rightarrow AB|a \\&lt;br /&gt;
    A\rightarrow b&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все нетерминалы в этой грамматике достижимы. Однако, если удалить &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; как непорождающий, то нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; станет недостижимым.&lt;br /&gt;
== См. также  ==&lt;br /&gt;
* [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|Контекстно-свободные грамматики]]&lt;br /&gt;
* [[Нормальная_форма_Хомского|Нормальная форма Хомского]]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Chomsky_normal_form Wikipedia {{---}} Chomsky normal form]&lt;br /&gt;
* ''Хопкрофт Д., Мотвани Р., Ульман Д.'' {{---}} Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. — Москва, Издательский дом «Вильямс», 2002. — 528 с. : ISBN 5-8459-0261-4 (рус.)&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Контекстно-свободные грамматики]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55663</id>
		<title>Удаление бесполезных символов из грамматики</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B5%D1%81%D0%BF%D0%BE%D0%BB%D0%B5%D0%B7%D0%BD%D1%8B%D1%85_%D1%81%D0%B8%D0%BC%D0%B2%D0%BE%D0%BB%D0%BE%D0%B2_%D0%B8%D0%B7_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B8&amp;diff=55663"/>
				<updated>2016-10-29T16:55:51Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Порождающие и непорождающие нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''порождающим''' (англ. ''generating''), если из него может быть выведена конечная терминальная цепочка. Иначе он называется '''непорождающим'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Очевидно, что если и только если все нетерминалы правой части правила являются порождающими, то порождающим является и нетерминал, стоящий в его левой части. Это позволяет обнаружить непорождающие нетерминалы с помощью следующей процедуры.&lt;br /&gt;
# Найти правила, не содержащие нетерминалов в правых частях. Составить множество нетерминалов, встречающихся в левых частях таких правил.&lt;br /&gt;
# Если найдено такое правило, что все нетерминалы, стоящие в его правой части, уже входят в множество, то добавить в множество нетерминалы, стоящие в его левой части.&lt;br /&gt;
# Если на шаге 2 множество изменилось, повторить шаг 2.&lt;br /&gt;
# Получено множество всех порождающих нетерминалов грамматики, а все нетерминалы, не попавшие в него, являются непорождающими.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих непорождающие нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Непорождающие нетерминалы по определению не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, однако используя [[Очередь|очередь]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим грамматику:&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
\begin{array}{l l}   &lt;br /&gt;
    S\rightarrow Ac\\&lt;br /&gt;
    A\rightarrow SD\\&lt;br /&gt;
    D\rightarrow aD\\&lt;br /&gt;
    A\rightarrow a    &lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Изначально множество порождающих нетерминалов состоит из одного элемента &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Добавим в множество нетерминал &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, так как существует правило &amp;lt;tex&amp;gt;S\rightarrow Ac&amp;lt;/tex&amp;gt;, в правой части которого стоят нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, который есть в множестве, и терминал &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# После следующего обхода правил из грамматики множество не изменится.&lt;br /&gt;
# Теперь удалим правила &amp;lt;tex&amp;gt;A\rightarrow SD&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D\rightarrow aD&amp;lt;/tex&amp;gt;, так как они содержит нетерминалы, которых нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Достижимые и недостижимые нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''достижимым''' (англ. ''reachable'') в КС-грамматике &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если существует порождение &amp;lt;tex&amp;gt;S \Rightarrow^* \alpha A \beta&amp;lt;/tex&amp;gt;. Иначе он называется '''недостижимым''' (англ. ''unreachable'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Очевидно, что если нетерминал в левой части правила является достижимым, то и все нетерминалы правой части являются достижимыми. Найти недостижимые нетерминалы можно с помощью следующей процедуры.&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Если найдено правило, в левой части которого стоит нетерминал, содержащийся в множестве, добавить в множество все нетерминалы из правой части.&lt;br /&gt;
# Если на шаге 2 множество изменилось, повторить шаг 2.&lt;br /&gt;
# Получено множество всех достижимых нетерминалов, а нетерминалы, не попавшие в него, являются недостижимыми.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
После удаления из грамматики правил, содержащих недостижимые нетерминалы, язык не изменится.&lt;br /&gt;
|proof=&lt;br /&gt;
Недостижимые нетерминалы по определению не достижимы из стартового, следовательно они не могли участвовать в выводе какого-либо слова.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Время работы алгоритма ===&lt;br /&gt;
Данный алгоритм работает за &amp;lt;tex&amp;gt;O(\left| \Gamma \right| ^ 2)&amp;lt;/tex&amp;gt;, однако используя [[Обход_в_глубину,_цвета_вершин|обход в глубину]] можно ускорить его до &amp;lt;tex&amp;gt;O(\left| \Gamma \right|)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим грамматику:&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
\begin{array}{l l}   &lt;br /&gt;
    S\rightarrow AB|CD\\&lt;br /&gt;
    A\rightarrow EF\\&lt;br /&gt;
    G\rightarrow AD\\&lt;br /&gt;
    C\rightarrow c&lt;br /&gt;
&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
# Возьмём множество, состоящее из единственного элемента: &amp;lt;tex&amp;gt;\lbrace S \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Из &amp;lt;tex&amp;gt;S&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;C&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;. Добавим их в множество и получим  &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Множество изменилось. Переберём заново правила из грамматики. Из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; можно вывести &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;F&amp;lt;/tex&amp;gt;, добавим их в множество.&lt;br /&gt;
# Снова переберём правила. Из &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; можно вывести только терминал, а &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; нету в множестве.&lt;br /&gt;
# После последнего обхода правил грамматики множество не изменилось, значит мы нашли все достижимые нетерминалы: &amp;lt;tex&amp;gt;\lbrace S, A, B, C, D, E, F \rbrace&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Теперь удалим правило &amp;lt;tex&amp;gt;G\rightarrow AD&amp;lt;/tex&amp;gt;, так как оно содержит в левой части нетерминал, которого нет в полученном множестве.&lt;br /&gt;
&lt;br /&gt;
== Полезные и бесполезные нетерминалы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; называется '''полезным''' (англ. ''useful'') в КС-грамматике &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt;, если он может участвовать в выводе, то есть существует порождение вида &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* w&amp;lt;/tex&amp;gt;. Иначе он называется '''бесполезным''' (англ. ''useless'').&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит бесполезных нетерминалов тогда и только тогда, когда грамматика &amp;lt;tex&amp;gt;\Gamma&amp;lt;/tex&amp;gt; не содержит ни недостижимых нетерминалов, ни непорождающих.&lt;br /&gt;
|proof=&lt;br /&gt;
''Необходимость.'' Очевидно, так как недостижимые и непорождающие нетерминалы являются бесполезными.&lt;br /&gt;
&lt;br /&gt;
''Достаточность.'' Рассмотрим любой нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как он достижим, существуют &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\beta&amp;lt;/tex&amp;gt; такие, что &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta&amp;lt;/tex&amp;gt;. Из того, что любой нетерминал является порождающим, следует, что из любой строки можно вывести строку из терминалов. Значит, существует &amp;lt;tex&amp;gt;\omega \in \Sigma ^ *&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;S \Rightarrow ^* \alpha A \beta \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;A&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;
Допустим, что в грамматике появился непорождающий нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Так как до удаления недостижимых нетерминалов существовал вывод из &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; некоторой конечной цепочки терминалов &amp;lt;tex&amp;gt;\omega&amp;lt;/tex&amp;gt;, то было удалено хотя бы какое-то одно правило из этого вывода.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;B\rightarrow\alpha&amp;lt;/tex&amp;gt; {{---}} правило, первым из удалённых применяемое в выводе &amp;lt;tex&amp;gt;A \Rightarrow ^* \omega&amp;lt;/tex&amp;gt;. Оно могло быть удалено только в том случае, если в &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt; присутствуют недостижимые нетерминалы. Но так как было выбрано первое удалённое правило из вывода, то &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; — достижим, следовательно достижимы и все нетерминалы из &amp;lt;tex&amp;gt;\alpha&amp;lt;/tex&amp;gt;. Значит, это правило не могло быть удалено.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
&lt;br /&gt;
Пусть нам дана грамматика:&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
\begin{array}{l l}   &lt;br /&gt;
    S\rightarrow AS|BS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Удалим правила, содержащие непорождающие нетерминалы и получим грамматику&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
\begin{array}{l l}   &lt;br /&gt;
    S\rightarrow AS|s \\&lt;br /&gt;
    E\rightarrow EF|FF \\&lt;br /&gt;
    A\rightarrow a \\&lt;br /&gt;
    F\rightarrow f&lt;br /&gt;
&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Теперь удалим недостижимые нетерминалы и получим грамматику&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
\begin{array}{l l}   &lt;br /&gt;
    S\rightarrow AS|s \\    &lt;br /&gt;
    A\rightarrow a&lt;br /&gt;
\end{array}&lt;br /&gt;
&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;&lt;br /&gt;
\begin{array}{l l}   &lt;br /&gt;
    S\rightarrow AB|a \\&lt;br /&gt;
    A\rightarrow b&lt;br /&gt;
\end{array}.&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
Все нетерминалы в этой грамматике достижимы. Однако, если удалить &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; как непорождающий, то нетерминал &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; станет недостижимым.&lt;br /&gt;
== См. также  ==&lt;br /&gt;
* [[Контекстно-свободные_грамматики,_вывод,_лево-_и_правосторонний_вывод,_дерево_разбора|Контекстно-свободные грамматики]]&lt;br /&gt;
* [[Нормальная_форма_Хомского|Нормальная форма Хомского]]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Chomsky_normal_form Chomsky normal form]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* ''Хопкрофт Д., Мотвани Р., Ульман Д.'' {{---}} Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. — Москва, Издательский дом «Вильямс», 2002. — 528 с. : ISBN 5-8459-0261-4 (рус.)&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Контекстно-свободные грамматики]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55662</id>
		<title>Алгоритм Бржозовского</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55662"/>
				<updated>2016-10-29T16:34:53Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: /* Источники информации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Задача&lt;br /&gt;
|definition = &lt;br /&gt;
Пусть дан [[Детерминированные_конечные_автоматы|автомат]] &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;. Требуется построить автомат &amp;lt;tex&amp;gt;\mathcal{A}_{min}&amp;lt;/tex&amp;gt; с наименьшим количеством состояний, распознающий тот же язык, что и &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; {{---}} состояние автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q, s \in Q, T \subset Q, \delta : Q \times \Sigma \to Q \rangle&amp;lt;/tex&amp;gt;. &lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Правым языком''' (англ. ''right language'') называется язык &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;, распознаваемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}_{d}(q) = \langle \Sigma , Q , q , T , \delta \rangle&amp;lt;/tex&amp;gt;, полученным из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; путём добавления уникального начального состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 }}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Левым языком''' (англ. ''left language'') называется язык &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, распознаваемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}_{g}(q) = \langle \Sigma , Q , q , T , \delta \rangle&amp;lt;/tex&amp;gt;, полученным из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; путём добавления уникального терминального состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=1&lt;br /&gt;
|statement=&lt;br /&gt;
Автомат является детерминированным тогда и только тогда, когда левые языки его состояний попарно не пересекаются.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратное слово''' &amp;lt;tex&amp;gt;r(u)&amp;lt;/tex&amp;gt; для слова &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; определяется следующим образом: &amp;lt;tex&amp;gt;r(\varepsilon) = \varepsilon&amp;lt;/tex&amp;gt; и если &amp;lt;tex&amp;gt;u = u_1 u_2 u_3 \dotsc u_p&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;r(u) = v_1 v_2 v_3 \dotsc v_p&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_i = u_{p - i + 1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный язык''' для языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} язык &amp;lt;tex&amp;gt;r(L) = \{ u \mid r(u) \in L \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный автомат''' для автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q , S , T , \delta \rangle&amp;lt;/tex&amp;gt; {{---}} автомат &amp;lt;tex&amp;gt;r(\mathcal{A}) = \langle \Sigma , Q , T , I , r(\delta) \rangle&amp;lt;/tex&amp;gt;, полученный из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; сменой местами начальных и конечных состояний и сменой направлений переходов.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=&lt;br /&gt;
Если &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; распознает язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt; распознает &amp;lt;tex&amp;gt;r(L)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=3&lt;br /&gt;
|statement=&lt;br /&gt;
Если левый язык состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, тогда его левый язык в &amp;lt;tex&amp;gt;r(A)&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;. Аналогично для правого языка &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q , I , T , \delta \rangle&amp;lt;/tex&amp;gt; {{---}} [[Недетерминированные_конечные_автоматы|НКА]].&amp;lt;br&amp;gt;Тогда детерминированный автомат &amp;lt;tex&amp;gt;d(\mathcal{A}) = \langle \Sigma , Q' , \{ i' \} , T' , \delta' \rangle&amp;lt;/tex&amp;gt; определяется следующим образом:&lt;br /&gt;
* Детерминированному состоянию соответствует множество недетерминированных состояний: для каждого &amp;lt;tex&amp;gt;q' \in Q'&amp;lt;/tex&amp;gt; имеем &amp;lt;tex&amp;gt;q' \subseteq Q&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* Начальное состояние в &amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} множество из &amp;lt;tex&amp;gt;I&amp;lt;/tex&amp;gt; начальных состояний автомата &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* Состояние в детерминированном автомате является терминальным тогда и только тогда, когда оно содержится хотя бы в одном недетерминированном состоянии,&lt;br /&gt;
* Пусть &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; {{---}} состояние детерминированного автомата и &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; – символ из &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;. Если переход из &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; по символу &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; определен, тогда, по построению: &amp;lt;tex&amp;gt;\delta'(q', a) = \bigcup\limits_{q \in q'}{ \delta(q, a)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=4&lt;br /&gt;
|statement=&lt;br /&gt;
Правый язык состояния &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; эквивалентен объединению правых языков состояний &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; автомата &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, принадлежащих множеству &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Левое отношение'''  (англ. ''left quotient'') регулярного языка &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;\Sigma^{*}&amp;lt;/tex&amp;gt; {{---}} язык &amp;lt;tex&amp;gt;u^{-1}L = \{ v \in X^{*} \mid uv \in L \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Минимальный автомат &amp;lt;tex&amp;gt;\mathcal{A}_{L}&amp;lt;/tex&amp;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;
* начальное состояние {{---}} &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* терминальные состояния {{---}} множество отношений, содержащих пустое слово,&lt;br /&gt;
* функция перехода &amp;lt;tex&amp;gt;\delta(u^{-1}L, x) = (ux)^{-1}L&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Автомат &amp;lt;tex&amp;gt;\mathcal{A}_L&amp;lt;/tex&amp;gt; уникален с точностью до изоморфизма и имеет минимальное количество состояний. &lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=5&lt;br /&gt;
|statement=&lt;br /&gt;
Детерминированный полный достижимый автомат минимален тогда и только тогда, когда правые языки его состояний различны.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Алгоритм==&lt;br /&gt;
===Описание===&lt;br /&gt;
Алгоритм минимизации конечных [[Детерминированные конечные автоматы|автоматов]] Бржозовского (Janusz A. (John) Brzozowski) выделяется, по крайней мере, следующими качествами:&lt;br /&gt;
* Он элегантен и весьма оригинален.&lt;br /&gt;
* Он эффективен.&lt;br /&gt;
* Он работает даже с [[Недетерминированные конечные автоматы|недетерминированными конечными автоматами]].&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} конечный автомат. &amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} детерминизированный автомат для &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} обратный автомат для &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Обозначим &amp;lt;tex&amp;gt;d(r(\mathcal{A}))&amp;lt;/tex&amp;gt; как &amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;r(d(r(\mathcal{A})))&amp;lt;/tex&amp;gt; как &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;d(r(d(r(\mathcal{A}))))&amp;lt;/tex&amp;gt; как &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about=Бржозовский, 1962&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} автомат (необязательно детерминированный), распознающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Минимальный детерминированный автомат &amp;lt;tex&amp;gt;\mathcal{A}_L&amp;lt;/tex&amp;gt; может быть вычислен следующим образом: &amp;lt;tex&amp;gt;\mathcal{A}_L = drdr(\mathcal{A})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
По построению автомат &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; детерминированный. Согласно утверждению 2, он распознает язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt; &lt;br /&gt;
Покажем, что все правые языки &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; различны. Из утверждения 1, левые языки &amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt; попарно не пересекаются. Из утверждения 3, правые языки &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt; являются левыми языками &amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt;. Таким образом, они попарно не пересекаются. Согласно утверждению 4, правый язык &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} объединение правых языков &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Поскольку правые языки &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt; попарно не пересекаются, все правые языки &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; различны. &lt;br /&gt;
Так как все правые языки &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; различны, согласно утверждению 5 автомат &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; минимальный. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Пример работы===&lt;br /&gt;
# Исходный [[Недетерминированные конечные автоматы|НКА]] &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Fa.png|Исходный НКА]]&lt;br /&gt;
# Первый шаг, &amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Rfa.png|Первый шаг]]&lt;br /&gt;
# Второй шаг, &amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Drfa.png|Второй шаг]]&amp;lt;br&amp;gt;В детерминизированных автоматах состояния переименованы, так что &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; всегда является начальным состоянием.&lt;br /&gt;
# Третий шаг, &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Rdrfa.png|Третий шаг]]&amp;lt;br&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;
# Заключительный шаг, &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Drdrfa.png|Заключительный шаг]]&lt;br /&gt;
&lt;br /&gt;
== Заключение ==&lt;br /&gt;
Самым эффективным алгоритмом минимизации принято считать [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]], который, как и прочие традиционные алгоритмы, работает только с [[Детерминированные_конечные_автоматы|ДКА]]. Его асимптотическое время выполнения зависит от логарифма исходных данных. С другой стороны очевидно, что алгоритм Бржозовского в худшем случае будет обладать экспоненциальным временем выполнения, ведь этого требует процедура детерминизации, выполняемая дважды. На практике же наблюдается парадокс, алгоритм Бржозовского во многих случаях опережает прочие подходы к минимизации, включая и [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]]. В работе&amp;lt;ref&amp;gt;[http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=A511A421C93DF66BDCC32A0E133D1F99?doi=10.1.1.59.8276&amp;amp;rep=rep1&amp;amp;type=pdf Deian Tabakov, Moshe Y. Vardi. Experimental evaluation of classical automata constructions]&amp;lt;/ref&amp;gt;, сравнивающей оба алгоритма, показано, что алгоритм Бржозовского оказывается эффективнее [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритма Хопкрофта]] для автоматов с большим числом переходов.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Минимизация ДКА, алгоритм за O(n^2) с построением пар различимых состояний]]&lt;br /&gt;
*[[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))]]&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [https://pdfs.semanticscholar.org/f3be/b5e5825e6eedaab7f382341c9dd9c2ab33fa.pdf J.-M. Champarnaud, A. Khorsi, T. Paranthoen {{---}} Split and join for minimizing: Brzozowski's algorithm]&lt;br /&gt;
* [http://sovietov.com/txt/minfa/minfa.html Пётр Советов {{---}} Алгоритм Бржозовского для минимизации конечного автомата]&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55661</id>
		<title>Алгоритм Бржозовского</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55661"/>
				<updated>2016-10-29T16:31:36Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Задача&lt;br /&gt;
|definition = &lt;br /&gt;
Пусть дан [[Детерминированные_конечные_автоматы|автомат]] &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;. Требуется построить автомат &amp;lt;tex&amp;gt;\mathcal{A}_{min}&amp;lt;/tex&amp;gt; с наименьшим количеством состояний, распознающий тот же язык, что и &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; {{---}} состояние автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q, s \in Q, T \subset Q, \delta : Q \times \Sigma \to Q \rangle&amp;lt;/tex&amp;gt;. &lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Правым языком''' (англ. ''right language'') называется язык &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;, распознаваемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}_{d}(q) = \langle \Sigma , Q , q , T , \delta \rangle&amp;lt;/tex&amp;gt;, полученным из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; путём добавления уникального начального состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 }}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Левым языком''' (англ. ''left language'') называется язык &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, распознаваемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}_{g}(q) = \langle \Sigma , Q , q , T , \delta \rangle&amp;lt;/tex&amp;gt;, полученным из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; путём добавления уникального терминального состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=1&lt;br /&gt;
|statement=&lt;br /&gt;
Автомат является детерминированным тогда и только тогда, когда левые языки его состояний попарно не пересекаются.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратное слово''' &amp;lt;tex&amp;gt;r(u)&amp;lt;/tex&amp;gt; для слова &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; определяется следующим образом: &amp;lt;tex&amp;gt;r(\varepsilon) = \varepsilon&amp;lt;/tex&amp;gt; и если &amp;lt;tex&amp;gt;u = u_1 u_2 u_3 \dotsc u_p&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;r(u) = v_1 v_2 v_3 \dotsc v_p&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_i = u_{p - i + 1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный язык''' для языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} язык &amp;lt;tex&amp;gt;r(L) = \{ u \mid r(u) \in L \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный автомат''' для автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q , S , T , \delta \rangle&amp;lt;/tex&amp;gt; {{---}} автомат &amp;lt;tex&amp;gt;r(\mathcal{A}) = \langle \Sigma , Q , T , I , r(\delta) \rangle&amp;lt;/tex&amp;gt;, полученный из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; сменой местами начальных и конечных состояний и сменой направлений переходов.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=&lt;br /&gt;
Если &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; распознает язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt; распознает &amp;lt;tex&amp;gt;r(L)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=3&lt;br /&gt;
|statement=&lt;br /&gt;
Если левый язык состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, тогда его левый язык в &amp;lt;tex&amp;gt;r(A)&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;. Аналогично для правого языка &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q , I , T , \delta \rangle&amp;lt;/tex&amp;gt; {{---}} [[Недетерминированные_конечные_автоматы|НКА]].&amp;lt;br&amp;gt;Тогда детерминированный автомат &amp;lt;tex&amp;gt;d(\mathcal{A}) = \langle \Sigma , Q' , \{ i' \} , T' , \delta' \rangle&amp;lt;/tex&amp;gt; определяется следующим образом:&lt;br /&gt;
* Детерминированному состоянию соответствует множество недетерминированных состояний: для каждого &amp;lt;tex&amp;gt;q' \in Q'&amp;lt;/tex&amp;gt; имеем &amp;lt;tex&amp;gt;q' \subseteq Q&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* Начальное состояние в &amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} множество из &amp;lt;tex&amp;gt;I&amp;lt;/tex&amp;gt; начальных состояний автомата &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* Состояние в детерминированном автомате является терминальным тогда и только тогда, когда оно содержится хотя бы в одном недетерминированном состоянии,&lt;br /&gt;
* Пусть &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; {{---}} состояние детерминированного автомата и &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; – символ из &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;. Если переход из &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; по символу &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; определен, тогда, по построению: &amp;lt;tex&amp;gt;\delta'(q', a) = \bigcup\limits_{q \in q'}{ \delta(q, a)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=4&lt;br /&gt;
|statement=&lt;br /&gt;
Правый язык состояния &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; эквивалентен объединению правых языков состояний &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; автомата &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, принадлежащих множеству &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Левое отношение'''  (англ. ''left quotient'') регулярного языка &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;\Sigma^{*}&amp;lt;/tex&amp;gt; {{---}} язык &amp;lt;tex&amp;gt;u^{-1}L = \{ v \in X^{*} \mid uv \in L \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Минимальный автомат &amp;lt;tex&amp;gt;\mathcal{A}_{L}&amp;lt;/tex&amp;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;
* начальное состояние {{---}} &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* терминальные состояния {{---}} множество отношений, содержащих пустое слово,&lt;br /&gt;
* функция перехода &amp;lt;tex&amp;gt;\delta(u^{-1}L, x) = (ux)^{-1}L&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Автомат &amp;lt;tex&amp;gt;\mathcal{A}_L&amp;lt;/tex&amp;gt; уникален с точностью до изоморфизма и имеет минимальное количество состояний. &lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=5&lt;br /&gt;
|statement=&lt;br /&gt;
Детерминированный полный достижимый автомат минимален тогда и только тогда, когда правые языки его состояний различны.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Алгоритм==&lt;br /&gt;
===Описание===&lt;br /&gt;
Алгоритм минимизации конечных [[Детерминированные конечные автоматы|автоматов]] Бржозовского (Janusz A. (John) Brzozowski) выделяется, по крайней мере, следующими качествами:&lt;br /&gt;
* Он элегантен и весьма оригинален.&lt;br /&gt;
* Он эффективен.&lt;br /&gt;
* Он работает даже с [[Недетерминированные конечные автоматы|недетерминированными конечными автоматами]].&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} конечный автомат. &amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} детерминизированный автомат для &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} обратный автомат для &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Обозначим &amp;lt;tex&amp;gt;d(r(\mathcal{A}))&amp;lt;/tex&amp;gt; как &amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;r(d(r(\mathcal{A})))&amp;lt;/tex&amp;gt; как &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;d(r(d(r(\mathcal{A}))))&amp;lt;/tex&amp;gt; как &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about=Бржозовский, 1962&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} автомат (необязательно детерминированный), распознающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Минимальный детерминированный автомат &amp;lt;tex&amp;gt;\mathcal{A}_L&amp;lt;/tex&amp;gt; может быть вычислен следующим образом: &amp;lt;tex&amp;gt;\mathcal{A}_L = drdr(\mathcal{A})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
По построению автомат &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; детерминированный. Согласно утверждению 2, он распознает язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt; &lt;br /&gt;
Покажем, что все правые языки &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; различны. Из утверждения 1, левые языки &amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt; попарно не пересекаются. Из утверждения 3, правые языки &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt; являются левыми языками &amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt;. Таким образом, они попарно не пересекаются. Согласно утверждению 4, правый язык &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} объединение правых языков &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Поскольку правые языки &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt; попарно не пересекаются, все правые языки &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; различны. &lt;br /&gt;
Так как все правые языки &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; различны, согласно утверждению 5 автомат &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt; минимальный. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Пример работы===&lt;br /&gt;
# Исходный [[Недетерминированные конечные автоматы|НКА]] &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Fa.png|Исходный НКА]]&lt;br /&gt;
# Первый шаг, &amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Rfa.png|Первый шаг]]&lt;br /&gt;
# Второй шаг, &amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Drfa.png|Второй шаг]]&amp;lt;br&amp;gt;В детерминизированных автоматах состояния переименованы, так что &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; всегда является начальным состоянием.&lt;br /&gt;
# Третий шаг, &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Rdrfa.png|Третий шаг]]&amp;lt;br&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;
# Заключительный шаг, &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt;:&amp;lt;br&amp;gt;[[Файл:Drdrfa.png|Заключительный шаг]]&lt;br /&gt;
&lt;br /&gt;
== Заключение ==&lt;br /&gt;
Самым эффективным алгоритмом минимизации принято считать [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]], который, как и прочие традиционные алгоритмы, работает только с [[Детерминированные_конечные_автоматы|ДКА]]. Его асимптотическое время выполнения зависит от логарифма исходных данных. С другой стороны очевидно, что алгоритм Бржозовского в худшем случае будет обладать экспоненциальным временем выполнения, ведь этого требует процедура детерминизации, выполняемая дважды. На практике же наблюдается парадокс, алгоритм Бржозовского во многих случаях опережает прочие подходы к минимизации, включая и [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]]. В работе&amp;lt;ref&amp;gt;[http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=A511A421C93DF66BDCC32A0E133D1F99?doi=10.1.1.59.8276&amp;amp;rep=rep1&amp;amp;type=pdf Deian Tabakov, Moshe Y. Vardi. Experimental evaluation of classical automata constructions]&amp;lt;/ref&amp;gt;, сравнивающей оба алгоритма, показано, что алгоритм Бржозовского оказывается эффективнее [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритма Хопкрофта]] для автоматов с большим числом переходов.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Минимизация ДКА, алгоритм за O(n^2) с построением пар различимых состояний]]&lt;br /&gt;
*[[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))]]&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [http://sovietov.com/txt/minfa/minfa.html Алгоритм Бржозовского для минимизации конечного автомата]&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55660</id>
		<title>Алгоритм Бржозовского</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55660"/>
				<updated>2016-10-29T16:15:41Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Задача&lt;br /&gt;
|definition = &lt;br /&gt;
Пусть дан [[Детерминированные_конечные_автоматы|автомат]] &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;. Требуется построить автомат &amp;lt;tex&amp;gt;\mathcal{A}_{min}&amp;lt;/tex&amp;gt; с наименьшим количеством состояний, распознающий тот же язык, что и &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; {{---}} состояние автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q, s \in Q, T \subset Q, \delta : Q \times \Sigma \to Q \rangle&amp;lt;/tex&amp;gt;. &lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Правым языком''' (англ. ''right language'') {{---}} называется язык &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;, принимаемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}_{d}(q) = \langle \Sigma , Q , q , T , \delta \rangle&amp;lt;/tex&amp;gt;, полученным из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; путём добавления уникального начального состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 }}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Левым языком''' (англ. ''left language'') {{---}} называется язык &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, принимаемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}_{g}(q) = \langle \Sigma , Q , q , T , \delta \rangle&amp;lt;/tex&amp;gt;, полученным из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; путём добавления уникального терминального состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=1&lt;br /&gt;
|statement=&lt;br /&gt;
Автомат является детерминированным тогда и только тогда, когда левые языки его состояний попарно не пересекаются.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратное слово''' &amp;lt;tex&amp;gt;r(u)&amp;lt;/tex&amp;gt; для слова &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; определяется следующим образом: &amp;lt;tex&amp;gt;r(\varepsilon) = \varepsilon&amp;lt;/tex&amp;gt; и если &amp;lt;tex&amp;gt;u = u_1 u_2 u_3 \dotsc u_p&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;r(u) = v_1 v_2 v_3 \dotsc v_p&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_i = u_{p - i + 1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный язык''' для языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} язык &amp;lt;tex&amp;gt;r(L) = \{ u \mid r(u) \in L \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный автомат''' для автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q , S , T , \delta \rangle&amp;lt;/tex&amp;gt; {{---}} автомат &amp;lt;tex&amp;gt;r(\mathcal{A}) = \langle \Sigma , Q , T , I , r(\delta) \rangle&amp;lt;/tex&amp;gt;, полученный из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; сменой местами начальных и конечных состояний и сменой направлений переходов.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=&lt;br /&gt;
Если &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; распознает язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt; распознает &amp;lt;tex&amp;gt;r(L)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=3&lt;br /&gt;
|statement=&lt;br /&gt;
Если левый язык состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, тогда его левый язык в &amp;lt;tex&amp;gt;r(A)&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;. Аналогично для правого языка &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q , I , T , \delta \rangle&amp;lt;/tex&amp;gt; {{---}} [[Недетерминированные_конечные_автоматы|НКА]].&amp;lt;br&amp;gt;Тогда детерминированный автомат &amp;lt;tex&amp;gt;d(\mathcal{A}) = \langle \Sigma , Q' , \{ i' \} , T' , \delta' \rangle&amp;lt;/tex&amp;gt; определяется следующим образом:&lt;br /&gt;
* Детерминированному состоянию соответствует множество недетерминированных состояний: для каждого &amp;lt;tex&amp;gt;q' \in Q'&amp;lt;/tex&amp;gt; имеем &amp;lt;tex&amp;gt;q' \subseteq Q&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* Начальное состояние в &amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} множество из &amp;lt;tex&amp;gt;I&amp;lt;/tex&amp;gt; начальных состояний автомата &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* Состояние в детерминированном автомате является терминальным тогда и только тогда, когда оно содержится хотя бы в одном недетерминированном состоянии,&lt;br /&gt;
* Пусть &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; {{---}} состояние детерминированного автомата и &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; – символ из &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;. Если переход из &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; по символу &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; определен, тогда, по построению: &amp;lt;tex&amp;gt;\delta'(q', a) = \bigcup\limits_{q \in q'}{ \delta(q, a)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=4&lt;br /&gt;
|statement=&lt;br /&gt;
Правый язык состояния &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; эквивалентен объединению правых языков состояний &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; автомата &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, принадлежащих множеству &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&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;\Sigma^{*}&amp;lt;/tex&amp;gt; {{---}} язык &amp;lt;tex&amp;gt;u^{-1}L = \{ v \in X^{*} \mid uv \in L \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Минимальный автомат &amp;lt;tex&amp;gt;\mathcal{A}_{L}&amp;lt;/tex&amp;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;
* начальное состояние {{---}} &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* терминальные состояния {{---}} множество отношений, содержащих пустое слово,&lt;br /&gt;
* функция перехода &amp;lt;tex&amp;gt;\delta(u^{-1}L, x) = (ux)^{-1}L&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Автомат &amp;lt;tex&amp;gt;\mathcal{A}_L&amp;lt;/tex&amp;gt; уникален с точностью до изоморфизма и имеет минимальное количество состояний. &lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=5&lt;br /&gt;
|statement=&lt;br /&gt;
Детерминированный полный достижимый автомат минимален тогда и только тогда, когда правые языки его состояний различны.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Алгоритм==&lt;br /&gt;
===Описание===&lt;br /&gt;
Алгоритм минимизации конечных [[Детерминированные конечные автоматы|автоматов]] Бржозовского (Janusz A. (John) Brzozowski) выделяется, по крайней мере, следующими качествами:&lt;br /&gt;
* Он элегантен и весьма оригинален.&lt;br /&gt;
* Он эффективен.&lt;br /&gt;
* Он работает даже с [[Недетерминированные конечные автоматы|недетерминированными конечными автоматами]].&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} конечный автомат. &amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} детерминизированный автомат для &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} обратный автомат для &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Обозначим &amp;lt;tex&amp;gt;d(r(\mathcal{A}))&amp;lt;/tex&amp;gt; как &amp;lt;tex&amp;gt;dr(\mathcal{A})&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;r(d(r(\mathcal{A})))&amp;lt;/tex&amp;gt; как &amp;lt;tex&amp;gt;rdr(\mathcal{A})&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;d(r(d(r(\mathcal{A}))))&amp;lt;/tex&amp;gt; как &amp;lt;tex&amp;gt;drdr(\mathcal{A})&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about=Бржозовский, 1962&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} автомат (необязательно детерминированный), распознающий язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Минимальный детерминированный автомат &amp;lt;tex&amp;gt;\mathcal{A}_L&amp;lt;/tex&amp;gt; может быть вычислен следующим образом: &amp;lt;tex&amp;gt;\mathcal{A}_L = drdr(\mathcal{A})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=По построению автомат drdr(A) конечный. Согласно утверждению 2, он распознает язык L. &lt;br /&gt;
Покажем, что правые языки drdr(A) все различны. Из утверждения 1, левые языки dr(A) попарно не пересекаются. Из утверждения 3, правые языки rdr(A) являются левыми языками dr(A). Таким образом, они попарно не пересекаются. Согласно утверждению 4, правый язык drdr(A) – объединение правых языков rdr(A). &lt;br /&gt;
Поскольку правые языки rdr(A) попарно не пересекаются, все правые языки drdr(A) различны. Тогда, согласно утверждению 5 автомат drdr(A) минимальный. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Пример работы===&lt;br /&gt;
# Исходный [[Недетерминированные конечные автоматы|НКА]] (&amp;lt;tex&amp;gt;FA&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Fa.png|Исходный НКА]]&lt;br /&gt;
# Первый шаг алгоритма (&amp;lt;tex&amp;gt;\operatorname{rev}(FA)&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Rfa.png|Первый шаг]]&lt;br /&gt;
# Второй шаг алгоритма (&amp;lt;tex&amp;gt;\operatorname{det}(\operatorname{rev}(FA))&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Drfa.png|Второй шаг]]&amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;\operatorname{det}&amp;lt;/tex&amp;gt; переименовывает состояния, после этого &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; всегда является начальным состоянием&lt;br /&gt;
# Третий шаг алгоритма (&amp;lt;tex&amp;gt;\operatorname{rev}(\operatorname{det}(\operatorname{rev}(FA)))&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Rdrfa.png|Третий шаг]]&amp;lt;br&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;
# Заключительный шаг алгоритма (&amp;lt;tex&amp;gt;\operatorname{det}(\operatorname{rev}(\operatorname{det}(\operatorname{rev}(FA))))&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Drdrfa.png|Заключительный шаг]]&lt;br /&gt;
&lt;br /&gt;
== Заключение ==&lt;br /&gt;
Самым эффективным алгоритмом минимизации принято считать [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]], который, как и прочие традиционные алгоритмы, работает только с [[Детерминированные_конечные_автоматы|ДКА]]. Его асимптотическое время выполнения зависит от логарифма исходных данных. С другой стороны очевидно, что алгоритм Бржозовского в худшем случае будет обладать экспоненциальным временем выполнения, ведь этого требует процедура детерминизации, выполняемая дважды. На практике же наблюдается парадокс, алгоритм Бржозовского во многих случаях опережает прочие подходы к минимизации, включая и [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]]. В работе&amp;lt;ref&amp;gt;[http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=A511A421C93DF66BDCC32A0E133D1F99?doi=10.1.1.59.8276&amp;amp;rep=rep1&amp;amp;type=pdf Deian Tabakov, Moshe Y. Vardi. Experimental evaluation of classical automata constructions]&amp;lt;/ref&amp;gt;, сравнивающей оба алгоритма, показано, что алгоритм Бржозовского оказывается эффективнее [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритма Хопкрофта]] для автоматов с большим числом переходов.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Минимизация ДКА, алгоритм за O(n^2) с построением пар различимых состояний]]&lt;br /&gt;
*[[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))]]&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [http://sovietov.com/txt/minfa/minfa.html Алгоритм Бржозовского для минимизации конечного автомата]&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55659</id>
		<title>Алгоритм Бржозовского</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55659"/>
				<updated>2016-10-28T21:56:57Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Задача&lt;br /&gt;
|definition = &lt;br /&gt;
Пусть дан [[Детерминированные_конечные_автоматы|автомат]] &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;. Требуется построить автомат &amp;lt;tex&amp;gt;\mathcal{A}_{min}&amp;lt;/tex&amp;gt; с наименьшим количеством состояний, распознающий тот же язык, что и &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; {{---}} состояние автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q, s \in Q, T \subset Q, \delta : Q \times \Sigma \to Q \rangle&amp;lt;/tex&amp;gt;. &lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Правым языком''' (англ. ''right language'') {{---}} называется язык &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;, принимаемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}_{d}(q) = \langle \Sigma , Q , q , T , \delta \rangle&amp;lt;/tex&amp;gt;, полученным из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; путём добавления уникального начального состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 }}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Левым языком''' (англ. ''left language'') {{---}} называется язык &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, принимаемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}_{g}(q) = \langle \Sigma , Q , q , T , \delta \rangle&amp;lt;/tex&amp;gt;, полученным из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; путём добавления уникального терминального состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=1&lt;br /&gt;
|statement=&lt;br /&gt;
Автомат является детерминированным тогда и только тогда, когда левые языки его состояний попарно не пересекаются.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратное слово''' &amp;lt;tex&amp;gt;r(u)&amp;lt;/tex&amp;gt; для слова &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; определяется следующим образом: &amp;lt;tex&amp;gt;r(\varepsilon) = \varepsilon&amp;lt;/tex&amp;gt; и если &amp;lt;tex&amp;gt;u = u_1 u_2 u_3 \dotsc u_p&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;r(u) = v_1 v_2 v_3 \dotsc v_p&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_i = u_{p - i + 1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный язык''' для языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} язык &amp;lt;tex&amp;gt;r(L) = \{ u \mid r(u) \in L \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный автомат''' для автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q , S , T , \delta \rangle&amp;lt;/tex&amp;gt; {{---}} автомат &amp;lt;tex&amp;gt;r(\mathcal{A}) = \langle \Sigma , Q , T , I , r(\delta) \rangle&amp;lt;/tex&amp;gt;, полученный из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; сменой местами начальных и конечных состояний и сменой направлений переходов.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=&lt;br /&gt;
Если &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; распознает язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt; распознает &amp;lt;tex&amp;gt;r(L)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=3&lt;br /&gt;
|statement=&lt;br /&gt;
Если левый язык состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, тогда его левый язык в &amp;lt;tex&amp;gt;r(A)&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;. Аналогично для правого языка &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q , I , T , \delta \rangle&amp;lt;/tex&amp;gt; {{---}} [[Недетерминированные_конечные_автоматы|НКА]].&amp;lt;br&amp;gt;Тогда детерминированный автомат &amp;lt;tex&amp;gt;d(\mathcal{A}) = \langle \Sigma , Q' , \{ i' \} , T' , \delta' \rangle&amp;lt;/tex&amp;gt; определяется следующим образом:&lt;br /&gt;
* Детерминированному состоянию соответствует множество недетерминированных состояний: для каждого &amp;lt;tex&amp;gt;q' \in Q'&amp;lt;/tex&amp;gt; имеем &amp;lt;tex&amp;gt;q' \subseteq Q&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* Начальное состояние в &amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} множество из &amp;lt;tex&amp;gt;I&amp;lt;/tex&amp;gt; начальных состояний автомата &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* Состояние в детерминированном автомате является терминальным тогда и только тогда, когда оно содержится хотя бы в одном недетерминированном состоянии,&lt;br /&gt;
* Пусть &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; {{---}} состояние детерминированного автомата и &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; – символ из &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;. Если переход из &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; по символу &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; определен, тогда, по построению: &amp;lt;tex&amp;gt;\delta'(q', a) = \bigcup\limits_{q \in q'}{ \delta(q, a)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=4&lt;br /&gt;
|statement=&lt;br /&gt;
Правый язык состояния &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; эквивалентен объединению правых языков состояний &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; автомата &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, принадлежащих множеству &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Минимальный автомат &amp;lt;tex&amp;gt;\mathcal{A}_{L}&amp;lt;/tex&amp;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;
* начальное состояние {{---}} &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* терминальные состояния {{---}} множество отношений, содержащих пустое слово,&lt;br /&gt;
* функция перехода &amp;lt;tex&amp;gt;\delta(u^{-1} \cdot L, x) = (ux)^{-1} \cdot L&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Автомат &amp;lt;tex&amp;gt;\mathcal{A}_L&amp;lt;/tex&amp;gt; уникален с точностью до изоморфизма и имеет минимальное количество состояний. &lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=5&lt;br /&gt;
|statement=&lt;br /&gt;
Автомат минимален тогда и только тогда, когда правые языки его состояний различны.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Алгоритм==&lt;br /&gt;
===Описание===&lt;br /&gt;
Алгоритм минимизации конечных [[Детерминированные конечные автоматы|автоматов]] Бржозовского (Janusz A. (John) Brzozowski) выделяется, по крайней мере, следующими качествами:&lt;br /&gt;
&lt;br /&gt;
* Он элегантен и весьма оригинален.&lt;br /&gt;
* Он эффективен.&lt;br /&gt;
* Он работает даже с [[Недетерминированные конечные автоматы|недетерминированными конечными автоматами]].&lt;br /&gt;
&lt;br /&gt;
Обладая обычными процедурами обращения &amp;lt;tex&amp;gt;\operatorname{rev}&amp;lt;/tex&amp;gt; и детерминизации &amp;lt;tex&amp;gt;\operatorname{det}&amp;lt;/tex&amp;gt; конечного [[Детерминированные конечные автоматы|автомата]], мы, с помощью идеи Бржозовского, можем немедленно приступить к минимизации заданного [[Детерминированные конечные автоматы|автомата]]. Для этого надо дважды провести его через обе вышеуказанные процедуры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;mFA = \operatorname {det}(\operatorname{rev}(\operatorname{det}(\operatorname{r}(FA))))&amp;lt;/tex&amp;gt;, где&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex&amp;gt;FA&amp;lt;/tex&amp;gt; это исходный КА,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\operatorname{rev}&amp;lt;/tex&amp;gt; это процедура обращения КА,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\operatorname{det}&amp;lt;/tex&amp;gt; это процедура детерминизации КА,&lt;br /&gt;
* &amp;lt;tex&amp;gt;mFA&amp;lt;/tex&amp;gt; это минимизированный КА.&lt;br /&gt;
&lt;br /&gt;
===Корректность===&lt;br /&gt;
По построению автомат drdr(A) конечный. Согласно утверждению 2, он распознает язык L. &lt;br /&gt;
Покажем, что правые языки drdr(A) все различны. Из утверждения 1, левые языки dr(A) попарно не пересекаются. Из утверждения 3, правые языки rdr(A) являются левыми языками dr(A). Таким образом, они попарно не пересекаются. Согласно утверждению 4, правый язык drdr(A) – объединение правых языков rdr(A). &lt;br /&gt;
Поскольку правые языки rdr(A) попарно не пересекаются, все правые языки drdr(A) различны. Тогда, согласно утверждению 5 автомат drdr(A) минимальный. &lt;br /&gt;
&lt;br /&gt;
==Пример работы==&lt;br /&gt;
# Исходный [[Недетерминированные конечные автоматы|НКА]] (&amp;lt;tex&amp;gt;FA&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Fa.png|Исходный НКА]]&lt;br /&gt;
# Первый шаг алгоритма (&amp;lt;tex&amp;gt;\operatorname{rev}(FA)&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Rfa.png|Первый шаг]]&lt;br /&gt;
# Второй шаг алгоритма (&amp;lt;tex&amp;gt;\operatorname{det}(\operatorname{rev}(FA))&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Drfa.png|Второй шаг]]&amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;\operatorname{det}&amp;lt;/tex&amp;gt; переименовывает состояния, после этого &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; всегда является начальным состоянием&lt;br /&gt;
# Третий шаг алгоритма (&amp;lt;tex&amp;gt;\operatorname{rev}(\operatorname{det}(\operatorname{rev}(FA)))&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Rdrfa.png|Третий шаг]]&amp;lt;br&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;
# Заключительный шаг алгоритма (&amp;lt;tex&amp;gt;\operatorname{det}(\operatorname{rev}(\operatorname{det}(\operatorname{rev}(FA))))&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Drdrfa.png|Заключительный шаг]]&lt;br /&gt;
&lt;br /&gt;
== Заключение ==&lt;br /&gt;
Самым эффективным алгоритмом минимизации принято считать [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]], который, как и прочие традиционные алгоритмы, работает только с [[Детерминированные_конечные_автоматы|ДКА]]. Его асимптотическое время выполнения зависит от логарифма исходных данных. С другой стороны очевидно, что алгоритм Бржозовского в худшем случае будет обладать экспоненциальным временем выполнения, ведь этого требует процедура детерминизации, выполняемая дважды. На практике же наблюдается парадокс, алгоритм Бржозовского во многих случаях опережает прочие подходы к минимизации, включая и [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]]. В работе&amp;lt;ref&amp;gt;[http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=A511A421C93DF66BDCC32A0E133D1F99?doi=10.1.1.59.8276&amp;amp;rep=rep1&amp;amp;type=pdf Deian Tabakov, Moshe Y. Vardi. Experimental evaluation of classical automata constructions]&amp;lt;/ref&amp;gt;, сравнивающей оба алгоритма, показано, что алгоритм Бржозовского оказывается эффективнее [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритма Хопкрофта]] для автоматов с большим числом переходов.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Минимизация ДКА, алгоритм за O(n^2) с построением пар различимых состояний]]&lt;br /&gt;
*[[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))]]&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [http://sovietov.com/txt/minfa/minfa.html Алгоритм Бржозовского для минимизации конечного автомата]&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55658</id>
		<title>Алгоритм Бржозовского</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55658"/>
				<updated>2016-10-28T21:55:14Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Задача&lt;br /&gt;
|definition = &lt;br /&gt;
Пусть дан [[Детерминированные_конечные_автоматы|автомат]] &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;. Требуется построить автомат &amp;lt;tex&amp;gt;\mathcal{A}_{min}&amp;lt;/tex&amp;gt; с наименьшим количеством состояний, распознающий тот же язык, что и &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; {{---}} состояние автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q, s \in Q, T \subset Q, \delta : Q \times \Sigma \to Q \rangle&amp;lt;/tex&amp;gt;. &lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Правым языком''' (англ. ''right language'') {{---}} называется язык &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;, принимаемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}_{d}(q) = \langle \Sigma , Q , q , T , \delta \rangle&amp;lt;/tex&amp;gt;, полученным из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; путём добавления уникального начального состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 }}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Левым языком''' (англ. ''left language'') {{---}} называется язык &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, принимаемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}_{g}(q) = \langle \Sigma , Q , q , T , \delta \rangle&amp;lt;/tex&amp;gt;, полученным из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; путём добавления уникального терминального состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=1&lt;br /&gt;
|statement=&lt;br /&gt;
Автомат является детерминированным тогда и только тогда, когда левые языки его состояний попарно не пересекаются.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратное слово''' &amp;lt;tex&amp;gt;r(u)&amp;lt;/tex&amp;gt; для слова &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; определяется следующим образом: &amp;lt;tex&amp;gt;r(\varepsilon) = \varepsilon&amp;lt;/tex&amp;gt; и если &amp;lt;tex&amp;gt;u = u_1 u_2 u_3 \dotsc u_p&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;r(u) = v_1 v_2 v_3 \dotsc v_p&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_i = u_{p - i + 1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный язык''' для языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} язык &amp;lt;tex&amp;gt;r(L) = \{ u \mid r(u) \in L \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный автомат''' для автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q , S , T , \delta \rangle&amp;lt;/tex&amp;gt; {{---}} автомат &amp;lt;tex&amp;gt;r(\mathcal{A}) = \langle \Sigma , Q , T , I , r(\delta) \rangle&amp;lt;/tex&amp;gt;, полученный из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; сменой местами начальных и конечных состояний и сменой направлений переходов.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=&lt;br /&gt;
Если &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; распознает язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt; распознает &amp;lt;tex&amp;gt;r(L)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=3&lt;br /&gt;
|statement=&lt;br /&gt;
Если левый язык состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, тогда его левый язык в &amp;lt;tex&amp;gt;r(A)&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;. Аналогично для правого языка &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q , I , T , \delta \rangle&amp;lt;/tex&amp;gt; {{---}} [[Недетерминированные_конечные_автоматы|НКА]].&amp;lt;br&amp;gt;Тогда детерминированный автомат &amp;lt;tex&amp;gt;d(\mathcal{A}) = \langle \Sigma , Q' , \{ i' \} , T' , \delta' \rangle&amp;lt;/tex&amp;gt; определяется следующим образом:&lt;br /&gt;
* Детерминированному состоянию соответствует множество недетерминированных состояний: для каждого &amp;lt;tex&amp;gt;q' \in Q'&amp;lt;/tex&amp;gt; имеем &amp;lt;tex&amp;gt;q' \subseteq Q&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* Начальное состояние в &amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} множество из &amp;lt;tex&amp;gt;I&amp;lt;/tex&amp;gt; начальных состояний автомата &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* Состояние в детерминированном автомате является терминальным тогда и только тогда, когда оно содержится хотя бы в одном недетерминированном состоянии,&lt;br /&gt;
* Пусть &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; {{---}} состояние детерминированного автомата и &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; – символ из &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;. Если переход из &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; по символу &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; определен, тогда, по построению: &amp;lt;tex&amp;gt;\delta'(q', a) = \bigcup\limits_{q \in q'}{ \delta(q, a)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=4&lt;br /&gt;
|statement=&lt;br /&gt;
Правый язык состояния &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; эквивалентен объединению правых языков состояний &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; автомата &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, принадлежащих множеству &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Минимальный автомат &amp;lt;tex&amp;gt;\mathcal{A_L}&amp;lt;/tex&amp;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;
* начальное состояние {{---}} &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* терминальные состояния {{---}} множество отношений, содержащих пустое слово,&lt;br /&gt;
* функция перехода &amp;lt;tex&amp;gt;\delta(u^-1 * L, x) = (ux)^-1 \cdot L&amp;lt;/tex&amp;gt;&lt;br /&gt;
Автомат &amp;lt;tex&amp;gt;\mathcal{A_L}&amp;lt;/tex&amp;gt; уникален с точностью до изоморфизма и имеет минимальное количество состояний. &lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=5&lt;br /&gt;
|statement=&lt;br /&gt;
Автомат минимален тогда и только тогда, когда правые языки его состояний различны.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Алгоритм==&lt;br /&gt;
===Описание===&lt;br /&gt;
Алгоритм минимизации конечных [[Детерминированные конечные автоматы|автоматов]] Бржозовского (Janusz A. (John) Brzozowski) выделяется, по крайней мере, следующими качествами:&lt;br /&gt;
&lt;br /&gt;
* Он элегантен и весьма оригинален.&lt;br /&gt;
* Он эффективен.&lt;br /&gt;
* Он работает даже с [[Недетерминированные конечные автоматы|недетерминированными конечными автоматами]].&lt;br /&gt;
&lt;br /&gt;
Обладая обычными процедурами обращения &amp;lt;tex&amp;gt;\operatorname{rev}&amp;lt;/tex&amp;gt; и детерминизации &amp;lt;tex&amp;gt;\operatorname{det}&amp;lt;/tex&amp;gt; конечного [[Детерминированные конечные автоматы|автомата]], мы, с помощью идеи Бржозовского, можем немедленно приступить к минимизации заданного [[Детерминированные конечные автоматы|автомата]]. Для этого надо дважды провести его через обе вышеуказанные процедуры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;mFA = \operatorname {det}(\operatorname{rev}(\operatorname{det}(\operatorname{r}(FA))))&amp;lt;/tex&amp;gt;, где&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex&amp;gt;FA&amp;lt;/tex&amp;gt; это исходный КА,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\operatorname{rev}&amp;lt;/tex&amp;gt; это процедура обращения КА,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\operatorname{det}&amp;lt;/tex&amp;gt; это процедура детерминизации КА,&lt;br /&gt;
* &amp;lt;tex&amp;gt;mFA&amp;lt;/tex&amp;gt; это минимизированный КА.&lt;br /&gt;
&lt;br /&gt;
===Корректность===&lt;br /&gt;
По построению автомат drdr(A) конечный. Согласно утверждению 2, он распознает язык L. &lt;br /&gt;
Покажем, что правые языки drdr(A) все различны. Из утверждения 1, левые языки dr(A) попарно не пересекаются. Из утверждения 3, правые языки rdr(A) являются левыми языками dr(A). Таким образом, они попарно не пересекаются. Согласно утверждению 4, правый язык drdr(A) – объединение правых языков rdr(A). &lt;br /&gt;
Поскольку правые языки rdr(A) попарно не пересекаются, все правые языки drdr(A) различны. Тогда, согласно утверждению 5 автомат drdr(A) минимальный. &lt;br /&gt;
&lt;br /&gt;
==Пример работы==&lt;br /&gt;
# Исходный [[Недетерминированные конечные автоматы|НКА]] (&amp;lt;tex&amp;gt;FA&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Fa.png|Исходный НКА]]&lt;br /&gt;
# Первый шаг алгоритма (&amp;lt;tex&amp;gt;\operatorname{rev}(FA)&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Rfa.png|Первый шаг]]&lt;br /&gt;
# Второй шаг алгоритма (&amp;lt;tex&amp;gt;\operatorname{det}(\operatorname{rev}(FA))&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Drfa.png|Второй шаг]]&amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;\operatorname{det}&amp;lt;/tex&amp;gt; переименовывает состояния, после этого &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; всегда является начальным состоянием&lt;br /&gt;
# Третий шаг алгоритма (&amp;lt;tex&amp;gt;\operatorname{rev}(\operatorname{det}(\operatorname{rev}(FA)))&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Rdrfa.png|Третий шаг]]&amp;lt;br&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;
# Заключительный шаг алгоритма (&amp;lt;tex&amp;gt;\operatorname{det}(\operatorname{rev}(\operatorname{det}(\operatorname{rev}(FA))))&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Drdrfa.png|Заключительный шаг]]&lt;br /&gt;
&lt;br /&gt;
== Заключение ==&lt;br /&gt;
Самым эффективным алгоритмом минимизации принято считать [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]], который, как и прочие традиционные алгоритмы, работает только с [[Детерминированные_конечные_автоматы|ДКА]]. Его асимптотическое время выполнения зависит от логарифма исходных данных. С другой стороны очевидно, что алгоритм Бржозовского в худшем случае будет обладать экспоненциальным временем выполнения, ведь этого требует процедура детерминизации, выполняемая дважды. На практике же наблюдается парадокс, алгоритм Бржозовского во многих случаях опережает прочие подходы к минимизации, включая и [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]]. В работе&amp;lt;ref&amp;gt;[http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=A511A421C93DF66BDCC32A0E133D1F99?doi=10.1.1.59.8276&amp;amp;rep=rep1&amp;amp;type=pdf Deian Tabakov, Moshe Y. Vardi. Experimental evaluation of classical automata constructions]&amp;lt;/ref&amp;gt;, сравнивающей оба алгоритма, показано, что алгоритм Бржозовского оказывается эффективнее [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритма Хопкрофта]] для автоматов с большим числом переходов.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Минимизация ДКА, алгоритм за O(n^2) с построением пар различимых состояний]]&lt;br /&gt;
*[[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))]]&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [http://sovietov.com/txt/minfa/minfa.html Алгоритм Бржозовского для минимизации конечного автомата]&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55657</id>
		<title>Алгоритм Бржозовского</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55657"/>
				<updated>2016-10-28T21:37:34Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Задача&lt;br /&gt;
|definition = &lt;br /&gt;
Пусть дан [[Детерминированные_конечные_автоматы|автомат]] &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;. Требуется построить автомат &amp;lt;tex&amp;gt;\mathcal{A}_{min}&amp;lt;/tex&amp;gt; с наименьшим количеством состояний, распознающий тот же язык, что и &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; {{---}} состояние автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q, s \in Q, T \subset Q, \delta : Q \times \Sigma \to Q \rangle&amp;lt;/tex&amp;gt;. &lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Правым языком''' (англ. ''right language'') {{---}} называется язык &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;, принимаемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}_{d}(q) = \langle \Sigma , Q , q , T , \delta \rangle&amp;lt;/tex&amp;gt;, полученным из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; путём добавления уникального начального состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 }}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Левым языком''' (англ. ''left language'') {{---}} называется язык &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, принимаемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}_{g}(q) = \langle \Sigma , Q , q , T , \delta \rangle&amp;lt;/tex&amp;gt;, полученным из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; путём добавления уникального терминального состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=1&lt;br /&gt;
|statement=&lt;br /&gt;
Автомат является детерминированным тогда и только тогда, когда левые языки его состояний попарно не пересекаются.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратное слово''' &amp;lt;tex&amp;gt;r(u)&amp;lt;/tex&amp;gt; для слова &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; определяется следующим образом: &amp;lt;tex&amp;gt;r(\varepsilon) = \varepsilon&amp;lt;/tex&amp;gt; и если &amp;lt;tex&amp;gt;u = u_1 u_2 u_3 \dotsc u_p&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;r(u) = v_1 v_2 v_3 \dotsc v_p&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_i = u_{p - i + 1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный язык''' для языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} язык &amp;lt;tex&amp;gt;r(L) = \{ u \mid r(u) \in L \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный автомат''' для автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q , S , T , \delta \rangle&amp;lt;/tex&amp;gt; {{---}} автомат &amp;lt;tex&amp;gt;r(\mathcal{A}) = \langle \Sigma , Q , T , I , r(\delta) \rangle&amp;lt;/tex&amp;gt;, полученный из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; сменой местами начальных и конечных состояний и сменой направлений переходов.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=&lt;br /&gt;
Если &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; распознает язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt; распознает &amp;lt;tex&amp;gt;r(L)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=3&lt;br /&gt;
|statement=&lt;br /&gt;
Если левый язык состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, тогда его левый язык в &amp;lt;tex&amp;gt;r(A)&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;. Аналогично для правого языка &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q , I , T , \delta \rangle&amp;lt;/tex&amp;gt; {{---}} [[Недетерминированные_конечные_автоматы|НКА]].&amp;lt;br&amp;gt;Тогда детерминированный автомат &amp;lt;tex&amp;gt;d(\mathcal{A}) = \langle \Sigma , Q' , \{ i' \} , T' , \delta' \rangle&amp;lt;/tex&amp;gt; определяется следующим образом:&lt;br /&gt;
* Детерминированному состоянию соответствует множество недетерминированных состояний: для каждого &amp;lt;tex&amp;gt;q' \in Q'&amp;lt;/tex&amp;gt; имеем &amp;lt;tex&amp;gt;q' \subseteq Q&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* Начальное состояние в &amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} множество из &amp;lt;tex&amp;gt;I&amp;lt;/tex&amp;gt; начальных состояний автомата &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* Состояние в детерминированном автомате является терминальным тогда и только тогда, когда оно содержится хотя бы в одном недетерминированном состоянии,&lt;br /&gt;
* Пусть &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; {{---}} состояние детерминированного автомата и &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; – символ из &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;. Если переход из &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; по символу &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; определен, тогда, по построению: &amp;lt;tex&amp;gt;\delta'(q', a) = \bigcup\limits_{q \in q'}{ \delta(q, a)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=4&lt;br /&gt;
|statement=&lt;br /&gt;
Правый язык состояния &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; эквивалентен объединению правых языков состояний &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; автомата &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;, принадлежащих множеству &amp;lt;tex&amp;gt;q'&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;
Алгоритм минимизации конечных [[Детерминированные конечные автоматы|автоматов]] Бржозовского (Janusz A. (John) Brzozowski) выделяется, по крайней мере, следующими качествами:&lt;br /&gt;
&lt;br /&gt;
* Он элегантен и весьма оригинален.&lt;br /&gt;
* Он эффективен.&lt;br /&gt;
* Он работает даже с [[Недетерминированные конечные автоматы|недетерминированными конечными автоматами]].&lt;br /&gt;
&lt;br /&gt;
Обладая обычными процедурами обращения &amp;lt;tex&amp;gt;\operatorname{rev}&amp;lt;/tex&amp;gt; и детерминизации &amp;lt;tex&amp;gt;\operatorname{det}&amp;lt;/tex&amp;gt; конечного [[Детерминированные конечные автоматы|автомата]], мы, с помощью идеи Бржозовского, можем немедленно приступить к минимизации заданного [[Детерминированные конечные автоматы|автомата]]. Для этого надо дважды провести его через обе вышеуказанные процедуры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;mFA = \operatorname {det}(\operatorname{rev}(\operatorname{det}(\operatorname{rev}(FA))))&amp;lt;/tex&amp;gt;, где&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex&amp;gt;FA&amp;lt;/tex&amp;gt; это исходный КА,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\operatorname{rev}&amp;lt;/tex&amp;gt; это процедура обращения КА,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\operatorname{det}&amp;lt;/tex&amp;gt; это процедура детерминизации КА,&lt;br /&gt;
* &amp;lt;tex&amp;gt;mFA&amp;lt;/tex&amp;gt; это минимизированный КА.&lt;br /&gt;
&lt;br /&gt;
===Корректность===&lt;br /&gt;
Корректность алгоритма доказана в работе&amp;lt;ref&amp;gt;[http://www.researchgate.net/publication/255626373_Split_and_join_for_minimizing__Brzozowski's_algorithm Split and join for minimizing : Brzozowski's algorithm]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Пример работы==&lt;br /&gt;
# Исходный [[Недетерминированные конечные автоматы|НКА]] (&amp;lt;tex&amp;gt;FA&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Fa.png|Исходный НКА]]&lt;br /&gt;
# Первый шаг алгоритма (&amp;lt;tex&amp;gt;\operatorname{rev}(FA)&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Rfa.png|Первый шаг]]&lt;br /&gt;
# Второй шаг алгоритма (&amp;lt;tex&amp;gt;\operatorname{det}(\operatorname{rev}(FA))&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Drfa.png|Второй шаг]]&amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;\operatorname{det}&amp;lt;/tex&amp;gt; переименовывает состояния, после этого &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; всегда является начальным состоянием&lt;br /&gt;
# Третий шаг алгоритма (&amp;lt;tex&amp;gt;\operatorname{rev}(\operatorname{det}(\operatorname{rev}(FA)))&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Rdrfa.png|Третий шаг]]&amp;lt;br&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;
# Заключительный шаг алгоритма (&amp;lt;tex&amp;gt;\operatorname{det}(\operatorname{rev}(\operatorname{det}(\operatorname{rev}(FA))))&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Drdrfa.png|Заключительный шаг]]&lt;br /&gt;
&lt;br /&gt;
== Заключение ==&lt;br /&gt;
Самым эффективным алгоритмом минимизации принято считать [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]], который, как и прочие традиционные алгоритмы, работает только с [[Детерминированные_конечные_автоматы|ДКА]]. Его асимптотическое время выполнения зависит от логарифма исходных данных. С другой стороны очевидно, что алгоритм Бржозовского в худшем случае будет обладать экспоненциальным временем выполнения, ведь этого требует процедура детерминизации, выполняемая дважды. На практике же наблюдается парадокс, алгоритм Бржозовского во многих случаях опережает прочие подходы к минимизации, включая и [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]]. В работе&amp;lt;ref&amp;gt;[http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=A511A421C93DF66BDCC32A0E133D1F99?doi=10.1.1.59.8276&amp;amp;rep=rep1&amp;amp;type=pdf Deian Tabakov, Moshe Y. Vardi. Experimental evaluation of classical automata constructions]&amp;lt;/ref&amp;gt;, сравнивающей оба алгоритма, показано, что алгоритм Бржозовского оказывается эффективнее [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритма Хопкрофта]] для автоматов с большим числом переходов.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Минимизация ДКА, алгоритм за O(n^2) с построением пар различимых состояний]]&lt;br /&gt;
*[[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))]]&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [http://sovietov.com/txt/minfa/minfa.html Алгоритм Бржозовского для минимизации конечного автомата]&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55656</id>
		<title>Алгоритм Бржозовского</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55656"/>
				<updated>2016-10-28T21:37:00Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Задача&lt;br /&gt;
|definition = &lt;br /&gt;
Пусть дан [[Детерминированные_конечные_автоматы|автомат]] &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;. Требуется построить автомат &amp;lt;tex&amp;gt;\mathcal{A}_{min}&amp;lt;/tex&amp;gt; с наименьшим количеством состояний, распознающий тот же язык, что и &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; {{---}} состояние автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q, s \in Q, T \subset Q, \delta : Q \times \Sigma \to Q \rangle&amp;lt;/tex&amp;gt;. &lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Правым языком''' (англ. ''right language'') {{---}} называется язык &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;, принимаемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}_{d}(q) = \langle \Sigma , Q , q , T , \delta \rangle&amp;lt;/tex&amp;gt;, полученным из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; путём добавления уникального начального состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 }}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Левым языком''' (англ. ''left language'') {{---}} называется язык &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, принимаемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}_{g}(q) = \langle \Sigma , Q , q , T , \delta \rangle&amp;lt;/tex&amp;gt;, полученным из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; путём добавления уникального терминального состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=1&lt;br /&gt;
|statement=&lt;br /&gt;
Автомат является детерминированным тогда и только тогда, когда левые языки его состояний попарно не пересекаются.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратное слово''' &amp;lt;tex&amp;gt;r(u)&amp;lt;/tex&amp;gt; для слова &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; определяется следующим образом: &amp;lt;tex&amp;gt;r(\varepsilon) = \varepsilon&amp;lt;/tex&amp;gt; и если &amp;lt;tex&amp;gt;u = u_1 u_2 u_3 \dotsc u_p&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;r(u) = v_1 v_2 v_3 \dotsc v_p&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_i = u_{p - i + 1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный язык''' для языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} язык &amp;lt;tex&amp;gt;r(L) = \{ u \mid r(u) \in L \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный автомат''' для автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q , S , T , \delta \rangle&amp;lt;/tex&amp;gt; {{---}} автомат &amp;lt;tex&amp;gt;r(\mathcal{A}) = \langle \Sigma , Q , T , I , r(\delta) \rangle&amp;lt;/tex&amp;gt;, полученный из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; сменой местами начальных и конечных состояний и сменой направлений переходов.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=&lt;br /&gt;
Если &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; распознает язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt; распознает &amp;lt;tex&amp;gt;r(L)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=3&lt;br /&gt;
|statement=&lt;br /&gt;
Если левый язык состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, тогда его левый язык в &amp;lt;tex&amp;gt;r(A)&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;. Аналогично для правого языка &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q , I , T , \delta \rangle&amp;lt;/tex&amp;gt; {{---}} [[Недетерминированные_конечные_автоматы|НКА]].&amp;lt;br&amp;gt;Тогда детерминированный автомат &amp;lt;tex&amp;gt;d(\mathcal{A}) = \langle \Sigma , Q' , \{ i' \} , T' , \delta' \rangle&amp;lt;/tex&amp;gt; определяется следующим образом:&lt;br /&gt;
* Детерминированному состоянию соответствует множество недетерминированных состояний: для каждого &amp;lt;tex&amp;gt;q' \in Q'&amp;lt;/tex&amp;gt; имеем &amp;lt;tex&amp;gt;q' \subseteq Q&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* Начальное состояние в &amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; {{---}} множество из &amp;lt;tex&amp;gt;I&amp;lt;/tex&amp;gt; начальных состояний автомата &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* Состояние в детерминированном автомате является терминальным тогда и только тогда, когда оно содержится хотя бы в одном недетерминированном состоянии,&lt;br /&gt;
* Пусть &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; {{---}} состояние детерминированного автомата и &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; – символ из &amp;lt;tex&amp;gt;\Sigma&amp;lt;/tex&amp;gt;. Если переход из &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; по символу &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; определен, тогда, по построению: &amp;lt;tex&amp;gt;\delta'(q', a) = \bigcup\limits_{q \in q'}{ \delta(q, a)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=4&lt;br /&gt;
|statement=&lt;br /&gt;
Правый язык состояния &amp;lt;tex&amp;gt;q'&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;d(\mathcal{A})&amp;lt;/tex&amp;gt; эквивалентен объединению правых языков состояний &amp;lt;tex&amp;gt;q \mathcal{A}&amp;lt;/tex&amp;gt;, принадлежащих множеству &amp;lt;tex&amp;gt;q'&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;
Алгоритм минимизации конечных [[Детерминированные конечные автоматы|автоматов]] Бржозовского (Janusz A. (John) Brzozowski) выделяется, по крайней мере, следующими качествами:&lt;br /&gt;
&lt;br /&gt;
* Он элегантен и весьма оригинален.&lt;br /&gt;
* Он эффективен.&lt;br /&gt;
* Он работает даже с [[Недетерминированные конечные автоматы|недетерминированными конечными автоматами]].&lt;br /&gt;
&lt;br /&gt;
Обладая обычными процедурами обращения &amp;lt;tex&amp;gt;\operatorname{rev}&amp;lt;/tex&amp;gt; и детерминизации &amp;lt;tex&amp;gt;\operatorname{det}&amp;lt;/tex&amp;gt; конечного [[Детерминированные конечные автоматы|автомата]], мы, с помощью идеи Бржозовского, можем немедленно приступить к минимизации заданного [[Детерминированные конечные автоматы|автомата]]. Для этого надо дважды провести его через обе вышеуказанные процедуры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;mFA = \operatorname {det}(\operatorname{rev}(\operatorname{det}(\operatorname{rev}(FA))))&amp;lt;/tex&amp;gt;, где&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex&amp;gt;FA&amp;lt;/tex&amp;gt; это исходный КА,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\operatorname{rev}&amp;lt;/tex&amp;gt; это процедура обращения КА,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\operatorname{det}&amp;lt;/tex&amp;gt; это процедура детерминизации КА,&lt;br /&gt;
* &amp;lt;tex&amp;gt;mFA&amp;lt;/tex&amp;gt; это минимизированный КА.&lt;br /&gt;
&lt;br /&gt;
===Корректность===&lt;br /&gt;
Корректность алгоритма доказана в работе&amp;lt;ref&amp;gt;[http://www.researchgate.net/publication/255626373_Split_and_join_for_minimizing__Brzozowski's_algorithm Split and join for minimizing : Brzozowski's algorithm]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Пример работы==&lt;br /&gt;
# Исходный [[Недетерминированные конечные автоматы|НКА]] (&amp;lt;tex&amp;gt;FA&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Fa.png|Исходный НКА]]&lt;br /&gt;
# Первый шаг алгоритма (&amp;lt;tex&amp;gt;\operatorname{rev}(FA)&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Rfa.png|Первый шаг]]&lt;br /&gt;
# Второй шаг алгоритма (&amp;lt;tex&amp;gt;\operatorname{det}(\operatorname{rev}(FA))&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Drfa.png|Второй шаг]]&amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;\operatorname{det}&amp;lt;/tex&amp;gt; переименовывает состояния, после этого &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; всегда является начальным состоянием&lt;br /&gt;
# Третий шаг алгоритма (&amp;lt;tex&amp;gt;\operatorname{rev}(\operatorname{det}(\operatorname{rev}(FA)))&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Rdrfa.png|Третий шаг]]&amp;lt;br&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;
# Заключительный шаг алгоритма (&amp;lt;tex&amp;gt;\operatorname{det}(\operatorname{rev}(\operatorname{det}(\operatorname{rev}(FA))))&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Drdrfa.png|Заключительный шаг]]&lt;br /&gt;
&lt;br /&gt;
== Заключение ==&lt;br /&gt;
Самым эффективным алгоритмом минимизации принято считать [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]], который, как и прочие традиционные алгоритмы, работает только с [[Детерминированные_конечные_автоматы|ДКА]]. Его асимптотическое время выполнения зависит от логарифма исходных данных. С другой стороны очевидно, что алгоритм Бржозовского в худшем случае будет обладать экспоненциальным временем выполнения, ведь этого требует процедура детерминизации, выполняемая дважды. На практике же наблюдается парадокс, алгоритм Бржозовского во многих случаях опережает прочие подходы к минимизации, включая и [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]]. В работе&amp;lt;ref&amp;gt;[http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=A511A421C93DF66BDCC32A0E133D1F99?doi=10.1.1.59.8276&amp;amp;rep=rep1&amp;amp;type=pdf Deian Tabakov, Moshe Y. Vardi. Experimental evaluation of classical automata constructions]&amp;lt;/ref&amp;gt;, сравнивающей оба алгоритма, показано, что алгоритм Бржозовского оказывается эффективнее [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритма Хопкрофта]] для автоматов с большим числом переходов.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Минимизация ДКА, алгоритм за O(n^2) с построением пар различимых состояний]]&lt;br /&gt;
*[[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))]]&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [http://sovietov.com/txt/minfa/minfa.html Алгоритм Бржозовского для минимизации конечного автомата]&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55558</id>
		<title>Алгоритм Бржозовского</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55558"/>
				<updated>2016-10-16T15:34:08Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Задача&lt;br /&gt;
|definition = &lt;br /&gt;
Пусть дан [[Детерминированные_конечные_автоматы|автомат]] &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;. Требуется построить автомат &amp;lt;tex&amp;gt;\mathcal{A}_{min}&amp;lt;/tex&amp;gt; с наименьшим количеством состояний, распознающий тот же язык, что и &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; {{---}} состояние автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q, s \in Q, T \subset Q, \delta : Q \times \Sigma \to Q \rangle&amp;lt;/tex&amp;gt;. &lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Правым языком''' (англ. ''right language'') {{---}} называется язык &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;, принимаемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}_{d}(q) = \langle \Sigma , Q , q , T , \delta \rangle&amp;lt;/tex&amp;gt;, полученным из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; путём добавления уникального начального состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 }}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Левым языком''' (англ. ''left language'') {{---}} называется язык &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, принимаемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}_{g}(q) = \langle \Sigma , Q , q , T , \delta \rangle&amp;lt;/tex&amp;gt;, полученным из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; путём добавления уникального терминального состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=1&lt;br /&gt;
|statement=&lt;br /&gt;
Автомат является детерминированным тогда и только тогда, когда левые языки его состояний попарно не пересекаются.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратное слово''' &amp;lt;tex&amp;gt;r(u)&amp;lt;/tex&amp;gt; для слова &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; определяется следующим образом: &amp;lt;tex&amp;gt;r(\varepsilon) = \varepsilon&amp;lt;/tex&amp;gt; и если &amp;lt;tex&amp;gt;u = u_1 u_2 u_3 \dotsc u_p&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;r(u) = v_1 v_2 v_3 \dotsc v_p&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_i = u_{p - i + 1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный язык''' для языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} язык &amp;lt;tex&amp;gt;r(L) = \{ u \mid r(u) \in L \}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный автомат''' для автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q , S , T , \delta \rangle&amp;lt;/tex&amp;gt; {{---}} автомат &amp;lt;tex&amp;gt;r(\mathcal{A}) = \langle \Sigma , Q , T , I , r(\delta) \rangle&amp;lt;/tex&amp;gt;, полученный из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; сменой местами начальных и конечных состояний и сменой направлений переходов.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=&lt;br /&gt;
Если &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; распознает язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt; распознает &amp;lt;tex&amp;gt;r(L)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=3&lt;br /&gt;
|statement=&lt;br /&gt;
Если левый язык состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, тогда его левый язык в &amp;lt;tex&amp;gt;r(A)&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;. Аналогично для правого языка &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q , I , T , \delta \rangle&amp;lt;/tex&amp;gt; {{---}} [[Недетерминированные_конечные_автоматы|НКА]].&amp;lt;br&amp;gt;Тогда детерминированный автомат &amp;lt;tex&amp;gt;d(\mathcal{A}) = \langle \Sigma , Q' , \{ i' \} , T' , \delta' \rangle&amp;lt;/tex&amp;gt; определяется следующим образом:&lt;br /&gt;
* Детерминированному состоянию соответствует множество недетерминированных состояний: для каждого &amp;lt;tex&amp;gt;q' \in Q'&amp;lt;/tex&amp;gt; имеем &amp;lt;tex&amp;gt;q' \subseteq Q&amp;lt;/tex&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
==Алгоритм==&lt;br /&gt;
===Описание===&lt;br /&gt;
Алгоритм минимизации конечных [[Детерминированные конечные автоматы|автоматов]] Бржозовского (Janusz A. (John) Brzozowski) выделяется, по крайней мере, следующими качествами:&lt;br /&gt;
&lt;br /&gt;
* Он элегантен и весьма оригинален.&lt;br /&gt;
* Он эффективен.&lt;br /&gt;
* Он работает даже с [[Недетерминированные конечные автоматы|недетерминированными конечными автоматами]].&lt;br /&gt;
&lt;br /&gt;
Обладая обычными процедурами обращения &amp;lt;tex&amp;gt;\operatorname{rev}&amp;lt;/tex&amp;gt; и детерминизации &amp;lt;tex&amp;gt;\operatorname{det}&amp;lt;/tex&amp;gt; конечного [[Детерминированные конечные автоматы|автомата]], мы, с помощью идеи Бржозовского, можем немедленно приступить к минимизации заданного [[Детерминированные конечные автоматы|автомата]]. Для этого надо дважды провести его через обе вышеуказанные процедуры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;mFA = \operatorname {det}(\operatorname{rev}(\operatorname{det}(\operatorname{rev}(FA))))&amp;lt;/tex&amp;gt;, где&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex&amp;gt;FA&amp;lt;/tex&amp;gt; это исходный КА,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\operatorname{rev}&amp;lt;/tex&amp;gt; это процедура обращения КА,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\operatorname{det}&amp;lt;/tex&amp;gt; это процедура детерминизации КА,&lt;br /&gt;
* &amp;lt;tex&amp;gt;mFA&amp;lt;/tex&amp;gt; это минимизированный КА.&lt;br /&gt;
&lt;br /&gt;
===Корректность===&lt;br /&gt;
Корректность алгоритма доказана в работе&amp;lt;ref&amp;gt;[http://www.researchgate.net/publication/255626373_Split_and_join_for_minimizing__Brzozowski's_algorithm Split and join for minimizing : Brzozowski's algorithm]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Пример работы==&lt;br /&gt;
# Исходный [[Недетерминированные конечные автоматы|НКА]] (&amp;lt;tex&amp;gt;FA&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Fa.png|Исходный НКА]]&lt;br /&gt;
# Первый шаг алгоритма (&amp;lt;tex&amp;gt;\operatorname{rev}(FA)&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Rfa.png|Первый шаг]]&lt;br /&gt;
# Второй шаг алгоритма (&amp;lt;tex&amp;gt;\operatorname{det}(\operatorname{rev}(FA))&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Drfa.png|Второй шаг]]&amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;\operatorname{det}&amp;lt;/tex&amp;gt; переименовывает состояния, после этого &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; всегда является начальным состоянием&lt;br /&gt;
# Третий шаг алгоритма (&amp;lt;tex&amp;gt;\operatorname{rev}(\operatorname{det}(\operatorname{rev}(FA)))&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Rdrfa.png|Третий шаг]]&amp;lt;br&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;
# Заключительный шаг алгоритма (&amp;lt;tex&amp;gt;\operatorname{det}(\operatorname{rev}(\operatorname{det}(\operatorname{rev}(FA))))&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Drdrfa.png|Заключительный шаг]]&lt;br /&gt;
&lt;br /&gt;
== Заключение ==&lt;br /&gt;
Самым эффективным алгоритмом минимизации принято считать [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]], который, как и прочие традиционные алгоритмы, работает только с [[Детерминированные_конечные_автоматы|ДКА]]. Его асимптотическое время выполнения зависит от логарифма исходных данных. С другой стороны очевидно, что алгоритм Бржозовского в худшем случае будет обладать экспоненциальным временем выполнения, ведь этого требует процедура детерминизации, выполняемая дважды. На практике же наблюдается парадокс, алгоритм Бржозовского во многих случаях опережает прочие подходы к минимизации, включая и [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]]. В работе&amp;lt;ref&amp;gt;[http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=A511A421C93DF66BDCC32A0E133D1F99?doi=10.1.1.59.8276&amp;amp;rep=rep1&amp;amp;type=pdf Deian Tabakov, Moshe Y. Vardi. Experimental evaluation of classical automata constructions]&amp;lt;/ref&amp;gt;, сравнивающей оба алгоритма, показано, что алгоритм Бржозовского оказывается эффективнее [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритма Хопкрофта]] для автоматов с большим числом переходов.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Минимизация ДКА, алгоритм за O(n^2) с построением пар различимых состояний]]&lt;br /&gt;
*[[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))]]&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [http://sovietov.com/txt/minfa/minfa.html Алгоритм Бржозовского для минимизации конечного автомата]&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55555</id>
		<title>Алгоритм Бржозовского</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B6%D0%BE%D0%B7%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B3%D0%BE&amp;diff=55555"/>
				<updated>2016-10-16T15:08:04Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Задача&lt;br /&gt;
|definition = &lt;br /&gt;
Пусть дан [[Детерминированные_конечные_автоматы|автомат]] &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;. Требуется построить автомат &amp;lt;tex&amp;gt;\mathcal{A}_{min}&amp;lt;/tex&amp;gt; с наименьшим количеством состояний, распознающий тот же язык, что и &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; {{---}} состояние автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q, s \in Q, T \subset Q, \delta : Q \times \Sigma \to Q \rangle&amp;lt;/tex&amp;gt;. &lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Правым языком''' (англ. ''right language'') {{---}} называется язык &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;, принимаемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}_{d}(q) = \langle \Sigma , Q , q , T , \delta \rangle&amp;lt;/tex&amp;gt;, полученным из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; путём добавления уникального начального состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 }}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Левым языком''' (англ. ''left language'') {{---}} называется язык &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, принимаемый автоматом &amp;lt;tex&amp;gt;\mathcal{A}_{g}(q) = \langle \Sigma , Q , q , T , \delta \rangle&amp;lt;/tex&amp;gt;, полученным из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; путём добавления уникального терминального состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 }}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=1&lt;br /&gt;
|statement=&lt;br /&gt;
Автомат является детерминированным тогда и только тогда, когда левые языки его состояний попарно не пересекаются.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратное слово''' &amp;lt;tex&amp;gt;r(u)&amp;lt;/tex&amp;gt; для слова &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; определяется следующим образом: &amp;lt;tex&amp;gt;r(\varepsilon) = \varepsilon&amp;lt;/tex&amp;gt; и если &amp;lt;tex&amp;gt;u = u_1 u_2 u_3 \dotsc u_p&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;r(u) = v_1 v_2 v_3 \dotsc v_p&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_i = u_{p - i + 1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный язык''' для языка &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; {{---}} язык &amp;lt;tex&amp;gt;r(L) = \{ u \mid r(u) \in L \}&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Обратный автомат''' для автомата &amp;lt;tex&amp;gt;\mathcal{A} = \langle \Sigma , Q , S , T , \delta \rangle&amp;lt;/tex&amp;gt; {{---}} автомат &amp;lt;tex&amp;gt;r(\mathcal{A}) = \langle \Sigma , Q , T , I , r(\delta) \rangle&amp;lt;/tex&amp;gt;, полученный из &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; сменой местами начальных и конечных состояний и сменой направлений переходов.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=&lt;br /&gt;
Если &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; распознает язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;r(\mathcal{A})&amp;lt;/tex&amp;gt; распознает &amp;lt;tex&amp;gt;r(L)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Утверждение&lt;br /&gt;
|about=3&lt;br /&gt;
|statement=&lt;br /&gt;
Если левый язык состояния &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;\mathcal{A}&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_g(q)&amp;lt;/tex&amp;gt;, тогда его левый язык в &amp;lt;tex&amp;gt;r(A)&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;L_d(q)&amp;lt;/tex&amp;gt;. Аналогично для правого языка &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Алгоритм==&lt;br /&gt;
===Описание===&lt;br /&gt;
Алгоритм минимизации конечных [[Детерминированные конечные автоматы|автоматов]] Бржозовского (Janusz A. (John) Brzozowski) выделяется, по крайней мере, следующими качествами:&lt;br /&gt;
&lt;br /&gt;
* Он элегантен и весьма оригинален.&lt;br /&gt;
* Он эффективен.&lt;br /&gt;
* Он работает даже с [[Недетерминированные конечные автоматы|недетерминированными конечными автоматами]].&lt;br /&gt;
&lt;br /&gt;
Обладая обычными процедурами обращения &amp;lt;tex&amp;gt;\operatorname{rev}&amp;lt;/tex&amp;gt; и детерминизации &amp;lt;tex&amp;gt;\operatorname{det}&amp;lt;/tex&amp;gt; конечного [[Детерминированные конечные автоматы|автомата]], мы, с помощью идеи Бржозовского, можем немедленно приступить к минимизации заданного [[Детерминированные конечные автоматы|автомата]]. Для этого надо дважды провести его через обе вышеуказанные процедуры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;mFA = \operatorname {det}(\operatorname{rev}(\operatorname{det}(\operatorname{rev}(FA))))&amp;lt;/tex&amp;gt;, где&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex&amp;gt;FA&amp;lt;/tex&amp;gt; это исходный КА,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\operatorname{rev}&amp;lt;/tex&amp;gt; это процедура обращения КА,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\operatorname{det}&amp;lt;/tex&amp;gt; это процедура детерминизации КА,&lt;br /&gt;
* &amp;lt;tex&amp;gt;mFA&amp;lt;/tex&amp;gt; это минимизированный КА.&lt;br /&gt;
&lt;br /&gt;
===Корректность===&lt;br /&gt;
Корректность алгоритма доказана в работе&amp;lt;ref&amp;gt;[http://www.researchgate.net/publication/255626373_Split_and_join_for_minimizing__Brzozowski's_algorithm Split and join for minimizing : Brzozowski's algorithm]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Пример работы==&lt;br /&gt;
# Исходный [[Недетерминированные конечные автоматы|НКА]] (&amp;lt;tex&amp;gt;FA&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Fa.png|Исходный НКА]]&lt;br /&gt;
# Первый шаг алгоритма (&amp;lt;tex&amp;gt;\operatorname{rev}(FA)&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Rfa.png|Первый шаг]]&lt;br /&gt;
# Второй шаг алгоритма (&amp;lt;tex&amp;gt;\operatorname{det}(\operatorname{rev}(FA))&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Drfa.png|Второй шаг]]&amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;\operatorname{det}&amp;lt;/tex&amp;gt; переименовывает состояния, после этого &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; всегда является начальным состоянием&lt;br /&gt;
# Третий шаг алгоритма (&amp;lt;tex&amp;gt;\operatorname{rev}(\operatorname{det}(\operatorname{rev}(FA)))&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Rdrfa.png|Третий шаг]]&amp;lt;br&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;
# Заключительный шаг алгоритма (&amp;lt;tex&amp;gt;\operatorname{det}(\operatorname{rev}(\operatorname{det}(\operatorname{rev}(FA))))&amp;lt;/tex&amp;gt;):&amp;lt;br&amp;gt;[[Файл:Drdrfa.png|Заключительный шаг]]&lt;br /&gt;
&lt;br /&gt;
== Заключение ==&lt;br /&gt;
Самым эффективным алгоритмом минимизации принято считать [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]], который, как и прочие традиционные алгоритмы, работает только с [[Детерминированные_конечные_автоматы|ДКА]]. Его асимптотическое время выполнения зависит от логарифма исходных данных. С другой стороны очевидно, что алгоритм Бржозовского в худшем случае будет обладать экспоненциальным временем выполнения, ведь этого требует процедура детерминизации, выполняемая дважды. На практике же наблюдается парадокс, алгоритм Бржозовского во многих случаях опережает прочие подходы к минимизации, включая и [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритм Хопкрофта]]. В работе&amp;lt;ref&amp;gt;[http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=A511A421C93DF66BDCC32A0E133D1F99?doi=10.1.1.59.8276&amp;amp;rep=rep1&amp;amp;type=pdf Deian Tabakov, Moshe Y. Vardi. Experimental evaluation of classical automata constructions]&amp;lt;/ref&amp;gt;, сравнивающей оба алгоритма, показано, что алгоритм Бржозовского оказывается эффективнее [[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))|алгоритма Хопкрофта]] для автоматов с большим числом переходов.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Минимизация ДКА, алгоритм за O(n^2) с построением пар различимых состояний]]&lt;br /&gt;
*[[Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n))]]&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [http://sovietov.com/txt/minfa/minfa.html Алгоритм Бржозовского для минимизации конечного автомата]&lt;br /&gt;
[[Категория: Теория формальных языков]]&lt;br /&gt;
[[Категория: Автоматы и регулярные языки]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Rake-Compress_%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D1%8C%D1%8F&amp;diff=54189</id>
		<title>Rake-Compress деревья</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Rake-Compress_%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D1%8C%D1%8F&amp;diff=54189"/>
				<updated>2016-05-22T17:33:42Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Задача, которая решается с помощью [[Link-Cut Tree|динамических деревьев]], формулируется следующим образом. Необходимо поддерживать лес деревьев и выполнять на нем следующие операции:&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{link(u, v)}&amp;lt;/tex&amp;gt; {{---}} добавить ребро &amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt;. Вершина &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; должна быть корнем некоторого дерева. Вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; должны находиться в разных деревьях,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{cut(u, v)}&amp;lt;/tex&amp;gt; {{---}} удалить ребро &amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt;. Ребро &amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt; должно присутствовать в графе,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{query()}&amp;lt;/tex&amp;gt; {{---}} некоторый запрос относительно структуры дерева.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Идея==&lt;br /&gt;
===Описание===&lt;br /&gt;
Пусть дано некоторое дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, для которого мы хотим выполнять описанные выше операции. Рассмотрим алгоритм ''сжатия дерева'' (англ. ''tree-contraction algorithm''), предложенный Миллером и Райфом. Алгоритм сжимает &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; в одну вершину путем применения операций &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt; в несколько раундов:&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; {{---}} все листья дерева сжимаются к своим родителям,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt; {{---}} выбирается и объединяется некоторое множество несмежных друг с другом вершин, имеющих ровно одного сына.&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;[[Файл:Rctree-rake.png|x180px|thumb|Операция &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt;]]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;[[Файл:Rctree-compress.png|x180px|thumb|Операция &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt;]]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сжатие дерева требует линейного времени и логарифмическое число раундов.&amp;lt;br&amp;gt;&lt;br /&gt;
Для выбора вершин, которые будут удалены во время операции &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt;, применяется следующий метод: для каждой вершины генерируется рандомный бит и вершина добавляется в множество удаляемых только в том случае, когда она имеет одного ребёнка, бит для неё равен &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, а для родителя и ребёнка равен &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Рассмотрим, как изменяется количество вершин в дереве после применения к нему операций &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;Разобьём все вершины дерева на три группы: &lt;br /&gt;
* &amp;lt;tex&amp;gt;T_0&amp;lt;/tex&amp;gt; {{---}} входящая степень равна нулю,&lt;br /&gt;
* &amp;lt;tex&amp;gt;T_1&amp;lt;/tex&amp;gt; {{---}} входящая степень равна одному,&lt;br /&gt;
* &amp;lt;tex&amp;gt;T_2&amp;lt;/tex&amp;gt; {{---}} входящая степень больше одного.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|about=1&lt;br /&gt;
|statement=&amp;lt;tex&amp;gt;T_2 \leqslant T_0 - 1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
Докажем по индукции по высоте дерева.&amp;lt;br&amp;gt;&lt;br /&gt;
* '''База &lt;br /&gt;
*: Для дерева из одной вершины утверждение верно.&lt;br /&gt;
* '''Переход&lt;br /&gt;
*: Пусть утверждение доказано для деревьев высоты меньше &amp;lt;tex&amp;gt;h&amp;lt;/tex&amp;gt;. Докажем для дерева высоты ровно &amp;lt;tex&amp;gt;h&amp;lt;/tex&amp;gt;. Рассмотрим степень корня:&amp;lt;br&amp;gt;&lt;br /&gt;
*:: Если корень имеет ровно одного ребенка, то переходим к случаю дерева высоты &amp;lt;tex&amp;gt;h - 1&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;Если у дерева несколько поддеревьев, то имеем:&amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;T_2 = 1 + \sum\limits_{u \in *: children(root)}T_2(u) \leqslant 1 + \sum\limits_{u \in children(root)}(T_0(u) - 1)&amp;lt;/tex&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;tex&amp;gt; \leqslant -1 + \sum\limits_{u \in children}T_0(u) \leqslant -1 + T_0 = T_0 - 1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
Заметим, что для леса деревьев лемма также справедлива.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=После применения операций &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt; к лесу, математическое ожидание количества вершин в нём не превосходит &amp;lt;tex&amp;gt;\dfrac{7}{8}&amp;lt;/tex&amp;gt; от их исходного числа.&lt;br /&gt;
|proof=Все листья будут удалены после операции &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt;, а каждая вершина, у которой ровно один сын, будет удалена с вероятностью &amp;lt;tex&amp;gt;\dfrac{1}{8}&amp;lt;/tex&amp;gt; после операции &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt; (так как мы рассматриваем три бита при выборе вершин и добавляем вершину в множество удаляемых только когда эти биты для родителя, вершины и ребёнка соответственно равны &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;).&amp;lt;br&amp;gt;&lt;br /&gt;
Таким образом математическое ожидание количества удаленных вершин &amp;lt;tex&amp;gt;\mathrm{deleted} = T_0 + \dfrac{T_1}{8}&amp;lt;/tex&amp;gt;. Из предыдущей леммы получаем:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{deleted} = \dfrac{1}{2} (T_0 + T_2) + \dfrac{1}{8} T_1 \geqslant \dfrac{1}{8} (T_0 + T_1 + T_2)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=Математическое ожидание количества операций &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt;, которые будут выполнены до полного сжатия дерева, равно &amp;lt;tex&amp;gt;O(\log{n})&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} общее количество вершин.&lt;br /&gt;
|proof=Из леммы 2 известно, что после каждой итерации применения операций &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt; число вершин в среднем уменьшается в константное число раз. Значит, количество итераций в среднем ограничено &amp;lt;tex&amp;gt;O(\log{n})&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;
[[Файл:RC_graph_example.png|400px|center|thumb|Исходное дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
[[Файл:RC_graph_contraction.png|350px|right|thumb|Алгоритм сжатия дерева &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
На каждом раунде сжатия (перечислены сверху вниз) удаляется множество вершин с использованием операций &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt;:&lt;br /&gt;
* Операция &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; удаляет лист и ребро, смежное с ним, сохраняя в соседях данные: метку удалённой вершины, вес удалённого ребра и данные о сжатых на предыдущих раундах вершинах.&lt;br /&gt;
* Операция &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt; удаляет вершины, имеющие ровно одного сына, и смежные им рёбра. Например, для вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; c сыном &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; и родителем &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; будут удалены рёбра &amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;(v, w)&amp;lt;/tex&amp;gt;. После этого добавляется ребро &amp;lt;tex&amp;gt;(u, w)&amp;lt;/tex&amp;gt;, а данные вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и удалённых рёбер (метка удалённой вершины, сохранённые данные и веса удалённых рёбер) сохраняются в соседние вершины. &lt;br /&gt;
&lt;br /&gt;
Например, для приведённого дерева на первом раунде сжатия применяется операция &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; для вершин &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; и операция &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt; для &amp;lt;tex&amp;gt;g&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Сжатие может быть рассмотрено как рекурсивная кластеризация дерева в один '''кластер'''. Изначально вершины и рёбра составляют базовый кластер. Операции &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt; формируют большие кластеры из нескольких меньших кластеров.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;На иллюстрации примера все кластеры (кроме базового) обозначены зелёными лепестками. Каждый кластер помечен заглавной буквой метки вершины, входящей в него. Например, кластер &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, полученный после сжатия вершины &amp;lt;tex&amp;gt;a&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;(a, b)&amp;lt;/tex&amp;gt;; сжатая вершина &amp;lt;tex&amp;gt;g&amp;lt;/tex&amp;gt; создает кластер &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;, содержащий эту вершину и рёбра &amp;lt;tex&amp;gt;(f, g)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;(g, h)&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;A&amp;lt;/tex&amp;gt; и ребро &amp;lt;tex&amp;gt;(b, c)&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;Представление сжатого дерева в виде кластеров:&lt;br /&gt;
[[Файл:RC_graph_clusters.png|400px|left|thumb|Кластеризованное дерево &amp;lt;tex&amp;gt;T&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;
{{Определение&lt;br /&gt;
|definition=Для кластера &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; скажем, что вершина &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; называется '''граничной вершиной''', если &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; смежная с вершинами не из &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. &lt;br /&gt;
}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition='''Граница кластера''' {{---}} множество граничных вершин кластера. &lt;br /&gt;
}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition='''Степень кластера''' {{---}} количество граничных вершин кластера.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&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;1&amp;lt;/tex&amp;gt;, а кластер &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; имеет границу &amp;lt;tex&amp;gt;\{f, g\}&amp;lt;/tex&amp;gt; и степень &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;. При сжатии дерева все кластеры, кроме последнего, имеют степени &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;. Свойством алгоритмом сжатия является то, что:&lt;br /&gt;
* операции &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; создают кластеры со степенью &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, &lt;br /&gt;
* операции &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt; создают кластеры со степенью &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* финальный кластер имеет степень &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Процесс сжатия исходного дерева может быть представлен в виде нового дерева, называемого &amp;lt;tex&amp;gt;\mathrm{RC-tree}&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;Пример такого дерева для рассматриваемого исходного дерева:&lt;br /&gt;
[[Файл:RC_graph_tree.png|500px|center|thumb|RC-tree для дерева &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Поскольку матожидание количества раундов {{---}} логарифм, то такое дерево будет сбалансированным.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{RC}&amp;lt;/tex&amp;gt; дерево можно использовать для ответа на динамические запросы для статического дерева. Для этого в &amp;lt;tex&amp;gt;\mathrm{RC}&amp;lt;/tex&amp;gt; дереве сохраним требуемую информацию (необходимо модифицировать для пересчёта информации операции &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt;) и используем обход для ответа на запросы. Поскольку дерево с большой вероятностью является сбалансированным, обход дерева также можно осуществить за логарифм.&amp;lt;br&amp;gt;&lt;br /&gt;
Для динамических деревьев, например, если доступны операции добавления/удаления ребра (операции &amp;lt;tex&amp;gt;\mathrm{link}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{cut}&amp;lt;/tex&amp;gt;), нужно эффективно перестраивать отдельные кластеры, пересчитывая данные. Для этого можно обновлять данные начиная с листа дерева, соответствующего обновляемой вершине в исходном дереве, и подниматься вверх.&lt;br /&gt;
&lt;br /&gt;
==Реализация==&lt;br /&gt;
===Хранение===&lt;br /&gt;
Для того, чтобы отвечать на запросы относительно структуры леса необходимо сохранить информацию о том, как происходил процесс сжатия леса. Для этого будем хранить таблицу, в каждой строке которой записана информация о структуре леса после выполнения операций. Каждая клетка таблицы будет хранить информацию о вершине после выполнения операций &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt;. Из информации будем сохранять родителя вершины, множество детей и метку, сжата ли вершина.&amp;lt;br&amp;gt;&lt;br /&gt;
Пример таблицы для следующей последовательности операций:&lt;br /&gt;
[[Файл:RC_tree_example.png|x200px|thumb|Пример выполнения операций.]]&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Шаг&lt;br /&gt;
! align=&amp;quot;center&amp;quot; | Операция&lt;br /&gt;
! &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;&lt;br /&gt;
! &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;&lt;br /&gt;
! &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;&lt;br /&gt;
! &amp;lt;tex&amp;gt;4&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 4&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt;&lt;br /&gt;
| Родитель: {{---}}&amp;lt;br&amp;gt;Дети: &amp;lt;tex&amp;gt;\emptyset&amp;lt;/tex&amp;gt;&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | {{---}} &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | {{---}}&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | {{---}}&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 3&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt;&lt;br /&gt;
| Родитель: {{---}}&amp;lt;br&amp;gt;Дети: &amp;lt;tex&amp;gt;\{3\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | {{---}}&lt;br /&gt;
| Родитель: &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;Дети: &amp;lt;tex&amp;gt;\emptyset&amp;lt;/tex&amp;gt;&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | {{---}}&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 2&lt;br /&gt;
| align=&amp;quot;center&amp;quot; |  &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt;&lt;br /&gt;
| Родитель: {{---}}&amp;lt;br&amp;gt;Дети: &amp;lt;tex&amp;gt;\{2\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
| Родитель: &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;Дети: &amp;lt;tex&amp;gt;\{3\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
| Родитель: &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;Дети: &amp;lt;tex&amp;gt;\emptyset&amp;lt;/tex&amp;gt;&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | {{---}}&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| &lt;br /&gt;
| Родитель: {{---}}&amp;lt;br&amp;gt;Дети: &amp;lt;tex&amp;gt;\{2\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
| Родитель: &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;Дети: &amp;lt;tex&amp;gt;\{3\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
| Родитель: &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;Дети: &amp;lt;tex&amp;gt;\{4\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
| Родитель: &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;Дети: &amp;lt;tex&amp;gt;\emptyset&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Для того, чтобы выбирать множество вершин для применения операции &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt; будем использовать следующий метод: для каждой вершины с помощью генератора псевдослучайных чисел выберем случайный бит. Вершина добавляется в множество, если у нее ровно один ребенок, она не является корнем и биты, которые были сгенерированы для нее, ребенка и родителя равны &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; соответственно.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим более подробно, как необходимо хранить клетки таблицы &amp;lt;tex&amp;gt;\mathrm{Rake-Compress}&amp;lt;/tex&amp;gt; дерева. Для вершины необходимо сохранить ее родителя, а также множество детей. Для того, чтобы обрабатывать каждую клетку таблицы за &amp;lt;tex&amp;gt;O(\log{n})&amp;lt;/tex&amp;gt;, нужно производить операции с множеством детей за &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;. &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;Рассмотрим, в каких случаях можно сжать вершину:&lt;br /&gt;
* если детей у вершины больше одного, то ее точно нельзя сжать, &lt;br /&gt;
* если у неё нет детей, то ее можно сжать только во время операции &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt;&lt;br /&gt;
* если у вершины один ребёнок, то её возможно сжать во время операции &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Чтобы определить, можно ли применить операцию &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt; к вершине, в том случае, когда у нее один ребёнок, нужно узнать, какой бит был сгенерирован на текущей итерации для ребёнка (один из трёх битов, генерируемых при операции &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt;). Для этого необходимо знать номер вершины-ребёнка. Значит, нам нужно определять, какие элементы находятся в множестве детей только в том случае, когда размер множества равен &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Поэтому, всю информацию о множестве можно хранить с помощью двух величин {{---}} хранить количество элементов в множестве и сумму их номеров. Поддерживая сумму номеров детей и их количество, можно эффективно узнавать номер вершины-ребёнка, когда это необходимо. Данная оптимизация позволяет за &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt; получать номер ребёнка и за &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt; обновлять множество детей.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Если вершина является корнем, то в качестве ее родителя будем хранить ее номер. Кроме того необходимо хранить изменения, которые произойдут с клеткой при переходе к следующему слою: будем хранить, кто должен стать новым родителем, на сколько изменится количество детей, а также как изменится сумма их номеров. Все это необходимо для того, чтобы обрабатывать каждую изменившуюся клетку за &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Псевдокод хранения клетки таблицы:&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{id}&amp;lt;/tex&amp;gt; {{---}} номер вершины,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{parent}&amp;lt;/tex&amp;gt; {{---}} родитель вершины,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{cntChild}&amp;lt;/tex&amp;gt; {{---}} количество детей вершины,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{sumChild}&amp;lt;/tex&amp;gt; {{---}} сумма номеров детей,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{newParent}&amp;lt;/tex&amp;gt; {{---}} новый родитель вершины после изменений, &lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{diffCntChild}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{diffSumChild}&amp;lt;/tex&amp;gt; {{---}} изменения, произведенные с полями &amp;lt;tex&amp;gt;\mathrm{cntChild}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{sumChild}&amp;lt;/tex&amp;gt; соответственно.&lt;br /&gt;
&lt;br /&gt;
 '''struct''' Cell''':'''&lt;br /&gt;
     '''int''' id, parent, cntChild, sumChild&lt;br /&gt;
     '''int''' newParent, diffCntChild, diffSumChild&lt;br /&gt;
     &lt;br /&gt;
     '''func''' applyChanges()''':'''&lt;br /&gt;
         parent = newParent&lt;br /&gt;
         sumChild += diffSumChild&lt;br /&gt;
         cntChild += diffCntChild&lt;br /&gt;
         diffCntChild = diffSumChild = 0&lt;br /&gt;
     &lt;br /&gt;
     '''func''' addChild(v: '''int''')''':'''&lt;br /&gt;
         diffCntChild++&lt;br /&gt;
         diffSumChild += v&lt;br /&gt;
  &lt;br /&gt;
     '''func''' removeChild(v: '''int''')''':'''&lt;br /&gt;
         diffCntChild--&lt;br /&gt;
         diffSumChild -= v&lt;br /&gt;
&lt;br /&gt;
Для хранения &amp;lt;tex&amp;gt;\mathrm{Rake-Compress}&amp;lt;/tex&amp;gt; дерева будем использовать следующие данные:&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{cells[]}&amp;lt;/tex&amp;gt; {{---}} список клеток, которые ей соответствуют, для каждой вершины,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{rand}&amp;lt;/tex&amp;gt; {{---}} генератор псевдослучайных чисел,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{time}&amp;lt;/tex&amp;gt; {{---}} счётчик количества примененных операций по изменению структуры леса,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{lastUpdateTime[]}&amp;lt;/tex&amp;gt; {{---}} массив, в котором для каждой вершины запишем номер последней операции, при обработки которой была изменена хотя бы одна клетка, которая соответствуют вершине: это позволит эффективно узнавать, была ли вершина уже помечена как поменявшаяся или нет.&lt;br /&gt;
&lt;br /&gt;
 '''struct''' RCTree(n: '''int''')''':'''&lt;br /&gt;
     '''RndGen''' rand = RandBitsGenerator()&lt;br /&gt;
     '''int''' time = 0&lt;br /&gt;
     '''for''' i = 0 '''to''' n&lt;br /&gt;
         lastUpdateTime[i] = 0&lt;br /&gt;
         cells[i] = []&lt;br /&gt;
&lt;br /&gt;
Кроме запросов о структуре леса, &amp;lt;tex&amp;gt;\mathrm{Rake-Compress}&amp;lt;/tex&amp;gt; деревья можно использовать для подсчета значений некоторых функций. Например, каждой вершине можно сопоставить некоторое значение и узнавать, чему равна сумма значений всех вершин, которые находятся в поддереве.&lt;br /&gt;
Для этого в клетках таблицы &amp;lt;tex&amp;gt;\mathrm{Rake-Compress}&amp;lt;/tex&amp;gt; дерева необходимо хранить не только состояние вершины, но и значение функции, посчитанной на части дерева, которое уже было сжато в вершину. Если функция является аддитивной, то ее пересчет аналогичен пересчету множества детей вершины. Так, если некоторая вершина сжимается к родителю, то в соответствующей родителю клетке необходимо обновить значение функции. При добавлении и удалении ребер необходимо в изменившихся клетках пересчитывать значение функции.&lt;br /&gt;
&lt;br /&gt;
===Построение===&lt;br /&gt;
Рассмотрим, как работает алгоритм построения &amp;lt;tex&amp;gt;\mathrm{Rake-Compress}&amp;lt;/tex&amp;gt; дерева. Будем строить таблицу по строкам. В каждый момент будем хранить множество вершин, которые еще не были сжаты, и перестраивать следующий слой. Также будем делать операции &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt; одновременно. Чтобы определить, нужно ли сжимать вершину, воспользуемся следующим алгоритмом:&lt;br /&gt;
 '''bool''' shouldRemoveVertex(c: '''Cell''', rand, layer: '''int''')''':'''&lt;br /&gt;
     '''if''' c.cntChild == 0&lt;br /&gt;
         '''return''' ''true''&lt;br /&gt;
     '''if''' c.cntChild &amp;gt; 1 '''or''' c.parent == c.id&lt;br /&gt;
         '''return''' ''false''&lt;br /&gt;
     '''if''' getCellForVertex(c.sumChild).cntChild == 0&lt;br /&gt;
         '''return''' ''false''&lt;br /&gt;
     '''if''' rand.getBit(c.id, layer) == 0 '''and''' rand.getBit(c.sumChild, layer) == 1 '''and''' rand.getBit(c.parent, layer) == 1:&lt;br /&gt;
         '''return''' ''true''&lt;br /&gt;
     '''return''' ''false''&lt;br /&gt;
&lt;br /&gt;
Таким образом, алгоритм построения дерева выглядит следующим образом:&lt;br /&gt;
 '''func''' build(parent: '''int[n]''')''':'''&lt;br /&gt;
     alive = &amp;lt;tex&amp;gt;\{0 \dots n - 1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
     '''int''' layer = 0&lt;br /&gt;
     '''for''' i = 0 '''to''' n                                              &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// заполним таблицу вершинами изначального дерева&amp;lt;/font&amp;gt;&lt;br /&gt;
         cells[i].add(Cell(parent[i]))&lt;br /&gt;
     '''while''' &amp;lt;tex&amp;gt;\mathrm{alive} \neq \emptyset&amp;lt;/tex&amp;gt;&lt;br /&gt;
         nextAlive = &amp;lt;tex&amp;gt;\emptyset&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''for''' &amp;lt;tex&amp;gt;v \in \mathrm{alive}&amp;lt;/tex&amp;gt;&lt;br /&gt;
             '''Cell''' c = getCellForVertex(v)                        &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// получить клетку таблицы, соответствующую вершине&amp;lt;/font&amp;gt;&lt;br /&gt;
             '''if''' shouldRemoveVertex(c, rand, layer)&lt;br /&gt;
                 '''if''' c.cntChild == 1&lt;br /&gt;
                     getCellForVertex(c.sumChild).newParent = c.parent&lt;br /&gt;
                     getCellForVertex(c.parent).addChild(c.sumChild)&lt;br /&gt;
                 '''if''' c.parent &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; v&lt;br /&gt;
                     getCellForVertex(c.parent).remove(v)&lt;br /&gt;
             '''else'''&lt;br /&gt;
                 nextAlive.add(v)&lt;br /&gt;
         alive = nextAlive&lt;br /&gt;
         '''for''' &amp;lt;tex&amp;gt;v \in \mathrm{alive}&amp;lt;/tex&amp;gt;&lt;br /&gt;
             '''Cell''' newCell = getCellForVertex(v).clone().applyChanges()&lt;br /&gt;
             cells[v].add(newCell)&lt;br /&gt;
         layer++&lt;br /&gt;
===Операции удаления и добавления ребра===&lt;br /&gt;
Как только некоторая вершина помечается как изменившаяся, отменим её действие на таблицу:&lt;br /&gt;
# Найдем момент времени, когда вершина сжимается к родителю. &lt;br /&gt;
# Рассмотрим, какие вершины поменяются при сжатии данной: это ее родитель (если он есть), а также сын (если он есть). Для каждой из этих вершин поменяем значения изменений, которые необходимо применить к состоянию. &lt;br /&gt;
# Пометим, что эти вершины поменялись на этом слое. Для этого на каждом слое будем хранить список вершин, которые на нем поменялись. А перед тем как обрабатывать очередной слой будем добавлять в множество изменившихся вершин вершины из соответствующего списка. &lt;br /&gt;
# Кроме удаления эффекта от изменившихся вершин также необходимо и добавить правильный эффект. Для этого будем для каждой из изменившихся вершин определять, как ее состояние меняется при переходе к следующему слою. Если вершина сжимается к ее родителю, то пометим родителя и ребенка (если он есть) и поменяем изменение, которое хранится в соответствующих клетках. А для пересчета состояния клеток воспользуемся значениями изменений, которые сохранены в клетках.&amp;lt;br&amp;gt;&lt;br /&gt;
Рассмотрим, что происходит с таблицей при изменении одного ребра. Основная идея заключается в том, чтобы научится пересчитывать все изменения таблицы за время пропорциональное их количеству. Для этого будем эффективно поддерживать множество изменившихся клеток. В момент, когда вершина помечается, как изменившаяся, найдем, как она влияет на таблицу и отменим это влияние. &amp;lt;br&amp;gt;Для начала необходимо найти момент времени, когда вершина сжимается. В этот момент она влияет на не более чем две вершины. Изменим значения &amp;lt;tex&amp;gt;\mathrm{cntChild}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;\mathrm{sumChild}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{newParent}&amp;lt;/tex&amp;gt; нужным образом. Также необходимо добавить эти вершины в множество изменившихся (в момент, когда будет обработан соответствующий слой). Поэтому, для каждого слоя еще будем хранить список вершин, которые должны быть помечены перед обработкой слоя.&amp;lt;br&amp;gt;Алгоритм обновления дерева:&lt;br /&gt;
 '''func''' changeTree(&amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt;: '''Edge''')''':'''&lt;br /&gt;
     time = time + 1&lt;br /&gt;
     affected = &amp;lt;tex&amp;gt;\emptyset&amp;lt;/tex&amp;gt;&lt;br /&gt;
     markAffected(u)                     &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// пусть из дерева было удалено ребро &amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
     markAffected(v)&lt;br /&gt;
     cells[u].parent = u&lt;br /&gt;
     cells[v].cntChild--&lt;br /&gt;
     cells[v].sumChild -= u&lt;br /&gt;
     '''int''' layer = 0&lt;br /&gt;
     '''while''' &amp;lt;tex&amp;gt;\mathrm{affected} \neq \emptyset&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''for''' &amp;lt;tex&amp;gt;v \in \mathrm{affectedOnLayer}&amp;lt;/tex&amp;gt;&lt;br /&gt;
             markAffected(v)&lt;br /&gt;
         '''for''' &amp;lt;tex&amp;gt;v \in \mathrm{affected}&amp;lt;/tex&amp;gt;&lt;br /&gt;
             '''Cell''' c = getCellForVertex(v)&lt;br /&gt;
             '''if''' shouldRemoveVertex(v)&lt;br /&gt;
                 cells[v].size = layer + 1&lt;br /&gt;
                 '''if''' c.cntChild == 1&lt;br /&gt;
                     getCellForVertex(c.sumChild).newParent = c.parent&lt;br /&gt;
                     getCellForVertex(c.parent).addChild(c.sumChild)&lt;br /&gt;
                     markAffected(c.sumChild)&lt;br /&gt;
                 '''if''' c.parent &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; v&lt;br /&gt;
                     getCellForVertex(c.parent).removeChild(v)&lt;br /&gt;
                     markAffected(c.parent)&lt;br /&gt;
                 affected.remove(v)&lt;br /&gt;
         '''for''' &amp;lt;tex&amp;gt;v \in \mathrm{affected}&amp;lt;/tex&amp;gt;&lt;br /&gt;
             '''Cell''' newCell = getCellForVertex(v).clone().applyChanges()&lt;br /&gt;
             cells[v][layer + 1] = newCell&lt;br /&gt;
         layer++&lt;br /&gt;
 &lt;br /&gt;
 '''func''' markAffected(v: '''int''')''':'''               &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// пометить вершину как изменившуюся&amp;lt;/font&amp;gt;&lt;br /&gt;
    '''if''' lastUpdateTime[v] == time&lt;br /&gt;
        '''return'''                            &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// вершина уже помечена&amp;lt;/font&amp;gt;&lt;br /&gt;
    lastUpdateTime[v] = time&lt;br /&gt;
    affected.add(v)&lt;br /&gt;
    removeEffectOfVertex(v)&lt;br /&gt;
 &lt;br /&gt;
 '''func''' removeEffectOfVertex(v: '''int''')''':'''       &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// удалить отметку о том, что вершина была помечена изменившийся&amp;lt;/font&amp;gt;&lt;br /&gt;
    '''int''' layer = cells[v].size&lt;br /&gt;
    '''Cell''' c = cells[v][layer]&lt;br /&gt;
    '''if''' c.parent == v&lt;br /&gt;
        '''return'''&lt;br /&gt;
    cells[c].parent.removeChild(v)&lt;br /&gt;
    '''if''' c.cntChild == 1&lt;br /&gt;
        cells[c.parent].addChild(c.sumChild)&lt;br /&gt;
        cells[c.sumChild].newParent = v&lt;br /&gt;
&lt;br /&gt;
==Сравнение с Link-Cut Tree==&lt;br /&gt;
Для Link-Cut деревьев (основанных на [[Splay-дерево|splay-деревьях]]), как и для &amp;lt;tex&amp;gt;\mathrm{Rake-Compress}&amp;lt;/tex&amp;gt; деревьев, время работы операций &amp;lt;tex&amp;gt;\mathrm{link}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{cut}&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;O(\log{n})&amp;lt;/tex&amp;gt;. В реальности &amp;lt;tex&amp;gt;\mathrm{RC}&amp;lt;/tex&amp;gt; деревья оказываются медленнее, чем &amp;lt;tex&amp;gt;\mathrm{LC}&amp;lt;/tex&amp;gt; деревья. &amp;lt;br&amp;gt;&lt;br /&gt;
Отличительной особенностью &amp;lt;tex&amp;gt;\mathrm{RC}&amp;lt;/tex&amp;gt; деревьев является возможность параллельного построения: операции &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt; можно выполнять параллельно для всех вершин. Если предположить, что множество детей можно пересчитывать за &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\mathrm{Rake-Compress}&amp;lt;/tex&amp;gt; дерево можно построить за &amp;lt;tex&amp;gt;O(\log{n})&amp;lt;/tex&amp;gt; в модели PRAM&amp;lt;ref&amp;gt;[https://en.wikipedia.org/wiki/Parallel_random-access_machine Wikipedia {{---}} Parallel random-access machine]&amp;lt;/ref&amp;gt; в случае наличия &amp;lt;tex&amp;gt;\Omega(n)&amp;lt;/tex&amp;gt; процессоров.&amp;lt;br&amp;gt;&lt;br /&gt;
Кроме этого, &amp;lt;tex&amp;gt;\mathrm{Rake-Compress}&amp;lt;/tex&amp;gt; деревья могут оказаться полезными, если необходимо пересчитывать значения не на путях, а на поддеревьях.&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
* [[Link-Cut Tree]]&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Parallel_Tree_Contraction Wikipedia {{---}} Parallel Tree Contraction]&lt;br /&gt;
* [https://github.com/BorysMinaiev/bachelor/blob/master/thesis_v2.pdf Б. Ю. Минаев {{---}} Реализация динамических Rake-Compress деревьев в случае отсутствия ограничения на степени вершин]&lt;br /&gt;
* [http://www.cs.cmu.edu/~jvittes/rc-trees Acar, Blelloch, and Vittes {{---}} RC-Tree implementation]&lt;br /&gt;
* [http://www.cs.princeton.edu/~rwerneck/papers/Wer06-dissertation.pdf R. Werneck {{---}} Design and Analysis of Data Structures for Dynamic Trees]&lt;br /&gt;
* G. L. Miller, J. H. Reif {{---}} Parallel Tree Contraction, Journal of Advances in Computer Research Volume 5, 1989&lt;br /&gt;
* Umit A. Acar, Guy E. Blelloch, Jorge L. Vittes {{---}} An Experimental Analysis of Change Propagation in Dynamic Trees, 1-2005&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Задача о наименьшем общем предке]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Rake-Compress_%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D1%8C%D1%8F&amp;diff=54186</id>
		<title>Rake-Compress деревья</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Rake-Compress_%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D1%8C%D1%8F&amp;diff=54186"/>
				<updated>2016-05-22T17:10:09Z</updated>
		
		<summary type="html">&lt;p&gt;Kiryukhinv: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Задача, которая решается с помощью [[Link-Cut Tree|динамических деревьев]], формулируется следующим образом. Необходимо поддерживать лес деревьев и выполнять на нем следующие операции:&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{link(u, v)}&amp;lt;/tex&amp;gt; {{---}} добавить ребро &amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt;. Вершина &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; должна быть корнем некоторого дерева. Вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; должны находиться в разных деревьях,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{cut(u, v)}&amp;lt;/tex&amp;gt; {{---}} удалить ребро &amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt;. Ребро &amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt; должно присутствовать в графе,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{query()}&amp;lt;/tex&amp;gt; {{---}} некоторый запрос относительно структуры дерева.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Идея==&lt;br /&gt;
===Описание===&lt;br /&gt;
Пусть дано некоторое дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, для которого мы хотим выполнять описанные выше операции. Рассмотрим алгоритм ''сжатия дерева'' (англ. ''tree-contraction algorithm''), предложенный Миллером и Райфом. Алгоритм сжимает &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; в одну вершину путем применения операций &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt; в несколько раундов:&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; {{---}} все листья дерева сжимаются к своим родителям,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt; {{---}} выбирается и объединяется некоторое множество несмежных друг с другом вершин, имеющих ровно одного сына.&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;[[Файл:Rctree-rake.png|x180px|thumb|Операция &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt;]]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;[[Файл:Rctree-compress.png|x180px|thumb|Операция &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt;]]&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сжатие дерева требует линейного времени и логарифмическое число раундов.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим, как изменяется количество вершин в дереве после применения к нему операций &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;Разобьём все вершины дерева на три группы: &lt;br /&gt;
* &amp;lt;tex&amp;gt;T_0&amp;lt;/tex&amp;gt; {{---}} входящая степень равна нулю,&lt;br /&gt;
* &amp;lt;tex&amp;gt;T_1&amp;lt;/tex&amp;gt; {{---}} входящая степень равна одному,&lt;br /&gt;
* &amp;lt;tex&amp;gt;T_2&amp;lt;/tex&amp;gt; {{---}} входящая степень больше одного.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|about=1&lt;br /&gt;
|statement=&amp;lt;tex&amp;gt;T_2 \leqslant T_0 - 1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
Докажем по индукции по высоте дерева.&amp;lt;br&amp;gt;&lt;br /&gt;
* '''База &lt;br /&gt;
*: Для дерева из одной вершины утверждение верно.&lt;br /&gt;
* '''Переход&lt;br /&gt;
*: Пусть утверждение доказано для деревьев высоты меньше &amp;lt;tex&amp;gt;h&amp;lt;/tex&amp;gt;. Докажем для дерева высоты ровно &amp;lt;tex&amp;gt;h&amp;lt;/tex&amp;gt;. Рассмотрим степень корня:&amp;lt;br&amp;gt;&lt;br /&gt;
*:: Если корень имеет ровно одного ребенка, то переходим к случаю дерева высоты &amp;lt;tex&amp;gt;h - 1&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;Если у дерева несколько поддеревьев, то имеем:&amp;lt;br&amp;gt;&amp;lt;tex&amp;gt;T_2 = 1 + \sum\limits_{u \in *: children(root)}T_2(u) \leqslant 1 + \sum\limits_{u \in children(root)}(T_0(u) - 1)&amp;lt;/tex&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;tex&amp;gt; \leqslant -1 + \sum\limits_{u \in children}T_0(u) \leqslant -1 + T_0 = T_0 - 1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
Заметим, что для леса деревьев лемма также справедлива.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=После применения операций &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt; к лесу, математическое ожидание количества вершин в нём не превосходит &amp;lt;tex&amp;gt;\dfrac{7}{8}&amp;lt;/tex&amp;gt; от их исходного числа.&lt;br /&gt;
|proof=Математическое ожидание количества удаленных вершин &amp;lt;tex&amp;gt;\mathrm{deleted} = T_0 + \dfrac{T_1}{8}&amp;lt;/tex&amp;gt; (так как все листья будут удалены после операции &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt;, а каждая вершина, у которой ровно один сын, будет удалена с вероятностью &amp;lt;tex&amp;gt;\dfrac{1}{8}&amp;lt;/tex&amp;gt; после операции &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt;). Из предыдущей леммы получаем:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{deleted} = \dfrac{1}{2} (T_0 + T_2) + \dfrac{1}{8} T_1 \geqslant \dfrac{1}{8} (T_0 + T_1 + T_2)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=Математическое ожидание количества операций &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt;, которые будут выполнены до полного сжатия дерева, равно &amp;lt;tex&amp;gt;O(\log{n})&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} общее количество вершин.&lt;br /&gt;
|proof=Из леммы 2 известно, что после каждой итерации применения операций &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt; число вершин в среднем уменьшается в константное число раз. Значит, количество итераций в среднем ограничено &amp;lt;tex&amp;gt;O(\log{n})&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;
[[Файл:RC_graph_example.png|400px|center|thumb|Исходное дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
[[Файл:RC_graph_contraction.png|350px|right|thumb|Алгоритм сжатия дерева &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
На каждом раунде сжатия (перечислены сверху вниз) удаляется множество вершин с использованием операций &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt;:&lt;br /&gt;
* Операция &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; удаляет лист и ребро, смежное с ним, сохраняя в соседях данные: метку удалённой вершины, вес удалённого ребра и данные о сжатых на предыдущих раундах вершинах.&lt;br /&gt;
* Операция &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt; удаляет вершины, имеющие ровно одного сына, и смежные им рёбра. Например, для вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; c сыном &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; и родителем &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; будут удалены рёбра &amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;(v, w)&amp;lt;/tex&amp;gt;. После этого добавляется ребро &amp;lt;tex&amp;gt;(u, w)&amp;lt;/tex&amp;gt;, а данные вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и удалённых рёбер (метка удалённой вершины, сохранённые данные и веса удалённых рёбер) сохраняются в соседние вершины.&lt;br /&gt;
&lt;br /&gt;
Например, для приведённого дерева на первом раунде сжатия применяется операция &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; для вершин &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; и операция &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt; для &amp;lt;tex&amp;gt;g&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Сжатие может быть рассмотрено как рекурсивная кластеризация дерева в один '''кластер'''. Изначально вершины и рёбра составляют базовый кластер. Операции &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt; формируют большие кластеры из нескольких меньших кластеров.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;На иллюстрации примера все кластеры (кроме базового) обозначены зелёными лепестками. Каждый кластер помечен заглавной буквой метки вершины, входящей в него. Например, кластер &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, полученный после сжатия вершины &amp;lt;tex&amp;gt;a&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;(a, b)&amp;lt;/tex&amp;gt;; сжатая вершина &amp;lt;tex&amp;gt;g&amp;lt;/tex&amp;gt; создает кластер &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;, содержащий эту вершину и рёбра &amp;lt;tex&amp;gt;(f, g)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;(g, h)&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;A&amp;lt;/tex&amp;gt; и ребро &amp;lt;tex&amp;gt;(b, c)&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;Представление сжатого дерева в виде кластеров:&lt;br /&gt;
[[Файл:RC_graph_clusters.png|400px|left|thumb|Кластеризованное дерево &amp;lt;tex&amp;gt;T&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;
{{Определение&lt;br /&gt;
|definition=Для кластера &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; скажем, что вершина &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; называется '''граничной вершиной''', если &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; смежная с вершинами не из &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. &lt;br /&gt;
}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition='''Граница кластера''' {{---}} множество граничных вершин кластера. &lt;br /&gt;
}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition='''Степень кластера''' {{---}} количество граничных вершин кластера.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&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;1&amp;lt;/tex&amp;gt;, а кластер &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; имеет границу &amp;lt;tex&amp;gt;\{f, g\}&amp;lt;/tex&amp;gt; и степень &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;. При сжатии дерева все кластеры, кроме последнего, имеют степени &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;. Свойством алгоритмом сжатия является то, что:&lt;br /&gt;
* операции &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; создают кластеры со степенью &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, &lt;br /&gt;
* операции &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt; создают кластеры со степенью &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* финальный кластер имеет степень &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Процесс сжатия исходного дерева может быть представлен в виде нового дерева, называемого &amp;lt;tex&amp;gt;\mathrm{RC-tree}&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;Пример такого дерева для рассматриваемого исходного дерева:&lt;br /&gt;
[[Файл:RC_graph_tree.png|500px|center|thumb|RC-tree для дерева &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Поскольку матожидание количества раундов {{---}} логарифм, то такое дерево будет сбалансированным.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{RC}&amp;lt;/tex&amp;gt; дерево можно использовать для ответа на динамические запросы для статического дерева. Для этого в &amp;lt;tex&amp;gt;\mathrm{RC}&amp;lt;/tex&amp;gt; дереве сохраним требуемую информацию (необходимо модифицировать для пересчёта информации операции &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt;) и используем обход для ответа на запросы. Поскольку дерево с большой вероятностью является сбалансированным, обход дерева также можно осуществить за логарифм.&amp;lt;br&amp;gt;&lt;br /&gt;
Для динамических деревьев, например, если доступны операции добавления/удаления ребра (операции &amp;lt;tex&amp;gt;\mathrm{link}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{cut}&amp;lt;/tex&amp;gt;), нужно эффективно перестраивать отдельные кластеры, пересчитывая данные. Для этого можно обновлять данные начиная с листа дерева, соответствующего обновляемой вершине в исходном дереве, и подниматься вверх.&lt;br /&gt;
&lt;br /&gt;
==Реализация==&lt;br /&gt;
===Хранение===&lt;br /&gt;
Для того, чтобы отвечать на запросы относительно структуры леса необходимо сохранить информацию о том, как происходил процесс сжатия леса. Для этого будем хранить таблицу, в каждой строке которой записана информация о структуре леса после выполнения операций. Каждая клетка таблицы будет хранить информацию о вершине после выполнения операций &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt;. Из информации будем сохранять родителя вершины, множество детей и метку, сжата ли вершина.&amp;lt;br&amp;gt;&lt;br /&gt;
Пример таблицы для следующей последовательности операций:&lt;br /&gt;
[[Файл:RC_tree_example.png|x200px|thumb|Пример выполнения операций.]]&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Шаг&lt;br /&gt;
! align=&amp;quot;center&amp;quot; | Операция&lt;br /&gt;
! &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;&lt;br /&gt;
! &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;&lt;br /&gt;
! &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;&lt;br /&gt;
! &amp;lt;tex&amp;gt;4&amp;lt;/tex&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 4&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt;&lt;br /&gt;
| Родитель: {{---}}&amp;lt;br&amp;gt;Дети: &amp;lt;tex&amp;gt;\emptyset&amp;lt;/tex&amp;gt;&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | {{---}} &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | {{---}}&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | {{---}}&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 3&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt;&lt;br /&gt;
| Родитель: {{---}}&amp;lt;br&amp;gt;Дети: &amp;lt;tex&amp;gt;\{3\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | {{---}}&lt;br /&gt;
| Родитель: &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;Дети: &amp;lt;tex&amp;gt;\emptyset&amp;lt;/tex&amp;gt;&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | {{---}}&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 2&lt;br /&gt;
| align=&amp;quot;center&amp;quot; |  &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt;&lt;br /&gt;
| Родитель: {{---}}&amp;lt;br&amp;gt;Дети: &amp;lt;tex&amp;gt;\{2\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
| Родитель: &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;Дети: &amp;lt;tex&amp;gt;\{3\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
| Родитель: &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;Дети: &amp;lt;tex&amp;gt;\emptyset&amp;lt;/tex&amp;gt;&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | {{---}}&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| &lt;br /&gt;
| Родитель: {{---}}&amp;lt;br&amp;gt;Дети: &amp;lt;tex&amp;gt;\{2\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
| Родитель: &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;Дети: &amp;lt;tex&amp;gt;\{3\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
| Родитель: &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;Дети: &amp;lt;tex&amp;gt;\{4\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
| Родитель: &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;&amp;lt;br&amp;gt;Дети: &amp;lt;tex&amp;gt;\emptyset&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Для того, чтобы выбирать множество вершин для применения операции &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt; будем использовать следующий метод: для каждой вершины с помощью генератора псевдослучайных чисел выберем случайный бит. Вершина добавляется в множество, если у нее ровно один ребенок, она не является корнем и биты, которые были сгенерированы для нее, ребенка и родителя равны &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; соответственно.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим более подробно, как необходимо хранить клетки таблицы &amp;lt;tex&amp;gt;\mathrm{Rake-Compress}&amp;lt;/tex&amp;gt; дерева. Для вершины необходимо сохранить ее родителя, а также множество детей. Для того, чтобы обрабатывать каждую клетку таблицы за &amp;lt;tex&amp;gt;O(\log{n})&amp;lt;/tex&amp;gt;, нужно производить операции с множеством детей за &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;. &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;Рассмотрим, в каких случаях можно сжать вершину:&lt;br /&gt;
* если детей у вершины больше одного, то ее точно нельзя сжать, &lt;br /&gt;
* если у неё нет детей, то ее можно сжать только во время операции &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt;&lt;br /&gt;
* если у вершины один ребёнок, то её возможно сжать во время операции &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt;. &lt;br /&gt;
Чтобы определить, можно ли применить операцию &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt; к вершине, в том случае, когда у нее один ребёнок, нужно узнать, какой бит был сгенерирован на текущей итерации для ребёнка (один из трёх битов, генерируемых при операции &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt;). Для этого необходимо знать номер вершины-ребёнка. Значит, нам нужно определять, какие элементы находятся в множестве детей только в том случае, когда размер множества равен &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Поэтому, всю информацию о множестве можно хранить с помощью двух величин {{---}} хранить количество элементов в множестве и сумму их номеров. Поддерживая сумму номеров детей и их количество, можно эффективно узнавать номер вершины-ребёнка, когда это необходимо. Данная оптимизация позволяет за &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt; получать номер ребёнка и за &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt; обновлять множество детей.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Если вершина является корнем, то в качестве ее родителя будем хранить ее номер. Кроме того необходимо хранить изменения, которые произойдут с клеткой при переходе к следующему слою: будем хранить, кто должен стать новым родителем, на сколько изменится количество детей, а также как изменится сумма их номеров. Все это необходимо для того, чтобы обрабатывать каждую изменившуюся клетку за &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Псевдокод хранения клетки таблицы:&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{id}&amp;lt;/tex&amp;gt; {{---}} номер вершины,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{parent}&amp;lt;/tex&amp;gt; {{---}} родитель вершины,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{cntChild}&amp;lt;/tex&amp;gt; {{---}} количество детей вершины,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{sumChild}&amp;lt;/tex&amp;gt; {{---}} сумма номеров детей,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{newParent}&amp;lt;/tex&amp;gt; {{---}} новый родитель вершины после изменений, &lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{diffCntChild}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{diffSumChild}&amp;lt;/tex&amp;gt; {{---}} изменения, произведенные с полями &amp;lt;tex&amp;gt;\mathrm{cntChild}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{sumChild}&amp;lt;/tex&amp;gt; соответственно.&lt;br /&gt;
&lt;br /&gt;
 '''struct''' Cell''':'''&lt;br /&gt;
     '''int''' id, parent, cntChild, sumChild&lt;br /&gt;
     '''int''' newParent, diffCntChild, diffSumChild&lt;br /&gt;
     &lt;br /&gt;
     '''func''' applyChanges()''':'''&lt;br /&gt;
         parent = newParent&lt;br /&gt;
         sumChild += diffSumChild&lt;br /&gt;
         cntChild += diffCntChild&lt;br /&gt;
         diffCntChild = diffSumChild = 0&lt;br /&gt;
     &lt;br /&gt;
     '''func''' addChild(v: '''int''')''':'''&lt;br /&gt;
         diffCntChild++&lt;br /&gt;
         diffSumChild += v&lt;br /&gt;
  &lt;br /&gt;
     '''func''' removeChild(v: '''int''')''':'''&lt;br /&gt;
         diffCntChild--&lt;br /&gt;
         diffSumChild -= v&lt;br /&gt;
&lt;br /&gt;
Для хранения &amp;lt;tex&amp;gt;\mathrm{Rake-Compress}&amp;lt;/tex&amp;gt; дерева будем использовать следующие данные:&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{cells[]}&amp;lt;/tex&amp;gt; {{---}} список клеток, которые ей соответствуют, для каждой вершины,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{rand}&amp;lt;/tex&amp;gt; {{---}} генератор псевдослучайных чисел,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{time}&amp;lt;/tex&amp;gt; {{---}} счётчик количества примененных операций по изменению структуры леса,&lt;br /&gt;
* &amp;lt;tex&amp;gt;\mathrm{lastUpdateTime[]}&amp;lt;/tex&amp;gt; {{---}} массив, в котором для каждой вершины запишем номер последней операции, при обработки которой была изменена хотя бы одна клетка, которая соответствуют вершине: это позволит эффективно узнавать, была ли вершина уже помечена как поменявшаяся или нет.&lt;br /&gt;
&lt;br /&gt;
 '''struct''' RCTree(n: '''int''')''':'''&lt;br /&gt;
     '''RndGen''' rand = RandBitsGenerator()&lt;br /&gt;
     '''int''' time = 0&lt;br /&gt;
     '''for''' i = 0 '''to''' n&lt;br /&gt;
         lastUpdateTime[i] = 0&lt;br /&gt;
         cells[i] = []&lt;br /&gt;
&lt;br /&gt;
Кроме запросов о структуре леса, &amp;lt;tex&amp;gt;\mathrm{Rake-Compress}&amp;lt;/tex&amp;gt; деревья можно использовать для подсчета значений некоторых функций. Например, каждой вершине можно сопоставить некоторое значение и узнавать, чему равна сумма значений всех вершин, которые находятся в поддереве.&lt;br /&gt;
Для этого в клетках таблицы &amp;lt;tex&amp;gt;\mathrm{Rake-Compress}&amp;lt;/tex&amp;gt; дерева необходимо хранить не только состояние вершины, но и значение функции, посчитанной на части дерева, которое уже было сжато в вершину. Если функция является аддитивной, то ее пересчет аналогичен пересчету множества детей вершины. Так, если некоторая вершина сжимается к родителю, то в соответствующей родителю клетке необходимо обновить значение функции. При добавлении и удалении ребер необходимо в изменившихся клетках пересчитывать значение функции.&lt;br /&gt;
&lt;br /&gt;
===Построение===&lt;br /&gt;
Рассмотрим, как работает алгоритм построения &amp;lt;tex&amp;gt;\mathrm{Rake-Compress}&amp;lt;/tex&amp;gt; дерева. Будем строить таблицу по строкам. В каждый момент будем хранить множество вершин, которые еще не были сжаты, и перестраивать следующий слой. Также будем делать операции &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt; одновременно. Чтобы определить, нужно ли сжимать вершину, воспользуемся следующим алгоритмом:&lt;br /&gt;
 '''bool''' shouldRemoveVertex(c: '''Cell''', rand, layer: '''int''')''':'''&lt;br /&gt;
     '''if''' c.cntChild == 0&lt;br /&gt;
         '''return''' ''true''&lt;br /&gt;
     '''if''' c.cntChild &amp;gt; 1 '''or''' c.parent == c.id&lt;br /&gt;
         '''return''' ''false''&lt;br /&gt;
     '''if''' getCellForVertex(c.sumChild).cntChild == 0&lt;br /&gt;
         '''return''' ''false''&lt;br /&gt;
     '''if''' rand.getBit(c.id, layer) == 0 '''and''' rand.getBit(c.sumChild, layer) == 1 '''and''' rand.getBit(c.parent, layer) == 1:&lt;br /&gt;
         '''return''' ''true''&lt;br /&gt;
     '''return''' ''false''&lt;br /&gt;
&lt;br /&gt;
Таким образом, алгоритм построения дерева выглядит следующим образом:&lt;br /&gt;
 '''func''' build(parent: '''int[n]''')''':'''&lt;br /&gt;
     alive = &amp;lt;tex&amp;gt;\{0 \dots n - 1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
     '''int''' layer = 0&lt;br /&gt;
     '''for''' i = 0 '''to''' n                                              &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// заполним таблицу вершинами изначального дерева&amp;lt;/font&amp;gt;&lt;br /&gt;
         cells[i].add(Cell(parent[i]))&lt;br /&gt;
     '''while''' &amp;lt;tex&amp;gt;\mathrm{alive} \neq \emptyset&amp;lt;/tex&amp;gt;&lt;br /&gt;
         nextAlive = &amp;lt;tex&amp;gt;\emptyset&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''for''' &amp;lt;tex&amp;gt;v \in \mathrm{alive}&amp;lt;/tex&amp;gt;&lt;br /&gt;
             '''Cell''' c = getCellForVertex(v)                        &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// получить клетку таблицы, соответствующую вершине&amp;lt;/font&amp;gt;&lt;br /&gt;
             '''if''' shouldRemoveVertex(c, rand, layer)&lt;br /&gt;
                 '''if''' c.cntChild == 1&lt;br /&gt;
                     getCellForVertex(c.sumChild).newParent = c.parent&lt;br /&gt;
                     getCellForVertex(c.parent).addChild(c.sumChild)&lt;br /&gt;
                 '''if''' c.parent &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; v&lt;br /&gt;
                     getCellForVertex(c.parent).remove(v)&lt;br /&gt;
             '''else'''&lt;br /&gt;
                 nextAlive.add(v)&lt;br /&gt;
         alive = nextAlive&lt;br /&gt;
         '''for''' &amp;lt;tex&amp;gt;v \in \mathrm{alive}&amp;lt;/tex&amp;gt;&lt;br /&gt;
             '''Cell''' newCell = getCellForVertex(v).clone().applyChanges()&lt;br /&gt;
             cells[v].add(newCell)&lt;br /&gt;
         layer++&lt;br /&gt;
===Операции удаления и добавления ребра===&lt;br /&gt;
Как только некоторая вершина помечается как изменившаяся, отменим её действие на таблицу:&lt;br /&gt;
# Найдем момент времени, когда вершина сжимается к родителю. &lt;br /&gt;
# Рассмотрим, какие вершины поменяются при сжатии данной: это ее родитель (если он есть), а также сын (если он есть). Для каждой из этих вершин поменяем значения изменений, которые необходимо применить к состоянию. &lt;br /&gt;
# Пометим, что эти вершины поменялись на этом слое. Для этого на каждом слое будем хранить список вершин, которые на нем поменялись. А перед тем как обрабатывать очередной слой будем добавлять в множество изменившихся вершин вершины из соответствующего списка. &lt;br /&gt;
# Кроме удаления эффекта от изменившихся вершин также необходимо и добавить правильный эффект. Для этого будем для каждой из изменившихся вершин определять, как ее состояние меняется при переходе к следующему слою. Если вершина сжимается к ее родителю, то пометим родителя и ребенка (если он есть) и поменяем изменение, которое хранится в соответствующих клетках. А для пересчета состояния клеток воспользуемся значениями изменений, которые сохранены в клетках.&amp;lt;br&amp;gt;&lt;br /&gt;
Рассмотрим, что происходит с таблицей при изменении одного ребра. Основная идея заключается в том, чтобы научится пересчитывать все изменения таблицы за время пропорциональное их количеству. Для этого будем эффективно поддерживать множество изменившихся клеток. В момент, когда вершина помечается, как изменившаяся, найдем, как она влияет на таблицу и отменим это влияние. &amp;lt;br&amp;gt;Для начала необходимо найти момент времени, когда вершина сжимается. В этот момент она влияет на не более чем две вершины. Изменим значения &amp;lt;tex&amp;gt;\mathrm{cntChild}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;\mathrm{sumChild}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{newParent}&amp;lt;/tex&amp;gt; нужным образом. Также необходимо добавить эти вершины в множество изменившихся (в момент, когда будет обработан соответствующий слой). Поэтому, для каждого слоя еще будем хранить список вершин, которые должны быть помечены перед обработкой слоя.&amp;lt;br&amp;gt;Алгоритм обновления дерева:&lt;br /&gt;
 '''func''' changeTree(&amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt;: '''Edge''')''':'''&lt;br /&gt;
     time = time + 1&lt;br /&gt;
     affected = &amp;lt;tex&amp;gt;\emptyset&amp;lt;/tex&amp;gt;&lt;br /&gt;
     markAffected(u)                     &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// пусть из дерева было удалено ребро &amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
     markAffected(v)&lt;br /&gt;
     cells[u].parent = u&lt;br /&gt;
     cells[v].cntChild--&lt;br /&gt;
     cells[v].sumChild -= u&lt;br /&gt;
     '''int''' layer = 0&lt;br /&gt;
     '''while''' &amp;lt;tex&amp;gt;\mathrm{affected} \neq \emptyset&amp;lt;/tex&amp;gt;&lt;br /&gt;
         '''for''' &amp;lt;tex&amp;gt;v \in \mathrm{affectedOnLayer}&amp;lt;/tex&amp;gt;&lt;br /&gt;
             markAffected(v)&lt;br /&gt;
         '''for''' &amp;lt;tex&amp;gt;v \in \mathrm{affected}&amp;lt;/tex&amp;gt;&lt;br /&gt;
             '''Cell''' c = getCellForVertex(v)&lt;br /&gt;
             '''if''' shouldRemoveVertex(v)&lt;br /&gt;
                 cells[v].size = layer + 1&lt;br /&gt;
                 '''if''' c.cntChild == 1&lt;br /&gt;
                     getCellForVertex(c.sumChild).newParent = c.parent&lt;br /&gt;
                     getCellForVertex(c.parent).addChild(c.sumChild)&lt;br /&gt;
                     markAffected(c.sumChild)&lt;br /&gt;
                 '''if''' c.parent &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; v&lt;br /&gt;
                     getCellForVertex(c.parent).removeChild(v)&lt;br /&gt;
                     markAffected(c.parent)&lt;br /&gt;
                 affected.remove(v)&lt;br /&gt;
         '''for''' &amp;lt;tex&amp;gt;v \in \mathrm{affected}&amp;lt;/tex&amp;gt;&lt;br /&gt;
             '''Cell''' newCell = getCellForVertex(v).clone().applyChanges()&lt;br /&gt;
             cells[v][layer + 1] = newCell&lt;br /&gt;
         layer++&lt;br /&gt;
 &lt;br /&gt;
 '''func''' markAffected(v: '''int''')''':'''               &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// пометить вершину как изменившуюся&amp;lt;/font&amp;gt;&lt;br /&gt;
    '''if''' lastUpdateTime[v] == time&lt;br /&gt;
        '''return'''                            &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// вершина уже помечена&amp;lt;/font&amp;gt;&lt;br /&gt;
    lastUpdateTime[v] = time&lt;br /&gt;
    affected.add(v)&lt;br /&gt;
    removeEffectOfVertex(v)&lt;br /&gt;
 &lt;br /&gt;
 '''func''' removeEffectOfVertex(v: '''int''')''':'''       &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// удалить отметку о том, что вершина была помечена изменившийся&amp;lt;/font&amp;gt;&lt;br /&gt;
    '''int''' layer = cells[v].size&lt;br /&gt;
    '''Cell''' c = cells[v][layer]&lt;br /&gt;
    '''if''' c.parent == v&lt;br /&gt;
        '''return'''&lt;br /&gt;
    cells[c].parent.removeChild(v)&lt;br /&gt;
    '''if''' c.cntChild == 1&lt;br /&gt;
        cells[c.parent].addChild(c.sumChild)&lt;br /&gt;
        cells[c.sumChild].newParent = v&lt;br /&gt;
&lt;br /&gt;
==Сравнение с Link-Cut Tree==&lt;br /&gt;
Для Link-Cut деревьев (основанных на [[Splay-дерево|splay-деревьях]]), как и для &amp;lt;tex&amp;gt;\mathrm{Rake-Compress}&amp;lt;/tex&amp;gt; деревьев, время работы операций &amp;lt;tex&amp;gt;\mathrm{link}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{cut}&amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt;O(\log{n})&amp;lt;/tex&amp;gt;. В реальности &amp;lt;tex&amp;gt;\mathrm{RC}&amp;lt;/tex&amp;gt; деревья оказываются медленнее, чем &amp;lt;tex&amp;gt;\mathrm{LC}&amp;lt;/tex&amp;gt; деревья. &amp;lt;br&amp;gt;&lt;br /&gt;
Отличительной особенностью &amp;lt;tex&amp;gt;\mathrm{RC}&amp;lt;/tex&amp;gt; деревьев является возможность параллельного построения: операции &amp;lt;tex&amp;gt;\mathrm{Rake}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{Compress}&amp;lt;/tex&amp;gt; можно выполнять параллельно для всех вершин. Если предположить, что множество детей можно пересчитывать за &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\mathrm{Rake-Compress}&amp;lt;/tex&amp;gt; дерево можно построить за &amp;lt;tex&amp;gt;O(\log{n})&amp;lt;/tex&amp;gt; в модели PRAM&amp;lt;ref&amp;gt;[https://en.wikipedia.org/wiki/Parallel_random-access_machine Wikipedia {{---}} Parallel random-access machine]&amp;lt;/ref&amp;gt; в случае наличия &amp;lt;tex&amp;gt;\Omega(n)&amp;lt;/tex&amp;gt; процессоров.&amp;lt;br&amp;gt;&lt;br /&gt;
Кроме этого, &amp;lt;tex&amp;gt;\mathrm{Rake-Compress}&amp;lt;/tex&amp;gt; деревья могут оказаться полезными, если необходимо пересчитывать значения не на путях, а на поддеревьях.&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
* [[Link-Cut Tree]]&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Parallel_Tree_Contraction Wikipedia {{---}} Parallel Tree Contraction]&lt;br /&gt;
* [https://github.com/BorysMinaiev/bachelor/blob/master/thesis_v2.pdf Б. Ю. Минаев {{---}} Реализация динамических Rake-Compress деревьев в случае отсутствия ограничения на степени вершин]&lt;br /&gt;
* [http://www.cs.cmu.edu/~jvittes/rc-trees Acar, Blelloch, and Vittes {{---}} RC-Tree implementation]&lt;br /&gt;
* [http://www.cs.princeton.edu/~rwerneck/papers/Wer06-dissertation.pdf R. Werneck {{---}} Design and Analysis of Data Structures for Dynamic Trees]&lt;br /&gt;
* G. L. Miller, J. H. Reif {{---}} Parallel Tree Contraction, Journal of Advances in Computer Research Volume 5, 1989&lt;br /&gt;
* Umit A. Acar, Guy E. Blelloch, Jorge L. Vittes {{---}} An Experimental Analysis of Change Propagation in Dynamic Trees, 1-2005&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Задача о наименьшем общем предке]]&lt;/div&gt;</summary>
		<author><name>Kiryukhinv</name></author>	</entry>

	</feed>