<?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=188.227.78.59&amp;*</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=188.227.78.59&amp;*"/>
		<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/188.227.78.59"/>
		<updated>2026-06-11T20:00:06Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%93%D1%80%D0%B0%D1%84%D1%8B-%D1%8D%D0%BA%D1%81%D0%BF%D0%B0%D0%BD%D0%B4%D0%B5%D1%80%D1%8B&amp;diff=62604</id>
		<title>Графы-экспандеры</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%93%D1%80%D0%B0%D1%84%D1%8B-%D1%8D%D0%BA%D1%81%D0%BF%D0%B0%D0%BD%D0%B4%D0%B5%D1%80%D1%8B&amp;diff=62604"/>
				<updated>2017-12-13T18:45:54Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: определение для однородного экспандера&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Граф-экспандер''' (или расширяющийся граф, англ. ''expander graph'') - в комбинаторике сильно разреженный граф, при этом связность определяется по вершинам, дугам или спектру.&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Однородный (комбинаторный) экспандер''' называется граф &amp;lt;tex&amp;gt;G = (V, E)&amp;lt;/tex&amp;gt; с параметрами &amp;lt;tex&amp;gt;(n, d, \epsilon)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;n = |V|&amp;lt;/tex&amp;gt;, степень любой вершины равно d, &amp;lt;tex&amp;gt;\epsilon&amp;lt;/tex&amp;gt; &amp;lt; 1, если выполняется условие: для &amp;lt;tex&amp;gt;\forall S \subset V&amp;lt;/tex&amp;gt;  &amp;lt;tex&amp;gt;|S| \leq n/2&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;\exists&amp;lt;/tex&amp;gt; множество соседей &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;r(S) = {v: \exists w \in S, (v, w) \in E}&amp;lt;/tex&amp;gt; достаточно велико, то есть &amp;lt;tex&amp;gt;|r(S)| &amp;gt; (1 + \epsilon)|S|&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
'''Замечание 1:''' в графе могут присутствовать кратные ребра и петли. Если у любой вершины есть петля, то &amp;lt;tex&amp;gt;\forall S \supseteq r(S)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Замечание 2:''' чем больше &amp;lt;tex&amp;gt;\epsilon&amp;lt;/tex&amp;gt;, тем сильнее свойство расширения. &lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
&amp;lt;tex&amp;gt;\forall n&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;\forall \epsilon &amp;lt; 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
для достаточно больших четных &amp;lt;tex&amp;gt;d = d(\epsilon)&amp;lt;/tex&amp;gt; существует однородный(комбинаторный) экспандер с параметрами &amp;lt;tex&amp;gt;(n, d, \epsilon)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Двудольный граф &amp;lt;tex&amp;gt;G = (L, R, E) \  (L&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt; {{---}} левая и правая  доли графов, &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; {{---}} множество ребер&amp;lt;tex&amp;gt;)&amp;lt;/tex&amp;gt; называется &amp;lt;tex&amp;gt;(n, m, d)-&amp;lt;/tex&amp;gt;'''экспандером''' (расширяющимся графом), если &amp;lt;tex&amp;gt;|L| = n, |R| = m&amp;lt;/tex&amp;gt;, степень всех вершин в доле &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; равна &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, и выполняются следующие свойства расширения:&lt;br /&gt;
* Для любого множества &amp;lt;tex&amp;gt;S \subset L, |S| \leqslant  \dfrac{n}{1000d}&amp;lt;/tex&amp;gt; множество соседей (соседи &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; лежат в &amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt;) достаточно велико: &amp;lt;tex&amp;gt;|Г(S)| &amp;gt; \dfrac{7}{8}d|S|&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Для любого множества &amp;lt;tex&amp;gt;S \subset L&amp;lt;/tex&amp;gt;, такого что &amp;lt;tex&amp;gt;|S| \leqslant \dfrac{n}{2}&amp;lt;/tex&amp;gt;, множество соседей немного больше самого множества &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, а именно, &amp;lt;tex&amp;gt;|Г(S)| &amp;gt; \dfrac{9}{8}|S|&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
''Граф-экспандер'' — это конечный ненаправленный ''мультиграф'', в котором любое подмножество вершин, не являясь «слишком большим», имеет «сильную» связность. Различные формализации этих понятий дают различные типы экспандеров: ''рёберный расширитель'', ''вершинный расширитель'', и ''спектральный расширитель''.&lt;br /&gt;
&lt;br /&gt;
'''Замечание:''' Несвязный граф не является экспандером. Любой связный граф является экспандером, однако различные связные графы имеют различные параметры расширителя. Полный граф имеет лучшие параметры расширителя, но имеет наибольшую возможную степень. Неформально говоря, граф является хорошим экспандером, если он имеет низкую степень и высокий параметр расширителя.&lt;br /&gt;
&lt;br /&gt;
===Реберное расширение===&lt;br /&gt;
''Рёберное расширение'' (также ''изопериметрическое число'' или константа Чигера) &amp;lt;tex&amp;gt;h(G)&amp;lt;/tex&amp;gt; графа &amp;lt;tex&amp;gt;G&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;h(G) = \min\limits_{0 &amp;lt; |S|\leqslant \frac{n}{2}} \frac{|\partial_{\text{out}}(S)|}{|S|}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
где минимум берётся по всем непустым множествам &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; не более чем &amp;lt;tex&amp;gt;n/2&amp;lt;/tex&amp;gt; вершин и &amp;lt;tex&amp;gt;\partial(S)&amp;lt;/tex&amp;gt; — ''граничные дуги'' множества &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, то есть, множество дуг с единственной вершиной в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Вершинное расширение===&lt;br /&gt;
''Вершинное изопериметрическое число'' &amp;lt;tex&amp;gt;h_{out}(G)&amp;lt;/tex&amp;gt; (также ''вершинное раширение'') графа &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; определяется как&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;h_{out}(G) = \min\limits_{0 &amp;lt; |S|\leqslant \frac{n}{2}} \frac{|\partial_{\text{out}}(S)|}{|S|}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
где &amp;lt;tex&amp;gt;\partial_{\text{out}}(S)&amp;lt;/tex&amp;gt; — ''внешняя граница'' &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, то есть множество вершин из &amp;lt;tex&amp;gt;V(G)\setminus S&amp;lt;/tex&amp;gt;, имеющих как минимум одного соседа в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В варианте этого определения (называемом ''уникальным соседним расширением'') &amp;lt;tex&amp;gt;\partial_{\text{out}}(S)&amp;lt;/tex&amp;gt; заменяется на множество вершин из &amp;lt;tex&amp;gt;V&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;h_{in}(G)&amp;lt;/tex&amp;gt; графа &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; определяется как&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;h_{in}(G) = \min\limits_{0 &amp;lt; |S|\leqslant \frac{n}{2}} \frac{|\partial_{\text{in}}(S)|}{|S|}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
где &amp;lt;tex&amp;gt;\partial_{in}(S)&amp;lt;/tex&amp;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;V(G)\setminus S&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Спектральное расширение===&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; является d-регулярным, возможно определение в терминах линейной алгебры на основе собственных значений матрицы смежности &amp;lt;tex&amp;gt;A = A(G)&amp;lt;/tex&amp;gt; графа &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;A_{ij}&amp;lt;/tex&amp;gt; — число дуг между вершинами &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;. Поскольку &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; является симметричной, согласно спектральной теореме, &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; имеет &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; действительных собственных значений &amp;lt;tex&amp;gt;\lambda_1 \ge \lambda_2 \ge \cdots \ge \lambda_{n}&amp;lt;/tex&amp;gt;. Известно, что эти значения лежат в промежутке &amp;lt;tex&amp;gt;[−d, d]&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Граф регулярен тогда и только тогда, когда вектор &amp;lt;tex&amp;gt;u\in \mathbb {R} ^{n} с u_{i}=1&amp;lt;/tex&amp;gt; для всех &amp;lt;tex&amp;gt;i = 1, …, n&amp;lt;/tex&amp;gt; является собственным вектором матрицы &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, а его собственное число будет постоянной степенью графа. Таким образом, мы имеем &amp;lt;tex&amp;gt;Au = du&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; — собственный вектор матрицы &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; с собственными значениями &amp;lt;tex&amp;gt;λ1 = d&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;d&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;d−λ2&amp;lt;/tex&amp;gt; и является мерилом спектрального расширения графа &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Известно, что &amp;lt;tex&amp;gt;\lambda_n = −d&amp;lt;/tex&amp;gt; тогда и только тогда, когда &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; — двудольный. Во многих случаях, например в лемме о перемешивании, необходимо ограничить снизу не только зазор между &amp;lt;tex&amp;gt;\lambda_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\lambda_2&amp;lt;/tex&amp;gt;, но и зазор между &amp;lt;tex&amp;gt;\lambda_1&amp;lt;/tex&amp;gt; и вторым максимальным по модулю собственным значением:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\lambda=\max\{|\lambda_2|, |\lambda_{n}|\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Поскольку это собственное значение соответствует некоторому собственному вектору, ортогональному &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;, его можно определить, используя отношение Рэлея:&lt;br /&gt;
&amp;lt;tex&amp;gt;\lambda=\max_{0\neq v\perp u} \frac{\|Av\|_2}{\|v\|_2},&amp;lt;/tex&amp;gt;&lt;br /&gt;
gde&lt;br /&gt;
&amp;lt;tex&amp;gt;\|v\|_2=\left(\sum_{i=1}^n v_i^2\right)^{1/2}&amp;lt;/tex&amp;gt;&lt;br /&gt;
— евклидова норма вектора &amp;lt;tex&amp;gt;v\in \mathbb {R} ^{n}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Нормализованная версия этого определения также широко используется и более удобна для получения определённых результатов. В таком случае рассматривается матрица &amp;lt;tex&amp;gt;{\tfrac {1}{d}}A&amp;lt;/tex&amp;gt;, являющаяся матрицей переходов графа G. Все её собственные значения лежат между &amp;lt;tex&amp;gt;−1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Если граф не регулярен, спектр графа может быть определён аналогичным образом, используя собственные значения матрицы Кирхгофа. Для направленного графа используются сингулярные значения матрицы сопряжения A, которые равны квадратным корням из собственных значений симметричной матрицы &amp;lt;tex&amp;gt;A^TA&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Конструирование==&lt;br /&gt;
Существуют три основные стратегии создания семейств графов расширений. Первая стратегия — алгебраическая и теоретико-групповая, вторая — аналитическая, использующая аддитивную комбинаторику, и третья — комбинаторная, использующая зигзаг-произведение и связанные комбинаторные произведения.&lt;br /&gt;
===Маргулис-Габбер-Галил===&lt;br /&gt;
Алгебраическое конструирование, основанное на графах Кэли, известно для различных вариантов экспандеров. Следующее конструирование принадлежит Маргулису и было проанализировано Габбером (Gabber) и Галилом (Galil). Для любого натурального &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; строим граф, &amp;lt;tex&amp;gt;G_{n}&amp;lt;/tex&amp;gt; со множеством вершин &amp;lt;tex&amp;gt;\mathbb Z _{n}\times \mathbb {Z} _{n}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;\mathbb {Z} _{n}=\mathbb Z /n \mathbb Z&amp;lt;/tex&amp;gt; . Для любой вершины &amp;lt;tex&amp;gt;(x,y)\in \mathbb {Z} _{n}\times \mathbb {Z} _{n}&amp;lt;/tex&amp;gt;, её восемь соседей будут&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;(x \pm 2y,y), (x \pm (2y+1),y), (x,y \pm 2x), (x,y \pm (2x+1)).&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выполняется следующая теорема:&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Для всех &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; граф &amp;lt;tex&amp;gt;Gn&amp;lt;/tex&amp;gt; второе по величине собственное число&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tex&amp;gt;\lambda(G)\leq 5 \sqrt{2}&amp;lt;/tex&amp;gt;.}}&lt;br /&gt;
&lt;br /&gt;
===Граф Рамануджана===&lt;br /&gt;
&amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-регулярный граф называется графом Рамануджана, если его второе по модулю собственное число не превосходит &amp;lt;tex&amp;gt;2{\sqrt {d-1}}&amp;lt;/tex&amp;gt;. Любоцкий, Сарнак, Филлипс и Маргулис указали явную конструкцию графов Кэли, являющихся графами Рамануджана. Опишем эту конструкцию.&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; простые числа, &amp;lt;tex&amp;gt;p = 1 \bmod 4&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;q = 1 \bmod 4&amp;lt;/tex&amp;gt;. В качестве группы &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; возьмём &amp;lt;tex&amp;gt;PGL(2, \mathbb Z/q{\mathbb Z})&amp;lt;/tex&amp;gt;, т.е. невырожденные матрицы 2 × 2 над полем вычетов по модулю &amp;lt;tex&amp;gt;q&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;i^2 = −1 \bmod q&amp;lt;/tex&amp;gt;. Можно доказать, что тогда имеется ровно &amp;lt;tex&amp;gt;(p + 1)&amp;lt;/tex&amp;gt; целочисленное решение уравнения&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;a_0^2 + a_1^2 + a_3^2 = p&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
такое, что &amp;lt;tex&amp;gt;a_0&amp;lt;/tex&amp;gt; положительно и нечётно, а &amp;lt;tex&amp;gt;a_1&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;a_2&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;a_3&amp;lt;/tex&amp;gt; чётны. Каждой такой четвёрке сопоставим матрицу&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;A = \begin{pmatrix} a_0 + ia_1 &amp;amp; a_2 + ia_3\\ -a_2 + ia_3 &amp;amp; a_0 - ia_1 \end{pmatrix}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Эти матрицы образуют множество S.&lt;br /&gt;
Нетрудно понять, что граф Кэли &amp;lt;tex&amp;gt;(G, S)&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;\Theta(q^3)&amp;lt;/tex&amp;gt; вершин, и степень каждой вершины равна &amp;lt;tex&amp;gt;(p + 1)&amp;lt;/tex&amp;gt;. Свойства данного графа зависят от соотношения &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. Рассмотрим случай, когда p является квадратичным вычетом по модулю &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;G&amp;lt;/tex&amp;gt; индекса два — подгруппе матриц, определитель которых является квадратичным вычетом). Обозначим &amp;lt;tex&amp;gt;X^{p,q}&amp;lt;/tex&amp;gt; связную компоненту полученного графа. Можно доказать, что у &amp;lt;tex&amp;gt;X^{p,q}&amp;lt;/tex&amp;gt; второе по абсолютной величине собственное число не превосходит &amp;lt;tex&amp;gt;2{\sqrt{p}}&amp;lt;/tex&amp;gt;, т.е. мы получили граф Рамануджана.&lt;br /&gt;
&lt;br /&gt;
==Примеры применения экспандеров==&lt;br /&gt;
===Коды, исправляющие ошибки===&lt;br /&gt;
С помощью расширяющего графа можно посторить линейный код, позволяющий исправлять ошибки в доле &amp;lt;tex&amp;gt;\delta = 1/(2000d)&amp;lt;/tex&amp;gt; битов. Чтобы задать линейный код с длиной кодового слова n, достаточно описать его проверочную матрицу &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;(&amp;lt;/tex&amp;gt;слово &amp;lt;tex&amp;gt;x \in \{0, 1\}^n&amp;lt;/tex&amp;gt; является кодовым словом если и только если &amp;lt;tex&amp;gt;Hx^t = 0)&amp;lt;/tex&amp;gt;. Другими словами, нужно задать систему линейных уравнений для переменных &amp;lt;tex&amp;gt;x_1, . . . , x_n;&amp;lt;/tex&amp;gt; решения этой системы и будут кодовыми словами.&lt;br /&gt;
===Увеличение вероятности успеха в алгоритмах с датчиком случайных чисел===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=Язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; принадлежит сложностному классу &amp;lt;tex&amp;gt;RP&amp;lt;/tex&amp;gt;, если существует полиномиальный алгоритм &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; такой что&lt;br /&gt;
1. для &amp;lt;tex&amp;gt;x \in L&amp;lt;/tex&amp;gt; для всех &amp;lt;tex&amp;gt;r \in \{0, 1\}^{poly(n)}&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;A(x, r) = 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
2. для &amp;lt;tex&amp;gt;x \notin L&amp;lt;/tex&amp;gt; не более чем для 1/2000 всех &amp;lt;tex&amp;gt;r \in \{0, 1\}^{poly(n)}&amp;lt;/tex&amp;gt; может выполняться &amp;lt;tex&amp;gt;A(x, r) = 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Покажем, что для любого &amp;lt;tex&amp;gt;\epsilon &amp;gt; 0&amp;lt;/tex&amp;gt; полиномиальный вероятностный алгоритм A можно модифицировать таким образом, чтобы вероятность ошибки уменьшилась до &amp;lt;tex&amp;gt;\epsilon&amp;lt;/tex&amp;gt;, а число используемых случайных битов не изменится.&lt;br /&gt;
&lt;br /&gt;
Пусть исходный алгоритм использует &amp;lt;tex&amp;gt;k = k(n)&amp;lt;/tex&amp;gt; случайных битов для вычислений на входах длины &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. Зафиксируем &amp;lt;tex&amp;gt;(2^k, 2^k, d)&amp;lt;/tex&amp;gt; - экспандер &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;d &amp;gt; 1/\epsilon&amp;lt;/tex&amp;gt;. Новый алгоритм действует следующим образом: выбирается случайная вершина &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; из левой доли графа (для этого требуется &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; случайных битов); затем исходный алгоритм &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; последовательно запускается на всех &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; наборах случайных битов, соответствующих соседям вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;. Если все полученные ответы равны &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, новый алгоритм также возвращает единицу; в противном случае возвращается ноль.&lt;br /&gt;
Покажем, что у нового алгоритма вероятность ошибки не превосходит &amp;lt;tex&amp;gt;1/d&amp;lt;/tex&amp;gt;. В самом деле, обозначим &amp;lt;tex&amp;gt;B = B(x)&amp;lt;/tex&amp;gt; множество таких вершин &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt; из правой доли графа, которые соответствуют неверному ответу старого алгоритма на входе &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;; аналогично, обозначим &amp;lt;tex&amp;gt;S = S(x)&amp;lt;/tex&amp;gt; множество таких вершин v из левой доли графа, которые для которых новый алгоритм даёт неверный ответ на входе &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Очевидно, &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; состоит из вершин, все соседи которых лежат в B. Предположим, что &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; содержит не менее &amp;lt;tex&amp;gt;n/(1000d)&amp;lt;/tex&amp;gt; вершин. Выберем среди них ровно &amp;lt;tex&amp;gt;n/(1000d)&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;|\Gamma(S')| \geqslant  \frac{7}{8}d\frac{n}{1000d}=7n/8000 &amp;gt; n/2000&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это противоречит тому, что все соседи &amp;lt;tex&amp;gt;S'&amp;lt;/tex&amp;gt; лежат в &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt;. В данном случае нам нужна явная в более сильном (чем в первом примере) смысле конструкция экспандера. Размер графа экспоненциално растёт с увеличенем &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, и нам необходим алгоритм, который по заданному номеру вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; (из левой доли графа) за время &amp;lt;tex&amp;gt;poly(k)&amp;lt;/tex&amp;gt; находит список номеров всех соседей этой вершины (в правой доле графа).&lt;br /&gt;
&lt;br /&gt;
===Хранение множества со сверхбыстрым запросом элементов===&lt;br /&gt;
Мы организуем хранение m-элементного множества &amp;lt;tex&amp;gt;S \subset \{1, . . . , n\}&amp;lt;/tex&amp;gt; в виде описания &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, состоящего из &amp;lt;tex&amp;gt;O(m log n)&amp;lt;/tex&amp;gt; битов. При этом проверка принадлежности &amp;lt;tex&amp;gt;a \in S&amp;lt;/tex&amp;gt; будет производиться чрезвычайно быстро. А именно, мы построим такой вероятностный алгоритм, который по любому входу &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; запрашивает из &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; один бит; если этот бит оказывается равным единице, то алгоритм отвечает, что &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;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;a \in \{1, . . . , n\}&amp;lt;/tex&amp;gt; алгоритм ошибается с вероятностью не более &amp;lt;tex&amp;gt;1/3&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Чтобы построить нужное нам хранилище &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, мы сначала зафиксируем некоторый экспандер, у которого левая доля &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин, правая &amp;lt;tex&amp;gt;R&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;k = O(m log n)&amp;lt;/tex&amp;gt; вершин, степень всех вершин левой доли одинакова и равна некоторому &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, и для каждого &amp;lt;tex&amp;gt;A \subset L&amp;lt;/tex&amp;gt; размера не более &amp;lt;tex&amp;gt;2m&amp;lt;/tex&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;|\Gamma(A)| \geqslant \frac{7}{8}d|A|&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; будет состоять в разметке вершин правой доли нулями и единицами. Эту разметку нужно выбрать таким образом, чтобы у каждой вершины из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; не менее &amp;lt;tex&amp;gt;2/3&amp;lt;/tex&amp;gt; соседей были помечены единицей, а у каждой вершины не из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; не менее &amp;lt;tex&amp;gt;2/3&amp;lt;/tex&amp;gt; соседей были помечены нулями.&amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; будет состоять в разметке вершин правой доли нулями и единицами. Эту разметку нужно выбрать таким образом, чтобы у каждой вершины из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; не менее &amp;lt;tex&amp;gt;2/3&amp;lt;/tex&amp;gt; соседей были помечены единицей, а у каждой вершины не из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; не менее &amp;lt;tex&amp;gt;2/3&amp;lt;/tex&amp;gt; соседей были помечены нулями.&lt;br /&gt;
&lt;br /&gt;
Остаётся объяснить, как построить нужную нам разметку правой доли графа. Будем строить её последовательными приближениями. Сначала пометим всех соседей всех вершин из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; единицами, а все остальные вершины – нулями. На данной разметке наш алгоритм с вероятностью &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; возвращает правильный ответ для всех &amp;lt;tex&amp;gt;a \in S&amp;lt;/tex&amp;gt;. Однако для &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; не из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; проверочный алгоритм может работать неверно. Обозначим T множество всех таких вершин вне &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, у которых более &amp;lt;tex&amp;gt;d/3&amp;lt;/tex&amp;gt; соседей помечены единицей. Поменяем разметку: пометим всех соседей &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;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;S&amp;lt;/tex&amp;gt;, у которых более &amp;lt;tex&amp;gt;d/3&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&amp;lt;/tex&amp;gt;, и т.д.&lt;br /&gt;
&lt;br /&gt;
Чтобы доказать, что данный процесс в конце концов сойдётся, нужно показать, что на каждом шаге число ‘проблемных’ вершин уменьшается в константу раз. Поскольку все шаги аналогичны, достаточно разобрать самый первый: докажем, что &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; в константу раз меньше, чем &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Мы воспользуемся тем, что для &amp;lt;tex&amp;gt;S \cup T&amp;lt;/tex&amp;gt; выполнено свойство расширения:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;(7/8)d(|S|+|T|) \leqslant |\Gamma(S \cup T)| \leqslant d|S| + (2/3)d|T|&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Откуда получаем &amp;lt;tex&amp;gt;|T| \leqslant 3/5|S|&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;SL=L&amp;lt;/tex&amp;gt; и Теорема PCP. В криптографии экспандеры используются для создания хеш-функций.&lt;br /&gt;
&lt;br /&gt;
Ниже приведены некоторые свойства экспандеров, считающиеся полезными во многих областях.&lt;br /&gt;
===Лемма о перемешивании===&lt;br /&gt;
Лемма о перемешивании утверждает, что для любых двух подмножеств вершин &amp;lt;tex&amp;gt;S,T\subseteq V&amp;lt;/tex&amp;gt; число рёбер между &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; примерно равно числу рёбер в случайном &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-регулярном графе. Приближение тем лучше, чем меньше &amp;lt;tex&amp;gt;\lambda =\max\{|\lambda _{2}|&amp;lt;/tex&amp;gt;,&amp;lt;tex&amp;gt;|\lambda _{n}|\}&amp;lt;/tex&amp;gt;. В случайном &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;-регулярном графе, также как и в случайном графе Эрдёша — Реньи с вероятностью &amp;lt;tex&amp;gt;{\tfrac {d}{n}}&amp;lt;/tex&amp;gt; выбора ребра, ожидается &amp;lt;tex&amp;gt;{\tfrac {d}{n}}\cdot |S|\cdot |T|&amp;lt;/tex&amp;gt; рёбер между &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Более формально, пусть &amp;lt;tex&amp;gt;E(S, T)&amp;lt;/tex&amp;gt; обозначает число рёбер между &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;. Если эти два множества пересекаются, дуги в пересечении считаются дважды, так что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;E(S,T)=2|E(G[S\cap T])|+E(S\setminus T,T)+E(S,T\setminus S)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Лемма о перемешивании утверждает, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\left|E(S,T)-{\frac {d\cdot |S|\cdot |T|}{n}}\right|\leq d\lambda {\sqrt {|S|\cdot |T|}}&amp;lt;/tex&amp;gt;,&lt;br /&gt;
где &amp;lt;tex&amp;gt;\lambda &amp;lt;/tex&amp;gt; — абсолютное значение нормализованного второго по величине собственного значения.&lt;br /&gt;
&lt;br /&gt;
Недавно Билу (Bilu) и Линайл (Linial) показали, что обратное тоже верно, то есть, при условии выполнения неравенства из леммы второе по величине собственное значение равно &amp;lt;tex&amp;gt;O(d\lambda \cdot (1+\log(1/\lambda )))&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Блуждания по экспандеру===&lt;br /&gt;
Согласно границе Чернова, если выбирать много независимых случайных значений из интервала &amp;lt;tex&amp;gt;[−1, 1]&amp;lt;/tex&amp;gt;, с большой степенью вероятности среднее выбранных значений будет близко к математическому ожиданию случайной переменной. Лемма о блуждании по экспандеру, согласно статьям Аджтари, Комлоша и Семереди и Гилмана, утверждает, что то же самое верно и для блужданий по экспандеру. Это полезно в теории дерандомизации, поскольку блуждание по экспандеру использует много меньше случайных бит, чем случайная независимая выборка.&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[https://ru.wikipedia.org/wiki/%D0%AD%D0%BA%D1%81%D0%BF%D0%B0%D0%BD%D0%B4%D0%B5%D1%80_(%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D1%8F_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2) Экспандер (теория графов)]&lt;br /&gt;
*[S. Hoory, N. Linial, A. Wigderson. Expander graphs and their applications. Bulletin of the AMS, vol. 43, Number 4, Oct. 2006, pp.439 561.]&lt;br /&gt;
*[ H. Buhrman, P.B. Miltersen, J. Radhakrishnan, S. Venkatesh. Are Bitvectors optimal? SIAM J. Comput., 31(6):1723–1744, 2002.]&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B8%D0%B1%D0%BE%D0%BD%D0%B0%D1%87%D1%87%D0%B8%D0%B5%D0%B2%D0%B0_%D0%BA%D1%83%D1%87%D0%B0&amp;diff=61915</id>
		<title>Фибоначчиева куча</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B8%D0%B1%D0%BE%D0%BD%D0%B0%D1%87%D1%87%D0%B8%D0%B5%D0%B2%D0%B0_%D0%BA%D1%83%D1%87%D0%B0&amp;diff=61915"/>
				<updated>2017-09-18T18:26:46Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: /* Недостатки и достоинства */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Фибоначчиева куча''' (англ. ''Fibonacci heap'')  {{---}} структура данных, отвечающая интерфейсу [[Приоритетные очереди#Операции | приоритетная очередь]]. Эта структура данных имеет меньшую [[Амортизационный анализ#Основные определения | амортизированную  сложность]], чем такие приоритетные очереди как [[Биномиальная куча | биномиальная куча]] и [[Двоичная куча | двоичная куча]]. Изначально эта структура данных была разработана Майклом Фридманом&amp;lt;ref&amp;gt;[[wikipedia:en:Michael_Fredman | Майкл Фридман {{---}} Википедия]]&amp;lt;/ref&amp;gt; и Робертом Тарьяном&amp;lt;ref&amp;gt;[[wikipedia:en:Robert_Tarjan | Роберт Тарьян {{---}} Википедия]]&amp;lt;/ref&amp;gt; при работе по улучшению асимптотической сложности [[Алгоритм Дейкстры | алгоритма Дейкстры]]. Свое название Фибоначчиева куча получила  из-за использования некоторых свойств  чисел Фибоначчи&amp;lt;ref&amp;gt;[[wikipedia:en:Fibonacci_number | Числа Фибоначчи {{---}} Википедия]]&amp;lt;/ref&amp;gt; в [[Амортизационный анализ#Метод потенциалов | потенциальном анализе]] этой реализации.&lt;br /&gt;
== Структура ==&lt;br /&gt;
Фибоначчиева куча  {{---}} набор из [[Дерево, эквивалентные определения | подвешенных деревьев]] удовлетворяющих свойству: каждый предок не больше своих детей(если дерево на минимум). Это означает, что минимум всей кучи это один из корней этих деревьев. Одним из главных преимуществ Фибоначчиевой кучи {{---}} гибкость её структуры из-за того, что на деревья не наложены никакие ограничения по форме. Например, Фибоначчиева куча может состоять хоть из деревьев в каждом из которых по одному элементу. Такая гибкость позволяет выполнять некоторые операции лениво, оставляя работу более поздним операциям. Далее будут даны некоторые определения, которые понадобятся в дальнейшем.&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Степень вершины''' (англ. ''degree'')  {{---}} количество детей данной вершины. Далее будем обозначать как &amp;lt;tex&amp;gt;degree(x)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; это вершина.&lt;br /&gt;
}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Степень кучи''' (англ. ''degree'')  {{---}} наибольшая степень вершины этой кучи. Далее будем обозначать как &amp;lt;tex&amp;gt;degree(H)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; это куча.&lt;br /&gt;
}}&lt;br /&gt;
== Реализация == &lt;br /&gt;
[[File:Fibonacci-heap.png|thumb|340px|Пример фибоначчиевой кучи]]&lt;br /&gt;
Для возможности быстрого удаления элемента из произвольного места и объединением с другим списком будем хранить их в [[Список#Циклический список | циклическом двусвязном списке]]. Также будем хранить и все уровни поддерева. Исходя из этого структура каждого узла будет выглядеть вот так.&lt;br /&gt;
&amp;lt;code style=&amp;quot;display:inline-block&amp;quot;&amp;gt;&lt;br /&gt;
 '''struct''' Node&lt;br /&gt;
    '''int''' key &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;     // ключ&amp;lt;/span&amp;gt;&lt;br /&gt;
    '''Node''' parent &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt; // указатель на родительский узел&amp;lt;/span&amp;gt;&lt;br /&gt;
    '''Node''' child &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;  // указатель на один из дочерних узлов&amp;lt;/span&amp;gt;&lt;br /&gt;
    '''Node''' left &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;   // указатель на левый узел того же предка&amp;lt;/span&amp;gt;&lt;br /&gt;
    '''Node''' right &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;  // указатель на правый узел того же предка&amp;lt;/span&amp;gt;&lt;br /&gt;
    '''int''' degree &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;  // степень вершины&amp;lt;/span&amp;gt;&lt;br /&gt;
    '''boolean''' mark &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// был ли удален в процессе изменения ключа ребенок этой вершины)&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;Также стоит упомянуть, что нам нужнен только на одного ребенка, поскольку остальные хранятся в двусвязном списке с ним. Для доступа ко всей кучи нам тоже нужен всего один элемент, поэтому разумно хранить именно указатель на минимум кучи(он обязательно один из корней), а для получения размера за константное время будем хранить размер кучи отдельно.&lt;br /&gt;
&amp;lt;code style=&amp;quot;display:inline-block&amp;quot;&amp;gt;&lt;br /&gt;
 '''struct''' fibonacciHeap&lt;br /&gt;
    '''int''' size &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// текущее количество узлов&amp;lt;/span&amp;gt;&lt;br /&gt;
    '''Node''' min &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// указатель на корень дерева с минимальным ключом&amp;lt;/span&amp;gt; &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
==== Cоздание кучи ====&lt;br /&gt;
Инициализация кучи.&lt;br /&gt;
&amp;lt;code style=&amp;quot;display:inline-block&amp;quot;&amp;gt;&lt;br /&gt;
 '''function''' buildHeap:&lt;br /&gt;
    min &amp;lt;tex&amp;gt;= \varnothing&amp;lt;/tex&amp;gt; &lt;br /&gt;
    size = 0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
==== Вставка элемента ====&lt;br /&gt;
Данная операция вставляет новый элемент в список корней правее минимума и при необходимости меняет указатель на минимум кучи.&lt;br /&gt;
&amp;lt;code style=&amp;quot;display:inline-block&amp;quot;&amp;gt;&lt;br /&gt;
 '''function''' insert(x: '''int'''):&lt;br /&gt;
    '''Node''' newNode &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;               // создаем новый узел&amp;lt;/span&amp;gt; &lt;br /&gt;
    newNode.key = x &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;            // инициализируем ключ нового узла&amp;lt;/span&amp;gt;&lt;br /&gt;
    '''if''' size = 0 &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;               // если куче нет элементов, то только что добавленный минимальный&amp;lt;/span&amp;gt;&lt;br /&gt;
        min = newNode&lt;br /&gt;
        min.left = newNode&lt;br /&gt;
        min.right = newNode&lt;br /&gt;
    '''else'''&amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;                        // иначе аккуратно меняем указатели в списке, чтобы не перепутать указатели&amp;lt;/span&amp;gt;&lt;br /&gt;
        '''Node''' prevRight = min.right &lt;br /&gt;
        min.right = newNode&lt;br /&gt;
        newNode.left = min &lt;br /&gt;
        newNode.right = prevRight &lt;br /&gt;
        prevRight.left = newNode &lt;br /&gt;
    '''if''' newNode.key &amp;lt; min.key&lt;br /&gt;
        min = newNode &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;          // меняем указатель на минимум, если надо&amp;lt;/span&amp;gt;&lt;br /&gt;
    newNode.parent &amp;lt;tex&amp;gt;= \varnothing&amp;lt;/tex&amp;gt; &lt;br /&gt;
    size++ &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;                     // не забываем увеличить переменную size &amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
==== Получение минимального элемента ====&lt;br /&gt;
Получение минимума всей кучи.&lt;br /&gt;
&amp;lt;code style=&amp;quot;display:inline-block&amp;quot;&amp;gt;&lt;br /&gt;
 '''int''' getMin:&lt;br /&gt;
    '''return''' min.key&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
==== Соедининение двух куч ====&lt;br /&gt;
Для сливание двух Фибоначчиевых куч необходимо просто объединить их корневые списки, а также обновить минимум новой кучи, если понадобится. Вынесем в вспомогательную функцию &amp;lt;tex&amp;gt;unionLists&amp;lt;/tex&amp;gt; логику, объединяющую  два списка вершины, которых подаются ей в качестве аргументов.&lt;br /&gt;
&amp;lt;code style=&amp;quot;display:inline-block&amp;quot;&amp;gt;  &lt;br /&gt;
 '''function''' unionLists(first: '''Node''', second: '''Node'''):&lt;br /&gt;
    '''Node''' L = first.left &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;              // аккуратно меняем указатели местами указатели&amp;lt;/span&amp;gt;&lt;br /&gt;
    '''Node''' R = second.right&lt;br /&gt;
    second.right = first&lt;br /&gt;
    first.left = second&lt;br /&gt;
    L.right = R&lt;br /&gt;
    R.left = L&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Сливаем два корневых списка в один и обновляем минимум, если нужно. &lt;br /&gt;
&amp;lt;code style=&amp;quot;display:inline-block&amp;quot;&amp;gt;&lt;br /&gt;
 '''function''' merge(that: '''fibonacciHeap'''):&lt;br /&gt;
    '''if''' that.size = 0 &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;              // если вторая куча пуста, нечего добавлять&amp;lt;/span&amp;gt;&lt;br /&gt;
        '''return'''&lt;br /&gt;
    '''if''' size = 0 &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;                   // если наша куча пуста, то результатом будет вторая куча&amp;lt;/span&amp;gt;&lt;br /&gt;
        min = that.min&lt;br /&gt;
        size = that.size&lt;br /&gt;
    '''else''' &lt;br /&gt;
        unionLists(min, that.min) &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;  // объединяем два корневых списка&amp;lt;/span&amp;gt;&lt;br /&gt;
        size += that.size&lt;br /&gt;
    '''if''' min &amp;lt;tex&amp;gt;= \varnothing&amp;lt;/tex&amp;gt; '''or''' (that.min &amp;lt;tex&amp;gt; \neq \varnothing&amp;lt;/tex&amp;gt; '''and''' that.min &amp;lt; min) &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;// если минимум кучи изменился, то надо обновить указатель&amp;lt;/span&amp;gt;&lt;br /&gt;
        min = that.min&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
==== Удаление минимального элемента====&lt;br /&gt;
Первая рассматриваемая операция, в ходе которой значительно меняется структура кучи. Здесь используется вспомогательная процедура &amp;lt;tex&amp;gt;consolidate&amp;lt;/tex&amp;gt;, благодаря которой собственно и достигается желанная амортизированная оценка. В данном случае &amp;lt;tex&amp;gt; min = \varnothing&amp;lt;/tex&amp;gt; не рассматривается и считается нарушением предусловий &amp;lt;tex&amp;gt;deleteMin&amp;lt;/tex&amp;gt;&lt;br /&gt;
&amp;lt;code style=&amp;quot;display:inline-block&amp;quot;&amp;gt;&lt;br /&gt;
 '''int''' deleteMin:&lt;br /&gt;
    '''Node''' prevMin = min &lt;br /&gt;
    unionLists(min, min.child) &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;   // список детей min объединяем с корневым&amp;lt;/span&amp;gt;&lt;br /&gt;
    '''Node''' L = min.left &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;            // аккуратно удаляем min из списка&amp;lt;/span&amp;gt;&lt;br /&gt;
    '''Node''' R = min.right&lt;br /&gt;
    L.right = R&lt;br /&gt;
    R.left = R&lt;br /&gt;
    '''if''' prevMin.right = prevMin &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;  // отдельно рассмотрим случай с одним элементом&amp;lt;/span&amp;gt;&lt;br /&gt;
        min &amp;lt;tex&amp;gt;= \varnothing&amp;lt;/tex&amp;gt;&lt;br /&gt;
        '''return'''&lt;br /&gt;
    min = min.right &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;              // пока что перекинем указаиель min на правого сына, а далее consolidate() скорректирует min в процессе выполнения&amp;lt;/span&amp;gt;&lt;br /&gt;
    consolidate()&lt;br /&gt;
    size-- &lt;br /&gt;
    '''return''' prevMin.key&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
===== Прорежение деревьев =====&lt;br /&gt;
Данная процедура принимает кучу и преобразует ее таким образом, что в корневом списке остается не более &amp;lt;tex&amp;gt; degree(H) + 1&amp;lt;/tex&amp;gt; вершин.&lt;br /&gt;
&lt;br /&gt;
Для этого возьмем массив списков указателей на корни деревьев &amp;lt;tex&amp;gt; A[0 \dots D[H]] &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt; degree(H) &amp;lt;/tex&amp;gt; {{---}} максимальная степень вершины в текущем корневом списке.&lt;br /&gt;
&lt;br /&gt;
Затем происходит [[Биномиальная_куча#merge | процесс, аналогичный слиянию биномиальных куч]]: добавляем поочередно каждый корень, смотря на его степень. Пусть она равна &amp;lt;tex&amp;gt; d &amp;lt;/tex&amp;gt;. Если в соответствующей ячейке &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; еще нету вершины, записываем текущую вершину туда. Иначе подвешиваем одно дерево к другому, и пытаемся также добавить дерево, степень корня которого уже равна &amp;lt;tex&amp;gt; d + 1 &amp;lt;/tex&amp;gt;. Продолжаем, пока не найдем свободную ячейку. Подвешиваем мы его следующим образом: в корневой список добавляем корень минимальный из тех двух, а корень другого добавляем в список детей корневой вершины. Чтобы лучше понять этот процесс лучше воспользоваться [https://www.cs.usfca.edu/~galles/visualization/FibonacciHeap.html визуализатором]&lt;br /&gt;
&amp;lt;code style=&amp;quot;display:inline-block&amp;quot;&amp;gt;&lt;br /&gt;
 '''function''' consolidate:&lt;br /&gt;
    A = '''Node[]'''&lt;br /&gt;
    A[min.degree] = min &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;                   // создаем массив и инициализируем его min&amp;lt;/span&amp;gt;&lt;br /&gt;
    '''Node''' current = min.right&lt;br /&gt;
    '''while''' A[current.degree] &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; current&amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;     // пока элементы массива меняются&amp;lt;/span&amp;gt;&lt;br /&gt;
        '''if''' A[current.degree] &amp;lt;tex&amp;gt;= \varnothing&amp;lt;/tex&amp;gt; &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;        // если ячейка пустая, то положим в нее текущий элемент&amp;lt;/span&amp;gt;&lt;br /&gt;
            A[current.degree] = current&lt;br /&gt;
            current = current.right&lt;br /&gt;
        '''else''' &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;                              // иначе подвесим к меньшему из текущего корня и того, который лежит в ячейке другой&amp;lt;/span&amp;gt;&lt;br /&gt;
            '''Node''' conflict = A[current.degree]&lt;br /&gt;
            '''Node''' addTo, adding&lt;br /&gt;
            '''if''' conflict.key &amp;lt; current.key&lt;br /&gt;
                addTo = conflict&lt;br /&gt;
                adding = current&lt;br /&gt;
            '''else'''&lt;br /&gt;
                addTo = current&lt;br /&gt;
                adding = conflict&lt;br /&gt;
            unionLists(addTo.child, adding)&lt;br /&gt;
            adding.parent = addTo&lt;br /&gt;
            addTo.degree++&lt;br /&gt;
            current = addTo&lt;br /&gt;
        '''if''' min.key &amp;gt; current.key &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;         // обновляем минимум, если нужно&amp;lt;/span&amp;gt;&lt;br /&gt;
            min = current     &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
'''Пример'''&lt;br /&gt;
&lt;br /&gt;
Изначально добавляем в нашу кучу &amp;lt;tex&amp;gt;7&amp;lt;/tex&amp;gt; элементов &amp;lt;tex&amp;gt;56, 22, 84, 32, 85, 15, 16&amp;lt;/tex&amp;gt;. После этого выполним операцию извлечения минимума:&lt;br /&gt;
&lt;br /&gt;
[[File:Fibonacci-heap-consolidate-example-1.png|thumb|center|500px|Начальное состояние кучи]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Удалим минимальный элемент из циклического корневого списка и заведем массив &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; для дальнейшего прорежения.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Fibonacci-heap-consolidate-example-2.png|thumb|center|500px|Удаление мимимума и создание массива]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Начнем процесс протяжения с первого элемента {{---}} &amp;lt;tex&amp;gt;56&amp;lt;/tex&amp;gt;. Его степень равна &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; поэтому запишем его адрес в нулевую ячейку массива.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Fibonacci-heap-consolidate-example-3.png|thumb|center|500px|Состояние массива после первой итерации]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Следующий элемент &amp;lt;tex&amp;gt;22&amp;lt;/tex&amp;gt; тоже имеет степень &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;. Возникает конфликт, который решается подвешиванием к меньшему корню большего. То есть к &amp;lt;tex&amp;gt;22&amp;lt;/tex&amp;gt; подвешиваем &amp;lt;tex&amp;gt;56&amp;lt;/tex&amp;gt; и увеличиваем степень &amp;lt;tex&amp;gt;22&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. В итоге степень &amp;lt;tex&amp;gt;22&amp;lt;/tex&amp;gt; равна &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Записываем адрес &amp;lt;tex&amp;gt;22&amp;lt;/tex&amp;gt; по индексу &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; в массив.&lt;br /&gt;
&lt;br /&gt;
[[File:Fibonacci-heap-consolidate-example-4.png.png|thumb|center|500px|Состояние после второй итерации]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Делаем тоже самое, что и на предыдущих итерациях, но теперь объединяем &amp;lt;tex&amp;gt;32&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;84&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Fibonacci-heap-consolidate-example-5.png|thumb|center|500px|Состояние после четвертой итерации]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Теперь у нас два элемента со степенью &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; в корневом списке. Объединим их подвесив к меньшему корню {{---}} &amp;lt;tex&amp;gt;22&amp;lt;/tex&amp;gt;, больший {{---}} &amp;lt;tex&amp;gt;32&amp;lt;/tex&amp;gt;. Теперь степень &amp;lt;tex&amp;gt;22&amp;lt;/tex&amp;gt; равна &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt;, запишем на &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; позицию массива обновленное значение.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Fibonacci-heap-consolidate-example-6.png|thumb|center|500px|Состояние после пятой итерации]] &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Ну и наконец аналогично объедений последние два элемента.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Fibonacci-heap-consolidate-example-7.png|thumb|center|500px|Финальное состояние кучи]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Уменьшение значения элемента ====&lt;br /&gt;
Основная идея: хотим, чтобы учетная стоимость данной операции была &amp;lt;tex&amp;gt; O(1) &amp;lt;/tex&amp;gt;. Было бы хорошо, чтобы вершина не всплывала до корня, и тогда дерево не придется сильно перестраивать. Для этого при удобном случае будем вырезать поддерево полностью и перемещать его в корневой [[Список |список]]. Итак, сам алгоритм:&lt;br /&gt;
&lt;br /&gt;
# Проверяем, если новое значение ключа все же не меньше значения ключа родителя, то все хорошо, и мы выходим.&lt;br /&gt;
# Иначе, вырезаем дерево с текущей вершиной в корневой [[Список |список]], и производим каскадное вырезание родителя. &lt;br /&gt;
&amp;lt;code style=&amp;quot;display:inline-block&amp;quot;&amp;gt;&lt;br /&gt;
 '''function''' decreaseKey(x: '''Node''', newValue: '''int'''):&lt;br /&gt;
    '''if''' newValue &amp;gt; x.parent.key &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt; // если после изменения структкра дерева сохранится, то меняем и выходим&amp;lt;/span&amp;gt;&lt;br /&gt;
        x.key = newValue&lt;br /&gt;
        '''return'''&lt;br /&gt;
    '''Node''' parent = x.parent &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;    // иначе вызываем cut и cascadingCut&amp;lt;/span&amp;gt;&lt;br /&gt;
    cut(x)&lt;br /&gt;
    cascadingCut(x.parent)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
===== Вырезание =====&lt;br /&gt;
При вырезании вершины мы удаляем ее из списка детей своего родителя, уменьшаем степень ее родителя (&amp;lt;tex&amp;gt; x.p.degree &amp;lt;/tex&amp;gt;) и снимаем пометку с текущей вершины (&amp;lt;tex&amp;gt; x.mark = false &amp;lt;/tex&amp;gt;).&lt;br /&gt;
&amp;lt;code style=&amp;quot;display:inline-block&amp;quot;&amp;gt;&lt;br /&gt;
 '''function''' cut(x: '''Node''')&lt;br /&gt;
    '''Node''' L = x.left&lt;br /&gt;
    '''Node''' R = x.right&lt;br /&gt;
    R.left = L &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;               // аккуратно удаляем текущую вершину&amp;lt;/span&amp;gt;&lt;br /&gt;
    L.right = R&lt;br /&gt;
    x.right = x&lt;br /&gt;
    x.left = x&lt;br /&gt;
    x.parent.degree--&lt;br /&gt;
    '''if''' x.parent.child = x &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;  // чтобы родитель не потерял ссылку на сыновей проверяем: &amp;lt;/span&amp;gt;&lt;br /&gt;
        '''if''' x.right = x. &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;    // если узел который мы вырезаем содержится в родителе, то меняем его на соседний&amp;lt;/span&amp;gt;&lt;br /&gt;
            x.parent.child &amp;lt;tex&amp;gt;= \varnothing&amp;lt;/tex&amp;gt; &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt; // иначе у родителтя больше нет детей&amp;lt;/span&amp;gt;&lt;br /&gt;
        '''else'''&lt;br /&gt;
            x.parent.child = x.right&lt;br /&gt;
    x.parent &amp;lt;tex&amp;gt;= \varnothing&amp;lt;/tex&amp;gt;&lt;br /&gt;
    unionLists(min, x) &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;       // вставляем наше поддерево в корневой список&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
===== Каскадное вырезание =====&lt;br /&gt;
Перед вызовом каскадного вырезания нам известно, удаляли ли ребенка у этой вершины. Если у вершины до этого не удаляли дочерний узел (&amp;lt;tex&amp;gt; x.mark = false &amp;lt;/tex&amp;gt;), то мы помечаем эту вершину (&amp;lt;tex&amp;gt; x.mark = true &amp;lt;/tex&amp;gt;) и прекращаем выполнение операции. В противном случае применяем операцию &amp;lt;tex&amp;gt;\mathrm {cut}&amp;lt;/tex&amp;gt; для текущей вершины и запускаем каскадное вырезание от родителя.&lt;br /&gt;
[[File:Каскадное вырезание.png|thumb|500px|Пример каскадного вырезания]]&lt;br /&gt;
&amp;lt;code style=&amp;quot;display:inline-block&amp;quot;&amp;gt;&lt;br /&gt;
 '''function''' cascadingCut(x: '''Node''')&lt;br /&gt;
    '''while''' x.mark = '''true''' &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt; // пока у нас помеченые вершины вырезаем их&amp;lt;/span&amp;gt;&lt;br /&gt;
        cut(x)&lt;br /&gt;
        x = x.parent&lt;br /&gt;
    x.mark = true &amp;lt;span style=&amp;quot;color:#008000&amp;quot;&amp;gt;        // последнюю вершину нужно пометить {{---}} у нее удаляли ребенка&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/code&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;3&amp;lt;/tex&amp;gt; фибоначчиевых деревьев. У вершины с ключом &amp;lt;tex&amp;gt;24&amp;lt;/tex&amp;gt; отсутствует &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; ребенок.&lt;br /&gt;
* Уменьшаем ключ &amp;lt;tex&amp;gt;26&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;5&amp;lt;/tex&amp;gt; и делаем операцию &amp;lt;tex&amp;gt;\mathrm {cut}&amp;lt;/tex&amp;gt; этого дерева. Получаем кучу с &amp;lt;tex&amp;gt;4&amp;lt;/tex&amp;gt; деревьями и новым минимумом. Но у вершины с ключом &amp;lt;tex&amp;gt;24&amp;lt;/tex&amp;gt; был удален второй ребенок, поэтому запускам операцию &amp;lt;tex&amp;gt;\mathrm {cascadingCut}&amp;lt;/tex&amp;gt; для этой вершины: вырезаем ее, помещаем в корневой [[Список |список]] и помечаем ее родителя.&lt;br /&gt;
* У вершины с ключом &amp;lt;tex&amp;gt;7&amp;lt;/tex&amp;gt; удален лишь один ребенок, поэтому операция &amp;lt;tex&amp;gt;\mathrm {cascadingCut}&amp;lt;/tex&amp;gt; от нее не запускается. В итоге, получаем кучу, состоящую из &amp;lt;tex&amp;gt;5&amp;lt;/tex&amp;gt; фибоначчиевых деревьев.&lt;br /&gt;
&lt;br /&gt;
==== Удаление элемента ====&lt;br /&gt;
Удаление вершины реализуется через уменьшение ее ключа до &amp;lt;tex&amp;gt; -\infty &amp;lt;/tex&amp;gt; и последующим извлечением минимума.&lt;br /&gt;
&amp;lt;code style=&amp;quot;display:inline-block&amp;quot;&amp;gt;&lt;br /&gt;
 '''function''' delete(x: '''Node''')&lt;br /&gt;
    decreaseKey(x, &amp;lt;tex&amp;gt;-\infty&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    deleteMin()&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
== Время работы ==&lt;br /&gt;
==== Потенциал ====&lt;br /&gt;
Для анализа производительности операций введем потенциал для фибоначчиевой кучи как &amp;lt;tex&amp;gt; \Phi = trees + 2 * marked &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt; trees &amp;lt;/tex&amp;gt; {{---}} количество элементов в корневом списке кучи, а &amp;lt;tex&amp;gt; marked &amp;lt;/tex&amp;gt; {{---}} количество вершин, у которых удален один ребенок (то есть вершин с пометкой &amp;lt;tex&amp;gt; x.mark = true &amp;lt;/tex&amp;gt;). Договоримся, что единицы потенциала достаточно для оплаты константного количества работы.&lt;br /&gt;
==== Cоздание кучи ====&lt;br /&gt;
Очевидно, что реальное время работы {{---}} &amp;lt;tex&amp;gt; O(1) &amp;lt;/tex&amp;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;tex&amp;gt; trees(H') = trees(H) + 1 &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; marked(H') = marked(H) &amp;lt;/tex&amp;gt;. Следовательно, увеличение потенциала составляет &amp;lt;tex&amp;gt; (trees(H) + 1 + 2 * marked(H)) - (trees(H) + 2 * marked(H)) = 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;.&lt;br /&gt;
==== Получение минимального элемента ====&lt;br /&gt;
Истинное время работы {{---}} &amp;lt;tex&amp;gt; O(1) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
==== Соедининение двух куч ====&lt;br /&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;tex&amp;gt; \Phi_{n + 1} - \Phi_n = 0 &amp;lt;/tex&amp;gt;.&lt;br /&gt;
==== Удаление минимального элемента====&lt;br /&gt;
Для доказательства времени работы этого алгоритма нам понадобится доказать несколько вспомогательных утверждений.&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=Лемма1&lt;br /&gt;
|statement=Для всех целых &amp;lt;tex&amp;gt; n \geqslant 2&amp;lt;/tex&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt; F_n = 1 + \sum\limits_{i=0}^{n-2} F_i &amp;lt;/tex&amp;gt;,&lt;br /&gt;
где &amp;lt;tex&amp;gt; F_n &amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt;-ое число Фибоначчи, определяемое формулой:&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
F_n =&lt;br /&gt;
\begin{cases}&lt;br /&gt;
 0, &amp;amp; n = 0 \\&lt;br /&gt;
 1, &amp;amp; n = 1 \\&lt;br /&gt;
 F_{n-1} + F_{n-2}, &amp;amp; n \geqslant 2&lt;br /&gt;
\end{cases} &amp;lt;/tex&amp;gt;&lt;br /&gt;
|proof=&lt;br /&gt;
Докажем лемму по индукции:&lt;br /&gt;
&lt;br /&gt;
при &amp;lt;tex&amp;gt;n = 2&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;F_2 = 1 + \sum\limits_{i=0}^0 F_i = 1 + 0 = 1&amp;lt;/tex&amp;gt;, что действительно верно.&lt;br /&gt;
&lt;br /&gt;
По индукции предполагаем, что &amp;lt;tex&amp;gt;F_{n-1} = 1 + \sum\limits_{i=0}^{n-3} F_i &amp;lt;/tex&amp;gt;. Тогда&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;F_n = F_{n-1} + F_{n-2} = 1 + \sum\limits_{i=0}^{n-3} F_i + F_{n-2} = 1 + \sum\limits_{i=0}^{n-2} F_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=Лемма2&lt;br /&gt;
|statement= Фибоначчиево дерево порядка &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; содержит не менее &amp;lt;tex&amp;gt;F_n&amp;lt;/tex&amp;gt; вершин.&lt;br /&gt;
|proof=&lt;br /&gt;
Докажем это утверждение по индукции.&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;s_n&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;n = 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;s_0 = 1 &amp;gt; F_0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При &amp;lt;tex&amp;gt;n = 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;s_1 = 1 = F_1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Предположим по индукции, что для всех &amp;lt;tex&amp;gt;i &amp;lt; n \ s_i \geqslant F_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Пусть в нашем дереве удалено поддерево порядка &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt;. Тогда&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;s_n = 1 + \sum\limits_{i=0}^{n-2} s_i \geqslant 1 + \sum\limits_{i=0}^{n-2} F_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Но по предыдущей [[#Лемма1|лемме]] :&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;tex&amp;gt;1 + \sum\limits_{i=0}^{n-2} F_i = F_n&amp;lt;/tex&amp;gt;. Следовательно, &amp;lt;tex&amp;gt;s_n \geqslant F_n&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=Лемма3&lt;br /&gt;
|statement= &amp;lt;tex&amp;gt;F_n =O(\varphi^n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex dpi=&amp;quot;160&amp;quot;&amp;gt; \varphi = \frac {1 + \sqrt 5} {2}&amp;lt;/tex&amp;gt;&lt;br /&gt;
|proof=&lt;br /&gt;
Для начала докажем, что &amp;lt;tex&amp;gt;F_n =&amp;lt;/tex&amp;gt; &amp;lt;tex dpi=&amp;quot;160&amp;quot;&amp;gt;\frac {\varphi^n - (-\varphi)^{-n}} {\sqrt 5}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Используем для этого математическую индукцию.&lt;br /&gt;
&lt;br /&gt;
При &amp;lt;tex&amp;gt;n = 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;F_0 =&amp;lt;/tex&amp;gt; &amp;lt;tex dpi=&amp;quot;160&amp;quot;&amp;gt;\frac {\varphi^0 - (-\varphi)^0} {\sqrt 5} = \frac {1 - 1} {\sqrt 5} = 0&amp;lt;/tex&amp;gt;, что верно.&lt;br /&gt;
&lt;br /&gt;
При &amp;lt;tex&amp;gt;n = 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;F_1 =&amp;lt;/tex&amp;gt; &amp;lt;tex dpi=&amp;quot;160&amp;quot;&amp;gt;\frac {\varphi^1 - (-\varphi)^{-1}} {\sqrt 5} = \frac {1} {\sqrt 5}(\frac {1 + \sqrt 5} {2} - \frac {1 - \sqrt 5} {2}) = \frac {2\sqrt 5} {2\sqrt 5} = 1&amp;lt;/tex&amp;gt;, что также верно.&lt;br /&gt;
&lt;br /&gt;
По индукции предполагаем, что &amp;lt;tex&amp;gt;F_{n-1} =&amp;lt;/tex&amp;gt; &amp;lt;tex dpi=&amp;quot;160&amp;quot;&amp;gt;\frac {\varphi^{n-1} - (-\varphi)^{1-n}} {\sqrt 5}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;F_{n-2} =&amp;lt;/tex&amp;gt; &amp;lt;tex dpi=&amp;quot;160&amp;quot;&amp;gt;\frac {\varphi^{n-2} - (-\varphi)^{2-n}} {\sqrt 5}&amp;lt;/tex&amp;gt;. Тогда&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;F_n = F_{n-1} + F_{n-2} =&amp;lt;/tex&amp;gt; &amp;lt;tex dpi=&amp;quot;160&amp;quot;&amp;gt;\frac {\varphi^{n-1} - (-\varphi)^{1-n}} {\sqrt 5} + \frac {\varphi^{n-2} - (-\varphi)^{2-n}} {\sqrt 5} =&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex dpi=&amp;quot;160&amp;quot;&amp;gt;= \frac {1} {\sqrt 5}&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;(\varphi^{n-1} - (-\varphi)^{1-n} + \varphi^{n-2} - (-\varphi)^{2-n}) &amp;lt;/tex&amp;gt; &amp;lt;tex dpi=&amp;quot;160&amp;quot;&amp;gt;= \frac {1} {\sqrt 5}&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;(\varphi^{n}(\varphi^{-1} + \varphi^{-2}) - (-\varphi)^{-n}(-\varphi + \varphi^{2}))&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подставив вместо &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt; его значение, нетрудно убедится, что &amp;lt;tex&amp;gt;\varphi^{-1} + \varphi^{-2} = -\varphi + \varphi^{2} = 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Поскольку &amp;lt;tex&amp;gt;\left\vert (-\varphi)^{-1} \right\vert &amp;lt; 1&amp;lt;/tex&amp;gt;, то выполняются неравенства &amp;lt;tex dpi=&amp;quot;160&amp;quot;&amp;gt;\frac {(-\varphi)^{-n}} {\sqrt 5} &amp;lt; \frac {1} {\sqrt 5} &amp;lt; \frac {1} {2}&amp;lt;/tex&amp;gt;. Таким образом, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-ое число Фибоначчи равно &amp;lt;tex dpi=&amp;quot;160&amp;quot;&amp;gt;\frac {\varphi^{n}} {\sqrt 5}&amp;lt;/tex&amp;gt;, округленному до ближайшего целого числа. Следовательно, &amp;lt;tex&amp;gt;F_n =O(\varphi^n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=Лемма4&lt;br /&gt;
|statement=Максимальная степень &amp;lt;tex&amp;gt;degree&amp;lt;/tex&amp;gt; произвольной вершины в фибоначчиевой куче с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами равна &amp;lt;tex&amp;gt;O(\log n)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|proof=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; {{---}} произвольная вершина в фибоначчиевой куче с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами, и пусть &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; {{---}} степень вершины &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Тогда по [[#Лемма2|доказанному выше]] в дереве, корень которого &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, содержится не менее &amp;lt;tex&amp;gt;F_k&amp;lt;/tex&amp;gt; вершин, что в свою очередь по [[#Лемма3|лемме]] равно &amp;lt;tex&amp;gt;O(\varphi^k)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
То есть&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;n \geqslant \varphi^{k}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Логарифмируя по основанию &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt;, получаем&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\log_{\varphi}n \geqslant k&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, максимальная степень &amp;lt;tex&amp;gt;degree&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;
Итоговая асимптотика операции &amp;lt;tex&amp;gt;\mathrm {extraxtMin}&amp;lt;/tex&amp;gt;, учитывая и вспомогательную функцию &amp;lt;tex&amp;gt; \mathrm {consolidate} &amp;lt;/tex&amp;gt;, время работы которой доказывается ниже, равно: &amp;lt;tex&amp;gt; O(1)+O(degree)+O(degree)=O(degree) &amp;lt;/tex&amp;gt;. По доказанной выше [[#Лемма4|лемме]] &amp;lt;tex&amp;gt;O(degree) = O(\log(n))&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Учетная стоимость &amp;lt;tex&amp;gt; \mathrm {consolidate} &amp;lt;/tex&amp;gt; равна &amp;lt;tex&amp;gt; O(degree) &amp;lt;/tex&amp;gt;. Докажем это:&lt;br /&gt;
&lt;br /&gt;
Изначально в корневом списке было не более &amp;lt;tex&amp;gt; degree + trees - 1 &amp;lt;/tex&amp;gt; вершин, поскольку он состоит из исходного списка корней с &amp;lt;tex&amp;gt;trees&amp;lt;/tex&amp;gt; узлами, минус извлеченный узел и плюс дочерние узлы, количество которых не превышает &amp;lt;tex&amp;gt; degree &amp;lt;/tex&amp;gt;. В ходе операции &amp;lt;tex&amp;gt; \mathrm {consolidate} &amp;lt;/tex&amp;gt; мы сделали &amp;lt;tex&amp;gt; O(degree + trees) &amp;lt;/tex&amp;gt; слияний деревьев. Потенциал перед извлечением минимума равен &amp;lt;tex&amp;gt; trees + 2 * marked &amp;lt;/tex&amp;gt;, а после не превышает &amp;lt;tex&amp;gt; degree + 1 + 2 * marked&amp;lt;/tex&amp;gt;, поскольку в корневом списке остается не более  &amp;lt;tex&amp;gt; degree + 1 &amp;lt;/tex&amp;gt; узлов, а количество помеченных узлов не изменяется. Таким образом, амортизированная стоимость не превосходит&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; O(degree + trees) + (degree + 1 + 2 * marked) - (trees + 2 * marked) = O(degree) + O(trees) - trees&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Поскольку мы договорились, что можем масштабировать единицу потенциала таким образом, чтобы покрывать константное количество работы, то итоговая амортизационная оценка {{---}} &amp;lt;tex&amp;gt; O(degree) &amp;lt;/tex&amp;gt;&lt;br /&gt;
==== Уменьшение значения элемента ====&lt;br /&gt;
Докажем, что амортизированное время работы операции &amp;lt;tex&amp;gt; \mathrm {decreaseKey} &amp;lt;/tex&amp;gt; есть &amp;lt;tex&amp;gt; O(1) &amp;lt;/tex&amp;gt;. Поскольку в процедуре нет циклов, ее время работы определяется лишь количеством рекурсивных вызовов каскадного вырезания.&lt;br /&gt;
&lt;br /&gt;
Пусть мы вызвали процедуру каскадного вырезания подверглось &amp;lt;tex&amp;gt; k &amp;lt;/tex&amp;gt; раз. Так как реальное время работы каждой итерации &amp;lt;tex&amp;gt; \mathrm {cascadingCut} &amp;lt;/tex&amp;gt; составляет &amp;lt;tex&amp;gt; O(1) &amp;lt;/tex&amp;gt;, то реальное время работы операции &amp;lt;tex&amp;gt; \mathrm {decreaseKey} &amp;lt;/tex&amp;gt; {{---}} &amp;lt;tex&amp;gt; O(k) &amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим, как изменится потенциал в результате выполнения данной операции. Пусть &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt; {{---}} фибоначчиева куча до вызова &amp;lt;tex&amp;gt; \mathrm {decreaseKey} &amp;lt;/tex&amp;gt;. Тогда после &amp;lt;tex&amp;gt; k &amp;lt;/tex&amp;gt; итераций операции &amp;lt;tex&amp;gt; \mathrm {cascadingCut} &amp;lt;/tex&amp;gt; вершин с пометкой &amp;lt;tex&amp;gt; x.mark = true &amp;lt;/tex&amp;gt; стало как минимум на &amp;lt;tex&amp;gt; k - 2 &amp;lt;/tex&amp;gt; меньше, потому что каждый вызов каскадного вырезания, за исключением последнего, уменьшает количество помеченных вершин на одну, и в результате последнего вызова одну вершину мы можем пометить. В корневом списке прибавилось &amp;lt;tex&amp;gt; k &amp;lt;/tex&amp;gt; новых деревьев (&amp;lt;tex&amp;gt; k - 1 &amp;lt;/tex&amp;gt; дерево за счет каскадного вырезания и еще одно из-за самого первого вызова операции &amp;lt;tex&amp;gt; \mathrm {cut} &amp;lt;/tex&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
В итоге, изменение потенциала составляет: &amp;lt;tex&amp;gt; \Phi_i - \Phi_{i - 1} = ((trees + k) + 2 * (marked + k - 2)) - (trees + 2 * marked) = 4 - k &amp;lt;/tex&amp;gt;. Следовательно, амортизированная стоимость не превышает &amp;lt;tex&amp;gt; O(k) + 4 - k &amp;lt;/tex&amp;gt;. Но поскольку мы можем соответствующим образом масштабировать единицы потенциала, то амортизированная стоимость операции &amp;lt;tex&amp;gt; \mathrm {decreaseKey} &amp;lt;/tex&amp;gt; равна &amp;lt;tex&amp;gt; O(1) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
==== Удаление элемента ====&lt;br /&gt;
Амортизированное время работы: &amp;lt;tex&amp;gt; O(1) + O(degree) = O(degree) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Поскольку ранее мы показали, что &amp;lt;tex&amp;gt; degree = O(\log n ) &amp;lt;/tex&amp;gt;, то соответствующие оценки доказаны.&lt;br /&gt;
==== Итоговая таблица ====&lt;br /&gt;
{| style=&amp;quot;background-color:#CCC;margin:0.5px&amp;quot;&lt;br /&gt;
!style=&amp;quot;background-color:#EEE&amp;quot;| Операция&lt;br /&gt;
!style=&amp;quot;background-color:#EEE&amp;quot;| Амортизированная сложность&lt;br /&gt;
|-align=&amp;quot;center&amp;quot;&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| &amp;lt;tex&amp;gt;\mathrm {makeHeap}&amp;lt;/tex&amp;gt;&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt; &lt;br /&gt;
|-align=&amp;quot;center&amp;quot;&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| &amp;lt;tex&amp;gt;\mathrm {insert}&amp;lt;/tex&amp;gt;&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt; &lt;br /&gt;
|-align=&amp;quot;center&amp;quot;&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| &amp;lt;tex&amp;gt;\mathrm {getMin}&amp;lt;/tex&amp;gt;&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt; &lt;br /&gt;
|-align=&amp;quot;center&amp;quot;&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| &amp;lt;tex&amp;gt;\mathrm {merge}&amp;lt;/tex&amp;gt;&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt; &lt;br /&gt;
|-align=&amp;quot;center&amp;quot;&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| &amp;lt;tex&amp;gt;\mathrm {extractMin}&amp;lt;/tex&amp;gt;&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| &amp;lt;tex&amp;gt;O(\log n )&amp;lt;/tex&amp;gt; &lt;br /&gt;
|-align=&amp;quot;center&amp;quot;&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| &amp;lt;tex&amp;gt;\mathrm {decreaseKey}&amp;lt;/tex&amp;gt;&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt; &lt;br /&gt;
|-align=&amp;quot;center&amp;quot;&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| &amp;lt;tex&amp;gt;\mathrm {delete}&amp;lt;/tex&amp;gt;&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| &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;
* Большое потребление памяти на узел(минимум 21 байт)&lt;br /&gt;
* Большая константа времени работы, что делает ее малоприменимой для реальных задач&lt;br /&gt;
* Некоторые операции могут в худшем случае могут работать за &amp;lt;tex&amp;gt;O(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;
* [[Биномиальная куча]]&lt;br /&gt;
* [[Левосторонняя куча]]&lt;br /&gt;
* [[Тонкая куча]]&lt;br /&gt;
* [[Толстая куча на избыточном счетчике]]&lt;br /&gt;
* [[Куча Бродала-Окасаки]]&lt;br /&gt;
== Примечания ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* Томас Кормен, Чарльз Лейзерсон, Рональд Ривест, Клиффорд Штайн — Алгоритмы: построение и анализ. — М.: Издательский дом «Вильямс», 2005. — С. 1296. — ISBN 5-8459-0857-4&lt;br /&gt;
* [[wikipedia:en:Числа Фибоначчи|Числа Фибоначчи {{---}} Википедия]]&lt;br /&gt;
* [[wikipedia:en:Fibonacci heap|Фибоначчиева куча {{---}} Википедия]]&lt;br /&gt;
* [https://www.cs.usfca.edu/~galles/visualization/FibonacciHeap.html Fibonacci heap visualization]&lt;br /&gt;
* [http://www.intuit.ru/department/algorithms/dscm/7/2.html Фибоначчиевы кучи — INTUIT.ru]&lt;br /&gt;
* [http://www.cs.duke.edu/courses/fall05/cps230/L-11.pdf Fibonacci Heaps {{---}} Duke University]&lt;br /&gt;
* [https://www.cs.princeton.edu/~wayne/teaching/fibonacci-heap.pdf Fibonacci Heaps {{---}} Princeton University]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Приоритетные очереди]]&lt;/div&gt;</summary>
		<author><name>188.227.78.59</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=59605</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=59605"/>
				<updated>2017-01-14T16:54:39Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: &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;/div&gt;</summary>
		<author><name>188.227.78.59</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=59595</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=59595"/>
				<updated>2017-01-14T11:17:49Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: &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;
* Хопкрофт Д., Мотвани Р., Ульман Д. {{---}} Введение в теорию автоматов, языков и вычислений&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>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Broadcast._Broadcast_routing&amp;diff=57746</id>
		<title>Broadcast. Broadcast routing</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Broadcast._Broadcast_routing&amp;diff=57746"/>
				<updated>2016-12-12T19:58:03Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Широковещательный канал, широковещание''' (англ. broadcasting) {{---}} метод передачи данных в компьютерных сетях, при котором поток данных (каждый переданный пакет в случае пакетной передачи) предназначен для приёма всеми участниками сети.&lt;br /&gt;
&lt;br /&gt;
'''Широковещательная маршрутизация''' (англ. broadcast routing) {{---}} маршрутизация, сопровождающаяся передачей служебной информации в широковещательном режиме.&lt;br /&gt;
&lt;br /&gt;
=Описание=&lt;br /&gt;
По умолчанию, широковещательные пакеты не направляются и не перенаправляются маршрутизаторами в любой сети. Маршрутизаторы создают широковещательные домены. Но он может быть настроен на пересылку в некоторых особых случаях. &lt;br /&gt;
&lt;br /&gt;
[[Файл:Broadcast_routing.jpg]]&lt;br /&gt;
&lt;br /&gt;
Выполнение широковещательной маршрутизации может быть произведено разными способами NPtp и Flooding&lt;br /&gt;
&lt;br /&gt;
==N Point - to - point==&lt;br /&gt;
Маршрутизатор создает пакет данных, а затем отправляет его на каждом хосте один за другим. В этом случае маршрутизатор создает несколько копий одного пакета данных с разными адресами назначения. Все пакеты посылаются как одноадресные, но они направляются на все адреса назначения, таким образом имитируется маршрутизатор широковещания. Этот метод потребляет много трафика и маршрутизатор должен знать адрес назначения каждого узла.&lt;br /&gt;
&lt;br /&gt;
==Flooding==&lt;br /&gt;
Когда маршрутизатор получает пакет, который должен быть передан, он просто посылает эти пакеты из всех интерфейсов. Все маршрутизаторы настроены таким же образом. Этот метод прост на CPU маршрутизатора, но нужно проверять наличие дублирующихся пакетов.&lt;br /&gt;
&lt;br /&gt;
=Безопасность сети=&lt;br /&gt;
Размножение широковещательных сообщений активным сетевым оборудованием, приводящее к экспоненциальному росту пакетов, некорректно сформированные пакеты, кольца в топологии компьютерной сети могут привести к т. н. ''широковещательной радиации'' (англ. broadcast radiation) {{---}} накоплению широковещательной передачи трафика в компьютерной сети. Экстремальные объемы широковещательного трафика составляют ''широковещательный шторм'' (англ. broadcast storm). Широковещательный шторм может потреблять достаточное количество сетевых ресурсов, с тем чтобы сделать сеть не в состоянии транспортировать нормальный трафик.&lt;br /&gt;
&lt;br /&gt;
==STP==&lt;br /&gt;
Spanning Tree Protocol (STP, протокол остовного дерева) — канальный протокол. STP решает задачу устранение петель в топологии произвольной сети Ethernet, в которой есть один или более сетевых мостов, связанных избыточными соединениями, автоматически блокируя соединения, которые в данный момент для полной связности коммутаторов являются избыточными.&lt;br /&gt;
&lt;br /&gt;
==RPF==&lt;br /&gt;
Reverse path forwarding - оптимизация алгоритмов маршрутизации для избавления от дублирующихся пакетов, использующая sink tree - входное дерево путей, ведущих к некоторому узлу в сети. Когда пакет поступает от маршрутизатора X, если пакет прибыл на линию дерева, ведущего к X, пакет движется по кратчайшему пути, поэтому он должен быть первым экземпляром - надо скопировать пакет на всех отходящих линиях. Если пакет поступает на другой линии, предположим, что пакет является копией - он не прибыл по кратчайшему пути - и отказаться от него. RPF обеспечивает эффективное использование полосы пропускания.&lt;br /&gt;
&lt;br /&gt;
=См. также=&lt;br /&gt;
* [[Сетевой уровень]]&lt;br /&gt;
* [[Мультикаст. Мультикаст маршрутизация]]&lt;br /&gt;
&lt;br /&gt;
=Источники информации=&lt;br /&gt;
*[https://en.wikipedia.org/wiki/Broadcasting_(networking) Broadcasting]&lt;br /&gt;
*[https://en.wikipedia.org/wiki/Broadcast_radiation Broadcast radiation]&lt;br /&gt;
*[https://en.wikipedia.org/wiki/Spanning_Tree_Protocol Spanning tree protocol]&lt;br /&gt;
*[https://en.wikipedia.org/wiki/Reverse_path_forwarding Reverse path forwarding]&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=Broadcast._Broadcast_routing&amp;diff=57681</id>
		<title>Broadcast. Broadcast routing</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=Broadcast._Broadcast_routing&amp;diff=57681"/>
				<updated>2016-12-12T16:06:57Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Широковещательный канал, широковещание''' (англ. broadcasting) {{---}} метод передачи данных в компьютерных сетях, при котором поток данных (каждый переданный пакет в случае пакетной передачи) предназначен для приёма всеми участниками сети.&lt;br /&gt;
&lt;br /&gt;
'''Широковещательная маршрутизация''' (англ. broadcast routing) {{---}} маршрутизация, сопровождающаяся передачей служебной информации в широковещательном режиме.&lt;br /&gt;
&lt;br /&gt;
=Описание=&lt;br /&gt;
По умолчанию, широковещательные пакеты не направляются и не перенаправляются маршрутизаторами в любой сети. Маршрутизаторы создают широковещательные домены. Но он может быть настроен на пересылку в некоторых особых случаях. Широковещательное сообщение предназначено для всех сетевых устройств.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Broadcast_routing.jpg]]&lt;br /&gt;
&lt;br /&gt;
Выполнение широковещательной маршрутизации может быть произведено разными способами NPtp и Flooding&lt;br /&gt;
&lt;br /&gt;
==N Point - to - point==&lt;br /&gt;
Маршрутизатор создает пакет данных, а затем отправляет его на каждом хосте один за другим. В этом случае маршрутизатор создает несколько копий одного пакета данных с разными адресами назначения. Все пакеты посылаются как одноадресные, но они направляются на все адреса назначения, таким образом имитируется маршрутизатор широковещания. Этот метод потребляет много трафика и маршрутизатор должен знать адрес назначения каждого узла.&lt;br /&gt;
&lt;br /&gt;
==Flooding==&lt;br /&gt;
Когда маршрутизатор получает пакет, который должен быть передан, он просто посылает эти пакеты из всех интерфейсов. Все маршрутизаторы настроены таким же образом. Этот метод прост на CPU маршрутизатора, но нужно проверять наличие дублирующихся пакетов.&lt;br /&gt;
&lt;br /&gt;
=Безопасность сети=&lt;br /&gt;
Размножение широковещательных сообщений активным сетевым оборудованием, приводящее к экспоненциальному росту пакетов, некорректно сформированные пакеты, кольца в топологии компьютерной сети могут привести к т. н. ''широковещательной радиации'' (англ. broadcast radiation) {{---}} накоплению широковещательной передачи трафика в компьютерной сети. Экстремальные объемы широковещательного трафика составляют ''широковещательный шторм'' (англ. broadcast storm). Широковещательный шторм может потреблять достаточное количество сетевых ресурсов, с тем чтобы сделать сеть не в состоянии транспортировать нормальный трафик. Пакет, который вызывает такую бурю назвали пакет Чернобыльской АЭС.&lt;br /&gt;
&lt;br /&gt;
==STP==&lt;br /&gt;
Spanning Tree Protocol (STP, протокол остовного дерева) — канальный протокол. STP решает задачу устранение петель в топологии произвольной сети Ethernet, в которой есть один или более сетевых мостов, связанных избыточными соединениями, автоматически блокируя соединения, которые в данный момент для полной связности коммутаторов являются избыточными.&lt;br /&gt;
&lt;br /&gt;
==RPF==&lt;br /&gt;
Reverse path forwarding - оптимизация алгоритмов маршрутизации для избавления от дублирующихся пакетов, использующая sink tree - входное дерево путей, ведущих к некоторому узлу в сети. Когда пакет поступает от маршрутизатора X, если пакет прибыл на линию дерева, ведущего к X, пакет движется по кратчайшему пути, поэтому он должен быть первым экземпляром - надо скопировать пакет на всех отходящих линиях. Если пакет поступает на другой линии, предположим, что пакет является копией - он не прибыл по кратчайшему пути - и отказаться от него. RPF обеспечивает эффективное использование полосы пропускания.&lt;br /&gt;
&lt;br /&gt;
=См. также=&lt;br /&gt;
* [[Сетевой уровень]]&lt;br /&gt;
* [[Мультикаст. Мультикаст маршрутизация]]&lt;br /&gt;
&lt;br /&gt;
=Источники информации=&lt;br /&gt;
*[https://en.wikipedia.org/wiki/Broadcasting_(networking) Broadcasting]&lt;br /&gt;
*[https://en.wikipedia.org/wiki/Broadcast_radiation Broadcast radiation]&lt;br /&gt;
*[https://en.wikipedia.org/wiki/Spanning_Tree_Protocol Spanning tree protocol]&lt;br /&gt;
*[https://en.wikipedia.org/wiki/Reverse_path_forwarding Reverse path forwarding]&lt;/div&gt;</summary>
		<author><name>188.227.78.59</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=55765</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=55765"/>
				<updated>2016-11-04T14:06:09Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: &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;
Пусть &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>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54481</id>
		<title>PSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54481"/>
				<updated>2016-06-04T19:15:59Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: /* Псевдокод */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ с заданными временами выполнения &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; параллельных станков с одинаковой скоростью выполнения работ.&amp;lt;br&amp;gt;Цель {{---}} составить такое расписание, чтобы суммарное время окончания всех работ было минимальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; заданы в порядке невозрастания (&amp;lt;tex&amp;gt;p_{0}  \geqslant p_{1} \geqslant \ldots \geqslant p_{n-1} &amp;lt;/tex&amp;gt;). Пусть теперь &amp;lt;tex&amp;gt;b_{i} = \left\lceil\dfrac{i}{m}\right\rceil&amp;lt;/tex&amp;gt;. Тогда в оптимальном расписании работа с номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; будет выполнена на станке с номером &amp;lt;tex&amp;gt;i \bmod m&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;b_{i}&amp;lt;/tex&amp;gt;-ой с конца.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Итоговым расписанием будет массив  &amp;lt;tex&amp;gt;\mathtt{schedule}&amp;lt;/tex&amp;gt;  где в  &amp;lt;tex&amp;gt;\mathtt{schedule[i][j]}&amp;lt;/tex&amp;gt;  храниться номер работы которую надо исполнить на станке номер &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой по счёту.&lt;br /&gt;
&lt;br /&gt;
 '''function''' getSchedule(p : '''int'''[n]): '''list'''&amp;lt;'''int'''&amp;gt;[m]&lt;br /&gt;
   '''Pair'''&amp;lt;'''int''','''int'''&amp;gt; jobs[n]&lt;br /&gt;
   '''for''' i = 0 '''to''' n&lt;br /&gt;
     jobs[i] = &amp;lt;tex&amp;gt;\langle&amp;lt;/tex&amp;gt;p[i], i&amp;lt;tex&amp;gt;\rangle&amp;lt;/tex&amp;gt; &amp;lt;font color=green&amp;gt;// Создаём пары для востановления номера работы после сортировки.&amp;lt;/font&amp;gt;&lt;br /&gt;
   sort(jobs) &amp;lt;font color=green&amp;gt;// Cортируем массив в порядке уменьшения p[i].&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
   '''list'''&amp;lt;'''int'''&amp;gt; schedule[m] &amp;lt;font color=green&amp;gt; // Заведём список работ для каждого станка. Ответ будет храниться в нём.&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''for''' i = 0 '''to''' n&lt;br /&gt;
     schedule[i mod m].pushFront(jobs[i].second) &amp;lt;font color=green&amp;gt;// Cтавим i-ую в порядке уменьшения p[i] работу на станок i mod m в конец.&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
   '''return''' schedule&lt;br /&gt;
&lt;br /&gt;
=== Ассимптотика ===&lt;br /&gt;
Так как нам понадобится [[Быстрая сортировка | сортировка]] для массива &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, то итоговая ассимптотика будет &amp;lt;tex&amp;gt;\mathcal{O}(n\log{n})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
Докажем две леммы:&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|statement= В оптимальном расписании на каждом станке работы выполняются в порядке неубывания времён выполнения.&lt;br /&gt;
|proof= Пусть это не так. Заметим что &amp;lt;tex&amp;gt;\sum\limits_{i=0}^{n-1} C_{i} = \sum\limits_{i=0}^{n-1} p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Следовательно каждая работа даёт вклад равный &amp;lt;tex&amp;gt;p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Тогда поменяем местами две работы которые нарушают порядок невозрастания. Заметим что &amp;lt;tex&amp;gt;\sum\limits_{i=0}^{n-1} C_{i}&amp;lt;/tex&amp;gt; уменьшилась. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma2&lt;br /&gt;
|statement= В оптимальном расписании количество выполненных работ на любых двух станках отличается не более чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof= Пусть это не так. Как было отмечено в предыдущей лемме, каждая работа даёт вклад в &amp;lt;tex&amp;gt;\sum\limits_{i=0}^{n-1} C_{i}&amp;lt;/tex&amp;gt; равный &amp;lt;tex&amp;gt;p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Найдём два станка количество работ на которых отличается больше чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Пусть это станки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Причём на стнаке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; выполняется больше работ. Тогда если отправить первую с начала работу со станка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; на станок &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; то  &amp;lt;tex&amp;gt;\sum\limits_{i=0}^{n-1} C_{i}&amp;lt;/tex&amp;gt; уменьшится на разность количества работ на станках &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=theorem1&lt;br /&gt;
|statement= Алгоритм &amp;lt;tex&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt; строит оптимальное расписание.&lt;br /&gt;
|proof= Пусть это не так и оптимальное расписание отличается от расписания построенного алгоритмом. Заметим что расписание построенное алгоритмом удовлетворяет обеим леммам. Тогда можно воспользоваться одной из них чтобы улучшить оптимальное раписание. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие. }}&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[Pintreepi1Lmax|&amp;lt;tex&amp;gt;P \mid intree, p_{i} = 1 \mid L_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[PpmtnriLmax|&amp;lt;tex&amp;gt;P \mid pmtn, r_i \mid L_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Ppi1sumwu|&amp;lt;tex&amp;gt;P \mid p_i=1 \mid \sum w_i U_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 22&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54478</id>
		<title>PSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54478"/>
				<updated>2016-06-04T18:59:15Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ с заданными временами выполнения &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; параллельных станков с одинаковой скоростью выполнения работ.&amp;lt;br&amp;gt;Цель {{---}} составить такое расписание, чтобы суммарное время окончания всех работ было минимальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; заданы в порядке невозрастания (&amp;lt;tex&amp;gt;p_{0}  \geqslant p_{1} \geqslant \ldots \geqslant p_{n-1} &amp;lt;/tex&amp;gt;). Пусть теперь &amp;lt;tex&amp;gt;b_{i} = \left\lceil\dfrac{i}{m}\right\rceil&amp;lt;/tex&amp;gt;. Тогда в оптимальном расписании работа с номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; будет выполнена на станке с номером &amp;lt;tex&amp;gt;i \bmod m&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;b_{i}&amp;lt;/tex&amp;gt;-ой с конца.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Итоговым расписанием будет массив &amp;lt;tex&amp;gt;schedule&amp;lt;/tex&amp;gt; где в &amp;lt;tex&amp;gt;schedule[i][j]&amp;lt;/tex&amp;gt; храниться номер работы которую надо исполнить на станке номер &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой по счёту.&lt;br /&gt;
&lt;br /&gt;
 '''function''' getSchedule(jobs : '''int'''[n]): &amp;lt;font color=green&amp;gt;// jobs - массив номеров работ отсортированных в порядке невозрастания p[i].&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''list'''&amp;lt;'''int'''&amp;gt; schedule[m] &amp;lt;font color=green&amp;gt; // Заведём список работ для каждого станка. Ответ будет храниться в нём.&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
   '''for''' i = 0 '''to''' n&lt;br /&gt;
     schedule[i mod m].push(jobs[i]) &amp;lt;font color=green&amp;gt;// Cтавим i-ую в порядке уменьшения p[i] работу на станок i mod m в конец.&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// Заметим что расписание для каждого станка получилось перевёрнутым.&amp;lt;br&amp;gt;  // Поэтому развернём расписание для каждого станка.&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''for''' i = 0 '''to''' m&lt;br /&gt;
     schedule[i].reverse()&amp;lt;br&amp;gt;&lt;br /&gt;
   '''return''' schedule&lt;br /&gt;
&lt;br /&gt;
=== Ассимптотика ===&lt;br /&gt;
Так как нам понадобится [[Быстрая сортировка | сортировка]] для массива &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, то итоговая ассимптотика будет &amp;lt;tex&amp;gt;\mathcal{O}(n\log{n})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
Докажем две леммы:&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|statement= В оптимальном расписании на каждом станке работы выполняются в порядке неубывания времён выполнения.&lt;br /&gt;
|proof= Пусть это не так. Заметим что &amp;lt;tex&amp;gt;\sum\limits_{i=0}^{n-1} C_{i} = \sum\limits_{i=0}^{n-1} p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Следовательно каждая работа даёт вклад равный &amp;lt;tex&amp;gt;p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Тогда поменяем местами две работы которые нарушают порядок невозрастания. Заметим что &amp;lt;tex&amp;gt;\sum\limits_{i=0}^{n-1} C_{i}&amp;lt;/tex&amp;gt; уменьшилась. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma2&lt;br /&gt;
|statement= В оптимальном расписании количество выполненных работ на любых двух станках отличается не более чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof= Пусть это не так. Как было отмечено в предыдущей лемме, каждая работа даёт вклад в &amp;lt;tex&amp;gt;\sum\limits_{i=0}^{n-1} C_{i}&amp;lt;/tex&amp;gt; равный &amp;lt;tex&amp;gt;p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Найдём два станка количество работ на которых отличается больше чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Пусть это станки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Причём на стнаке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; выполняется больше работ. Тогда если отправить первую с начала работу со станка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; на станок &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; то  &amp;lt;tex&amp;gt;\sum\limits_{i=0}^{n-1} C_{i}&amp;lt;/tex&amp;gt; уменьшится на разность количества работ на станках &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=theorem1&lt;br /&gt;
|statement= Алгоритм &amp;lt;tex&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt; строит оптимальное расписание.&lt;br /&gt;
|proof= Пусть это не так и оптимальное расписание отличается от расписания построенного алгоритмом. Заметим что расписание построенное алгоритмом удовлетворяет обеим леммам. Тогда можно воспользоваться одной из них чтобы улучшить оптимальное раписание. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие. }}&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[Pintreepi1Lmax|&amp;lt;tex&amp;gt;P \mid intree, p_{i} = 1 \mid L_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[PpmtnriLmax|&amp;lt;tex&amp;gt;P \mid pmtn, r_i \mid L_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Ppi1sumwu|&amp;lt;tex&amp;gt;P \mid p_i=1 \mid \sum w_i U_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 22&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54477</id>
		<title>PSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54477"/>
				<updated>2016-06-04T18:56:19Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: /* Источники информации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ с заданными временами выполнения &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; параллельных станков с одинаковой скоростью выполнения работ.&amp;lt;br&amp;gt;Цель {{---}} составить такое расписание, чтобы суммарное время окончания всех работ было минимальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; заданы в порядке невозрастания (&amp;lt;tex&amp;gt;p_{0}  \geqslant p_{1} \geqslant \ldots \geqslant p_{n-1} &amp;lt;/tex&amp;gt;). Пусть теперь &amp;lt;tex&amp;gt;b_{i} = \left\lceil\dfrac{i}{m}\right\rceil&amp;lt;/tex&amp;gt;. Тогда в оптимальном расписании работа с номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; будет выполнена на станке с номером &amp;lt;tex&amp;gt;i \bmod m&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;b_{i}&amp;lt;/tex&amp;gt;-ой с конца.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Итоговым расписанием будет массив &amp;lt;tex&amp;gt;schedule&amp;lt;/tex&amp;gt; где в &amp;lt;tex&amp;gt;schedule[i][j]&amp;lt;/tex&amp;gt; храниться номер работы которую надо исполнить на станке номер &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой по счёту.&lt;br /&gt;
&lt;br /&gt;
 '''function''' getSchedule(jobs : '''int'''[n]): &amp;lt;font color=green&amp;gt;// jobs - массив номеров работ отсортированных в порядке невозрастания p[i].&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''list'''&amp;lt;'''int'''&amp;gt; schedule[m] &amp;lt;font color=green&amp;gt; // Заведём список работ для каждого станка. Ответ будет храниться в нём.&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
   '''for''' i = 0 '''to''' n&lt;br /&gt;
     schedule[i mod m].push(jobs[i]) &amp;lt;font color=green&amp;gt;// Cтавим i-ую в порядке уменьшения p[i] работу на станок i mod m в конец.&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// Заметим что расписание для каждого станка получилось перевёрнутым.&amp;lt;br&amp;gt;  // Поэтому развернём расписание для каждого станка.&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''for''' i = 0 '''to''' m&lt;br /&gt;
     schedule[i].reverse()&amp;lt;br&amp;gt;&lt;br /&gt;
   '''return''' schedule&lt;br /&gt;
&lt;br /&gt;
=== Ассимптотика ===&lt;br /&gt;
Так как нам понадобится [[Быстрая сортировка | сортировка]] для массива &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, то итоговая ассимптотика будет &amp;lt;tex&amp;gt;\mathcal{O}(n\log{n})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
Докажем две леммы:&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|statement= В оптимальном расписании на каждом станке работы выполняются в порядке неубывания времён выполнения.&lt;br /&gt;
|proof= Пусть это не так. Заметим что &amp;lt;tex&amp;gt;\sum\limits_{i=0}^{n-1} C_{i} = \sum\limits_{i=0}^{n-1} p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Следовательно каждая работа даёт вклад равный &amp;lt;tex&amp;gt;p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Тогда поменяем местами две работы которые нарушают порядок невозрастания. Заметим что &amp;lt;tex&amp;gt;\sum\limits_{i=0}^{n-1} C_{i}&amp;lt;/tex&amp;gt; уменьшилась. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma2&lt;br /&gt;
|statement= В оптимальном расписании количество выполненных работ на любых двух станках отличается не более чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof= Пусть это не так. Как было отмечено в предыдущей лемме, каждая работа даёт вклад в &amp;lt;tex&amp;gt;\sum\limits_{i=0}^{n-1} C_{i}&amp;lt;/tex&amp;gt; равный &amp;lt;tex&amp;gt;p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Найдём два станка количество работ на которых отличается больше чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Пусть это станки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Причём на стнаке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; выполняется больше работ. Тогда если отправить первую с начала работу со станка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; на станок &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; то  &amp;lt;tex&amp;gt;\sum\limits_{i=0}^{n-1} C_{i}&amp;lt;/tex&amp;gt; уменьшится на разность количества работ на станках &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=theorem1&lt;br /&gt;
|statement= Алгоритм &amp;lt;tex&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt; строит оптимальное расписание.&lt;br /&gt;
|proof= Пусть это не так и оптимальное расписание отличается от расписания построенного алгоритмом. Заметим что расписание построенное алгоритмом удовлетворяет обеим леммам. Тогда можно воспользоваться одной из них чтобы улучшить оптимальное раписание. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие. }}&lt;br /&gt;
&lt;br /&gt;
=== Источники информации ===&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 22&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54475</id>
		<title>PSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54475"/>
				<updated>2016-06-04T18:47:06Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: /* Псевдокод */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ с заданными временами выполнения &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; параллельных станков с одинаковой скоростью выполнения работ.&amp;lt;br&amp;gt;Цель {{---}} составить такое расписание, чтобы суммарное время окончания всех работ было минимальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; заданы в порядке невозрастания (&amp;lt;tex&amp;gt;p_{0}  \geqslant p_{1} \geqslant \ldots \geqslant p_{n-1} &amp;lt;/tex&amp;gt;). Пусть теперь &amp;lt;tex&amp;gt;b_{i} = \left\lceil\dfrac{i}{m}\right\rceil&amp;lt;/tex&amp;gt;. Тогда в оптимальном расписании работа с номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; будет выполнена на станке с номером &amp;lt;tex&amp;gt;i \bmod m&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;b_{i}&amp;lt;/tex&amp;gt;-ой с конца.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Итоговым расписанием будет массив &amp;lt;tex&amp;gt;schedule&amp;lt;/tex&amp;gt; где в &amp;lt;tex&amp;gt;schedule[i][j]&amp;lt;/tex&amp;gt; храниться номер работы которую надо исполнить на станке номер &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой по счёту.&lt;br /&gt;
&lt;br /&gt;
 '''function''' getSchedule(jobs : '''int'''[n]): &amp;lt;font color=green&amp;gt;// jobs - массив номеров работ отсортированных в порядке невозрастания p[i].&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''list'''&amp;lt;'''int'''&amp;gt; schedule[m] &amp;lt;font color=green&amp;gt; // Заведём список работ для каждого станка. Ответ будет храниться в нём.&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
   '''for''' i = 0 '''to''' n&lt;br /&gt;
     schedule[i mod m].push(jobs[i]) &amp;lt;font color=green&amp;gt;// Cтавим i-ую в порядке уменьшения p[i] работу на станок i mod m в конец.&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// Заметим что расписание для каждого станка получилось перевёрнутым.&amp;lt;br&amp;gt;  // Поэтому развернём расписание для каждого станка.&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''for''' i = 0 '''to''' m&lt;br /&gt;
     schedule[i].reverse()&amp;lt;br&amp;gt;&lt;br /&gt;
   '''return''' schedule&lt;br /&gt;
&lt;br /&gt;
=== Ассимптотика ===&lt;br /&gt;
Так как нам понадобится [[Быстрая сортировка | сортировка]] для массива &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, то итоговая ассимптотика будет &amp;lt;tex&amp;gt;\mathcal{O}(n\log{n})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
Докажем две леммы:&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|statement= В оптимальном расписании на каждом станке работы выполняются в порядке неубывания времён выполнения.&lt;br /&gt;
|proof= Пусть это не так. Заметим что &amp;lt;tex&amp;gt;\sum\limits_{i=0}^{n-1} C_{i} = \sum\limits_{i=0}^{n-1} p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Следовательно каждая работа даёт вклад равный &amp;lt;tex&amp;gt;p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Тогда поменяем местами две работы которые нарушают порядок невозрастания. Заметим что &amp;lt;tex&amp;gt;\sum\limits_{i=0}^{n-1} C_{i}&amp;lt;/tex&amp;gt; уменьшилась. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma2&lt;br /&gt;
|statement= В оптимальном расписании количество выполненных работ на любых двух станках отличается не более чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof= Пусть это не так. Как было отмечено в предыдущей лемме, каждая работа даёт вклад в &amp;lt;tex&amp;gt;\sum\limits_{i=0}^{n-1} C_{i}&amp;lt;/tex&amp;gt; равный &amp;lt;tex&amp;gt;p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Найдём два станка количество работ на которых отличается больше чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Пусть это станки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Причём на стнаке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; выполняется больше работ. Тогда если отправить первую с начала работу со станка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; на станок &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; то  &amp;lt;tex&amp;gt;\sum\limits_{i=0}^{n-1} C_{i}&amp;lt;/tex&amp;gt; уменьшится на разность количества работ на станках &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=theorem1&lt;br /&gt;
|statement= Алгоритм &amp;lt;tex&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt; строит оптимальное расписание.&lt;br /&gt;
|proof= Пусть это не так и оптимальное расписание отличается от расписания построенного алгоритмом. Заметим что расписание построенное алгоритмом удовлетворяет обеим леммам. Тогда можно воспользоваться одной из них чтобы улучшить оптимальное раписание. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие. }}&lt;br /&gt;
&lt;br /&gt;
=== Источники информации ===&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 22&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54474</id>
		<title>PSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54474"/>
				<updated>2016-06-04T18:46:43Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: /* Псевдокод */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ с заданными временами выполнения &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; параллельных станков с одинаковой скоростью выполнения работ.&amp;lt;br&amp;gt;Цель {{---}} составить такое расписание, чтобы суммарное время окончания всех работ было минимальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; заданы в порядке невозрастания (&amp;lt;tex&amp;gt;p_{0}  \geqslant p_{1} \geqslant \ldots \geqslant p_{n-1} &amp;lt;/tex&amp;gt;). Пусть теперь &amp;lt;tex&amp;gt;b_{i} = \left\lceil\dfrac{i}{m}\right\rceil&amp;lt;/tex&amp;gt;. Тогда в оптимальном расписании работа с номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; будет выполнена на станке с номером &amp;lt;tex&amp;gt;i \bmod m&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;b_{i}&amp;lt;/tex&amp;gt;-ой с конца.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Итоговым расписанием будет массив &amp;lt;tex&amp;gt;schedule&amp;lt;/tex&amp;gt; где в &amp;lt;tex&amp;gt;schedule[i][j]&amp;lt;/tex&amp;gt; храниться номер работы которую надо исполнить на станке номер &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой по счёту.&lt;br /&gt;
&lt;br /&gt;
 '''function''' getSchedule(jobs : '''int'''[n]): &amp;lt;font color=green&amp;gt;// jobs - массив номеров работ отсортированных в порядке невозрастания p[i].&amp;lt;/font&amp;gt;&lt;br /&gt;
   list&amp;lt;int&amp;gt; schedule[m] &amp;lt;font color=green&amp;gt; // Заведём список работ для каждого станка. Ответ будет храниться в нём.&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
   '''for''' i = 0 '''to''' n&lt;br /&gt;
     schedule[i mod m].push(jobs[i]) &amp;lt;font color=green&amp;gt;// Cтавим i-ую в порядке уменьшения p[i] работу на станок i mod m в конец.&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// Заметим что расписание для каждого станка получилось перевёрнутым.&amp;lt;br&amp;gt;  // Поэтому развернём расписание для каждого станка.&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''for''' i = 0 '''to''' m&lt;br /&gt;
     schedule[i].reverse()&amp;lt;br&amp;gt;&lt;br /&gt;
   '''return''' schedule&lt;br /&gt;
&lt;br /&gt;
=== Ассимптотика ===&lt;br /&gt;
Так как нам понадобится [[Быстрая сортировка | сортировка]] для массива &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, то итоговая ассимптотика будет &amp;lt;tex&amp;gt;\mathcal{O}(n\log{n})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
Докажем две леммы:&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|statement= В оптимальном расписании на каждом станке работы выполняются в порядке неубывания времён выполнения.&lt;br /&gt;
|proof= Пусть это не так. Заметим что &amp;lt;tex&amp;gt;\sum\limits_{i=0}^{n-1} C_{i} = \sum\limits_{i=0}^{n-1} p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Следовательно каждая работа даёт вклад равный &amp;lt;tex&amp;gt;p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Тогда поменяем местами две работы которые нарушают порядок невозрастания. Заметим что &amp;lt;tex&amp;gt;\sum\limits_{i=0}^{n-1} C_{i}&amp;lt;/tex&amp;gt; уменьшилась. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma2&lt;br /&gt;
|statement= В оптимальном расписании количество выполненных работ на любых двух станках отличается не более чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof= Пусть это не так. Как было отмечено в предыдущей лемме, каждая работа даёт вклад в &amp;lt;tex&amp;gt;\sum\limits_{i=0}^{n-1} C_{i}&amp;lt;/tex&amp;gt; равный &amp;lt;tex&amp;gt;p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Найдём два станка количество работ на которых отличается больше чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Пусть это станки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Причём на стнаке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; выполняется больше работ. Тогда если отправить первую с начала работу со станка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; на станок &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; то  &amp;lt;tex&amp;gt;\sum\limits_{i=0}^{n-1} C_{i}&amp;lt;/tex&amp;gt; уменьшится на разность количества работ на станках &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=theorem1&lt;br /&gt;
|statement= Алгоритм &amp;lt;tex&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt; строит оптимальное расписание.&lt;br /&gt;
|proof= Пусть это не так и оптимальное расписание отличается от расписания построенного алгоритмом. Заметим что расписание построенное алгоритмом удовлетворяет обеим леммам. Тогда можно воспользоваться одной из них чтобы улучшить оптимальное раписание. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие. }}&lt;br /&gt;
&lt;br /&gt;
=== Источники информации ===&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 22&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54473</id>
		<title>PSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54473"/>
				<updated>2016-06-04T18:44:10Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: /* Псевдокод */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ с заданными временами выполнения &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; параллельных станков с одинаковой скоростью выполнения работ.&amp;lt;br&amp;gt;Цель {{---}} составить такое расписание, чтобы суммарное время окончания всех работ было минимальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; заданы в порядке невозрастания (&amp;lt;tex&amp;gt;p_{0}  \geqslant p_{1} \geqslant \ldots \geqslant p_{n-1} &amp;lt;/tex&amp;gt;). Пусть теперь &amp;lt;tex&amp;gt;b_{i} = \left\lceil\dfrac{i}{m}\right\rceil&amp;lt;/tex&amp;gt;. Тогда в оптимальном расписании работа с номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; будет выполнена на станке с номером &amp;lt;tex&amp;gt;i \bmod m&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;b_{i}&amp;lt;/tex&amp;gt;-ой с конца.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Итоговым расписанием будет массив &amp;lt;tex&amp;gt;schedule&amp;lt;/tex&amp;gt; где в &amp;lt;tex&amp;gt;schedule[i][j]&amp;lt;/tex&amp;gt; храниться номер работы которую надо исполнить на станке номер &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ой по счёту.&lt;br /&gt;
&lt;br /&gt;
 '''function''' getSchedule(jobs : int[n]): &amp;lt;font color=green&amp;gt;// jobs - массив номеров работ отсортированных в порядке невозрастания p[i].&amp;lt;/font&amp;gt;&lt;br /&gt;
   list&amp;lt;int&amp;gt; schedule[m] &amp;lt;font color=green&amp;gt; // Заведём список работ для каждого станка. Ответ будет храниться в нём.&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
   '''for''' i = 0 '''to''' n&lt;br /&gt;
     schedule[i mod m].push(jobs[i]) &amp;lt;font color=green&amp;gt;// Cтавим i-ую в порядке уменьшения p[i] работу на станок i mod m в конец.&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
   &amp;lt;font color=green&amp;gt;// Заметим что расписание для каждого станка получилось перевёрнутым.&amp;lt;br&amp;gt;  // Поэтому развернём расписание для каждого станка.&amp;lt;/font&amp;gt;&lt;br /&gt;
   '''for''' i = 0 '''to''' m&lt;br /&gt;
     schedule[i].reverse()&amp;lt;br&amp;gt;&lt;br /&gt;
   '''return''' schedule&lt;br /&gt;
&lt;br /&gt;
=== Ассимптотика ===&lt;br /&gt;
Так как нам понадобится [[Быстрая сортировка | сортировка]] для массива &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, то итоговая ассимптотика будет &amp;lt;tex&amp;gt;\mathcal{O}(n\log{n})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
Докажем две леммы:&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|statement= В оптимальном расписании на каждом станке работы выполняются в порядке неубывания времён выполнения.&lt;br /&gt;
|proof= Пусть это не так. Заметим что &amp;lt;tex&amp;gt;\sum\limits_{i=0}^{n-1} C_{i} = \sum\limits_{i=0}^{n-1} p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Следовательно каждая работа даёт вклад равный &amp;lt;tex&amp;gt;p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Тогда поменяем местами две работы которые нарушают порядок невозрастания. Заметим что &amp;lt;tex&amp;gt;\sum\limits_{i=0}^{n-1} C_{i}&amp;lt;/tex&amp;gt; уменьшилась. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma2&lt;br /&gt;
|statement= В оптимальном расписании количество выполненных работ на любых двух станках отличается не более чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof= Пусть это не так. Как было отмечено в предыдущей лемме, каждая работа даёт вклад в &amp;lt;tex&amp;gt;\sum\limits_{i=0}^{n-1} C_{i}&amp;lt;/tex&amp;gt; равный &amp;lt;tex&amp;gt;p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Найдём два станка количество работ на которых отличается больше чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Пусть это станки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Причём на стнаке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; выполняется больше работ. Тогда если отправить первую с начала работу со станка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; на станок &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; то  &amp;lt;tex&amp;gt;\sum\limits_{i=0}^{n-1} C_{i}&amp;lt;/tex&amp;gt; уменьшится на разность количества работ на станках &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=theorem1&lt;br /&gt;
|statement= Алгоритм &amp;lt;tex&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt; строит оптимальное расписание.&lt;br /&gt;
|proof= Пусть это не так и оптимальное расписание отличается от расписания построенного алгоритмом. Заметим что расписание построенное алгоритмом удовлетворяет обеим леммам. Тогда можно воспользоваться одной из них чтобы улучшить оптимальное раписание. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие. }}&lt;br /&gt;
&lt;br /&gt;
=== Источники информации ===&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 22&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54467</id>
		<title>PSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54467"/>
				<updated>2016-06-04T18:31:25Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: /* Доказательство корректности */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ с заданными временами выполнения &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; параллельных станков с одинаковой скоростью выполнения работ.&amp;lt;br&amp;gt;Цель {{---}} составить такое расписание, чтобы суммарное время окончания всех работ было минимальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; заданы в порядке невозрастания (&amp;lt;tex&amp;gt;p_{0}  \geqslant p_{1} \geqslant \ldots \geqslant p_{n-1} &amp;lt;/tex&amp;gt;). Пусть теперь &amp;lt;tex&amp;gt;b_{i} = \left\lceil\dfrac{i}{m}\right\rceil&amp;lt;/tex&amp;gt;. Тогда в оптимальном расписании работа с номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; будет выполнена на станке с номером &amp;lt;tex&amp;gt;i \bmod m&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;b_{i}&amp;lt;/tex&amp;gt;-ой с конца.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Здесь предполагается что работы отсортирован в порядке неубывания времён выполнения.&lt;br /&gt;
&lt;br /&gt;
 list&amp;lt;int&amp;gt; schedule[m] &amp;lt;font color=green&amp;gt; //Заведём список работ для каждого станка. Ответ будет храниться в нём.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' n&lt;br /&gt;
         schedule[i mod m].push(i) &amp;lt;font color=green&amp;gt;//ставим работу с номером i на станок i mod m в конец.&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &amp;lt;font color=green&amp;gt;//Заметим что расписание для каждого станка получилось перевёрнутым&amp;lt;br&amp;gt;    //Поэтому развернём расписание для каждого станка.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' m&lt;br /&gt;
         schedule[i].reverse()&lt;br /&gt;
&lt;br /&gt;
=== Ассимптотика ===&lt;br /&gt;
Так как нам понадобится [[Быстрая сортировка | сортировка]] для массива &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, то итоговая ассимптотика будет &amp;lt;tex&amp;gt;\mathcal{O}(n\log{n})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
Докажем две леммы:&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|statement= В оптимальном расписании на каждом станке работы выполняются в порядке неубывания времён выполнения.&lt;br /&gt;
|proof= Пусть это не так. Заметим что &amp;lt;tex&amp;gt;\sum\limits_{i=0}^{n-1} C_{i} = \sum\limits_{i=0}^{n-1} p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Следовательно каждая работа даёт вклад равный &amp;lt;tex&amp;gt;p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Тогда поменяем местами две работы которые нарушают порядок невозрастания. Заметим что &amp;lt;tex&amp;gt;\sum\limits_{i=0}^{n-1} C_{i}&amp;lt;/tex&amp;gt; уменьшилась. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma2&lt;br /&gt;
|statement= В оптимальном расписании количество выполненных работ на любых двух станках отличается не более чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof= Пусть это не так. Как было отмечено в предыдущей лемме, каждая работа даёт вклад в &amp;lt;tex&amp;gt;\sum\limits_{i=0}^{n-1} C_{i}&amp;lt;/tex&amp;gt; равный &amp;lt;tex&amp;gt;p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Найдём два станка количество работ на которых отличается больше чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Пусть это станки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Причём на стнаке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; выполняется больше работ. Тогда если отправить первую с начала работу со станка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; на станок &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; то  &amp;lt;tex&amp;gt;\sum\limits_{i=0}^{n-1} C_{i}&amp;lt;/tex&amp;gt; уменьшится на разность количества работ на станках &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=theorem1&lt;br /&gt;
|statement= Алгоритм &amp;lt;tex&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt; строит оптимальное расписание.&lt;br /&gt;
|proof= Пусть это не так и оптимальное расписание отличается от расписания построенного алгоритмом. Заметим что расписание построенное алгоритмом удовлетворяет обеим леммам. Тогда можно воспользоваться одной из них чтобы улучшить оптимальное раписание. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие. }}&lt;br /&gt;
&lt;br /&gt;
=== Источники информации ===&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 22&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54466</id>
		<title>PSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54466"/>
				<updated>2016-06-04T18:29:27Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: /* Источники информации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ с заданными временами выполнения &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; параллельных станков с одинаковой скоростью выполнения работ.&amp;lt;br&amp;gt;Цель {{---}} составить такое расписание, чтобы суммарное время окончания всех работ было минимальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; заданы в порядке невозрастания (&amp;lt;tex&amp;gt;p_{0}  \geqslant p_{1} \geqslant \ldots \geqslant p_{n-1} &amp;lt;/tex&amp;gt;). Пусть теперь &amp;lt;tex&amp;gt;b_{i} = \left\lceil\dfrac{i}{m}\right\rceil&amp;lt;/tex&amp;gt;. Тогда в оптимальном расписании работа с номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; будет выполнена на станке с номером &amp;lt;tex&amp;gt;i \bmod m&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;b_{i}&amp;lt;/tex&amp;gt;-ой с конца.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Здесь предполагается что работы отсортирован в порядке неубывания времён выполнения.&lt;br /&gt;
&lt;br /&gt;
 list&amp;lt;int&amp;gt; schedule[m] &amp;lt;font color=green&amp;gt; //Заведём список работ для каждого станка. Ответ будет храниться в нём.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' n&lt;br /&gt;
         schedule[i mod m].push(i) &amp;lt;font color=green&amp;gt;//ставим работу с номером i на станок i mod m в конец.&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &amp;lt;font color=green&amp;gt;//Заметим что расписание для каждого станка получилось перевёрнутым&amp;lt;br&amp;gt;    //Поэтому развернём расписание для каждого станка.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' m&lt;br /&gt;
         schedule[i].reverse()&lt;br /&gt;
&lt;br /&gt;
=== Ассимптотика ===&lt;br /&gt;
Так как нам понадобится [[Быстрая сортировка | сортировка]] для массива &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, то итоговая ассимптотика будет &amp;lt;tex&amp;gt;\mathcal{O}(n\log{n})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
Докажем две леммы:&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|statement= В оптимальном расписании на каждом станке работы выполняются в порядке неубывания времён выполнения.&lt;br /&gt;
|proof= Пусть это не так. Заметим что &amp;lt;tex&amp;gt;\sum C_{i} = \sum p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Следовательно каждая работа даёт вклад равный &amp;lt;tex&amp;gt;p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Тогда поменяем местами две работы которые нарушают порядок невозрастания. Заметим что &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; уменьшилась. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma2&lt;br /&gt;
|statement= В оптимальном расписании количество выполненных работ на любых двух станках отличается не более чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof= Пусть это не так. Как было отмечено в предыдущей лемме, каждая работа даёт вклад в &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; равный &amp;lt;tex&amp;gt;p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Найдём два станка количество работ на которых отличается больше чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Пусть это станки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Причём на стнаке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; выполняется больше работ. Тогда если отправить первую с начала работу со станка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; на станок &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; то  &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; уменьшится на разность количества работ на станках &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=theorem1&lt;br /&gt;
|statement= Алгоритм &amp;lt;tex&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt; строит оптимальное расписание.&lt;br /&gt;
|proof= Пусть это не так и оптимальное расписание отличается от расписания построенного алгоритмом. Заметим что расписание построенное алгоритмом удовлетворяет обеим леммам. Тогда можно воспользоваться одной из них чтобы улучшить оптимальное раписание. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие. }}&lt;br /&gt;
&lt;br /&gt;
=== Источники информации ===&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 22&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54465</id>
		<title>PSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54465"/>
				<updated>2016-06-04T18:29:10Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ с заданными временами выполнения &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; параллельных станков с одинаковой скоростью выполнения работ.&amp;lt;br&amp;gt;Цель {{---}} составить такое расписание, чтобы суммарное время окончания всех работ было минимальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; заданы в порядке невозрастания (&amp;lt;tex&amp;gt;p_{0}  \geqslant p_{1} \geqslant \ldots \geqslant p_{n-1} &amp;lt;/tex&amp;gt;). Пусть теперь &amp;lt;tex&amp;gt;b_{i} = \left\lceil\dfrac{i}{m}\right\rceil&amp;lt;/tex&amp;gt;. Тогда в оптимальном расписании работа с номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; будет выполнена на станке с номером &amp;lt;tex&amp;gt;i \bmod m&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;b_{i}&amp;lt;/tex&amp;gt;-ой с конца.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Здесь предполагается что работы отсортирован в порядке неубывания времён выполнения.&lt;br /&gt;
&lt;br /&gt;
 list&amp;lt;int&amp;gt; schedule[m] &amp;lt;font color=green&amp;gt; //Заведём список работ для каждого станка. Ответ будет храниться в нём.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' n&lt;br /&gt;
         schedule[i mod m].push(i) &amp;lt;font color=green&amp;gt;//ставим работу с номером i на станок i mod m в конец.&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &amp;lt;font color=green&amp;gt;//Заметим что расписание для каждого станка получилось перевёрнутым&amp;lt;br&amp;gt;    //Поэтому развернём расписание для каждого станка.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' m&lt;br /&gt;
         schedule[i].reverse()&lt;br /&gt;
&lt;br /&gt;
=== Ассимптотика ===&lt;br /&gt;
Так как нам понадобится [[Быстрая сортировка | сортировка]] для массива &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, то итоговая ассимптотика будет &amp;lt;tex&amp;gt;\mathcal{O}(n\log{n})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
Докажем две леммы:&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|statement= В оптимальном расписании на каждом станке работы выполняются в порядке неубывания времён выполнения.&lt;br /&gt;
|proof= Пусть это не так. Заметим что &amp;lt;tex&amp;gt;\sum C_{i} = \sum p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Следовательно каждая работа даёт вклад равный &amp;lt;tex&amp;gt;p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Тогда поменяем местами две работы которые нарушают порядок невозрастания. Заметим что &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; уменьшилась. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma2&lt;br /&gt;
|statement= В оптимальном расписании количество выполненных работ на любых двух станках отличается не более чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof= Пусть это не так. Как было отмечено в предыдущей лемме, каждая работа даёт вклад в &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; равный &amp;lt;tex&amp;gt;p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Найдём два станка количество работ на которых отличается больше чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Пусть это станки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Причём на стнаке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; выполняется больше работ. Тогда если отправить первую с начала работу со станка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; на станок &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; то  &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; уменьшится на разность количества работ на станках &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=theorem1&lt;br /&gt;
|statement= Алгоритм &amp;lt;tex&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt; строит оптимальное расписание.&lt;br /&gt;
|proof= Пусть это не так и оптимальное расписание отличается от расписания построенного алгоритмом. Заметим что расписание построенное алгоритмом удовлетворяет обеим леммам. Тогда можно воспользоваться одной из них чтобы улучшить оптимальное раписание. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие. }}&lt;br /&gt;
&lt;br /&gt;
=== Источники информации ===&lt;br /&gt;
* P. Brucker. Scheduling Algorithms (2006), 5th edition, стр. 26 - 28&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54464</id>
		<title>PSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54464"/>
				<updated>2016-06-04T18:28:17Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: /* Ассимптотика */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ с заданными временами выполнения &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; параллельных станков с одинаковой скоростью выполнения работ.&amp;lt;br&amp;gt;Цель {{---}} составить такое расписание, чтобы суммарное время окончания всех работ было минимальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; заданы в порядке невозрастания (&amp;lt;tex&amp;gt;p_{0}  \geqslant p_{1} \geqslant \ldots \geqslant p_{n-1} &amp;lt;/tex&amp;gt;). Пусть теперь &amp;lt;tex&amp;gt;b_{i} = \left\lceil\dfrac{i}{m}\right\rceil&amp;lt;/tex&amp;gt;. Тогда в оптимальном расписании работа с номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; будет выполнена на станке с номером &amp;lt;tex&amp;gt;i \bmod m&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;b_{i}&amp;lt;/tex&amp;gt;-ой с конца.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Здесь предполагается что работы отсортирован в порядке неубывания времён выполнения.&lt;br /&gt;
&lt;br /&gt;
 list&amp;lt;int&amp;gt; schedule[m] &amp;lt;font color=green&amp;gt; //Заведём список работ для каждого станка. Ответ будет храниться в нём.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' n&lt;br /&gt;
         schedule[i mod m].push(i) &amp;lt;font color=green&amp;gt;//ставим работу с номером i на станок i mod m в конец.&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &amp;lt;font color=green&amp;gt;//Заметим что расписание для каждого станка получилось перевёрнутым&amp;lt;br&amp;gt;    //Поэтому развернём расписание для каждого станка.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' m&lt;br /&gt;
         schedule[i].reverse()&lt;br /&gt;
&lt;br /&gt;
=== Ассимптотика ===&lt;br /&gt;
Так как нам понадобится [[Быстрая сортировка | сортировка]] для массива &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, то итоговая ассимптотика будет &amp;lt;tex&amp;gt;\mathcal{O}(n\log{n})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
Докажем две леммы:&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|statement= В оптимальном расписании на каждом станке работы выполняются в порядке неубывания времён выполнения.&lt;br /&gt;
|proof= Пусть это не так. Заметим что &amp;lt;tex&amp;gt;\sum C_{i} = \sum p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Следовательно каждая работа даёт вклад равный &amp;lt;tex&amp;gt;p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Тогда поменяем местами две работы которые нарушают порядок невозрастания. Заметим что &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; уменьшилась. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma2&lt;br /&gt;
|statement= В оптимальном расписании количество выполненных работ на любых двух станках отличается не более чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof= Пусть это не так. Как было отмечено в предыдущей лемме, каждая работа даёт вклад в &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; равный &amp;lt;tex&amp;gt;p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Найдём два станка количество работ на которых отличается больше чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Пусть это станки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Причём на стнаке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; выполняется больше работ. Тогда если отправить первую с начала работу со станка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; на станок &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; то  &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; уменьшится на разность количества работ на станках &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=theorem1&lt;br /&gt;
|statement= Алгоритм &amp;lt;tex&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt; строит оптимальное расписание.&lt;br /&gt;
|proof= Пусть это не так и оптимальное расписание отличается от расписания построенного алгоритмом. Заметим что расписание построенное алгоритмом удовлетворяет обеим леммам. Тогда можно воспользоваться одной из них чтобы улучшить оптимальное раписание. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие. }}&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54463</id>
		<title>PSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54463"/>
				<updated>2016-06-04T18:23:52Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ с заданными временами выполнения &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; параллельных станков с одинаковой скоростью выполнения работ.&amp;lt;br&amp;gt;Цель {{---}} составить такое расписание, чтобы суммарное время окончания всех работ было минимальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; заданы в порядке невозрастания (&amp;lt;tex&amp;gt;p_{0}  \geqslant p_{1} \geqslant \ldots \geqslant p_{n-1} &amp;lt;/tex&amp;gt;). Пусть теперь &amp;lt;tex&amp;gt;b_{i} = \left\lceil\dfrac{i}{m}\right\rceil&amp;lt;/tex&amp;gt;. Тогда в оптимальном расписании работа с номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; будет выполнена на станке с номером &amp;lt;tex&amp;gt;i \bmod m&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;b_{i}&amp;lt;/tex&amp;gt;-ой с конца.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Здесь предполагается что работы отсортирован в порядке неубывания времён выполнения.&lt;br /&gt;
&lt;br /&gt;
 list&amp;lt;int&amp;gt; schedule[m] &amp;lt;font color=green&amp;gt; //Заведём список работ для каждого станка. Ответ будет храниться в нём.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' n&lt;br /&gt;
         schedule[i mod m].push(i) &amp;lt;font color=green&amp;gt;//ставим работу с номером i на станок i mod m в конец.&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &amp;lt;font color=green&amp;gt;//Заметим что расписание для каждого станка получилось перевёрнутым&amp;lt;br&amp;gt;    //Поэтому развернём расписание для каждого станка.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' m&lt;br /&gt;
         schedule[i].reverse()&lt;br /&gt;
&lt;br /&gt;
=== Ассимптотика ===&lt;br /&gt;
Так как нам понадобится сортировка для массива &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, то итоговая ассимптотика будет &amp;lt;tex&amp;gt;\mathcal{O}(n\log{n})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
Докажем две леммы:&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|statement= В оптимальном расписании на каждом станке работы выполняются в порядке неубывания времён выполнения.&lt;br /&gt;
|proof= Пусть это не так. Заметим что &amp;lt;tex&amp;gt;\sum C_{i} = \sum p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Следовательно каждая работа даёт вклад равный &amp;lt;tex&amp;gt;p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Тогда поменяем местами две работы которые нарушают порядок невозрастания. Заметим что &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; уменьшилась. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma2&lt;br /&gt;
|statement= В оптимальном расписании количество выполненных работ на любых двух станках отличается не более чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof= Пусть это не так. Как было отмечено в предыдущей лемме, каждая работа даёт вклад в &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; равный &amp;lt;tex&amp;gt;p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Найдём два станка количество работ на которых отличается больше чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Пусть это станки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Причём на стнаке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; выполняется больше работ. Тогда если отправить первую с начала работу со станка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; на станок &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; то  &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; уменьшится на разность количества работ на станках &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=theorem1&lt;br /&gt;
|statement= Алгоритм &amp;lt;tex&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt; строит оптимальное расписание.&lt;br /&gt;
|proof= Пусть это не так и оптимальное расписание отличается от расписания построенного алгоритмом. Заметим что расписание построенное алгоритмом удовлетворяет обеим леммам. Тогда можно воспользоваться одной из них чтобы улучшить оптимальное раписание. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие. }}&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54449</id>
		<title>PSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54449"/>
				<updated>2016-06-04T17:10:54Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: /* Доказательство корректности */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ с заданными временами выполнения &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.  И &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; параллельных станков с одинаковой скоростью выполнения работ.&amp;lt;br&amp;gt;Цель {{---}} составить такое расписание, чтобы суммарное время окончания всех работ было минимальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; заданы в порядке невозрастания (&amp;lt;tex&amp;gt;p_{0}  \geqslant p_{1} \geqslant \ldots \geqslant p_{n-1} &amp;lt;/tex&amp;gt;). Пусть теперь &amp;lt;tex&amp;gt;b_{i} = \left\lceil\dfrac{i}{m}\right\rceil&amp;lt;/tex&amp;gt;. Тогда в оптимальном расписании работа с номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; будет выполнена на станке с номером &amp;lt;tex&amp;gt;i \bmod m&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;b_{i}&amp;lt;/tex&amp;gt;-ой с конца.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Здесь предполагается что работы отсортирован в порядке неубывания времён выполнения.&lt;br /&gt;
&lt;br /&gt;
 list&amp;lt;int&amp;gt; schedule[m] &amp;lt;font color=green&amp;gt; //Заведём список работ для каждого станка. Ответ будет храниться в нём.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' n&lt;br /&gt;
         schedule[i mod m].push(i) &amp;lt;font color=green&amp;gt;//ставим работу с номером i на станок i mod m в конец.&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &amp;lt;font color=green&amp;gt;//Заметим что расписание для каждого станка получилось перевёрнутым&amp;lt;br&amp;gt;    //Поэтому развернём расписание для каждого станка.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' m&lt;br /&gt;
         schedule[i].reverse()&lt;br /&gt;
&lt;br /&gt;
=== Ассимптотика ===&lt;br /&gt;
Так как нам понадобится сортировка для массива &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, то итоговая ассимптотика будет &amp;lt;tex&amp;gt;\mathcal{O}(n\log{n})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
Докажем две леммы:&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|statement= В оптимальном расписании на каждом станке работы выполняются в порядке неубывания времён выполнения.&lt;br /&gt;
|proof= Пусть это не так. Заметим что &amp;lt;tex&amp;gt;\sum C_{i} = \sum p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Следовательно каждая работа даёт вклад равный &amp;lt;tex&amp;gt;p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Тогда поменяем местами две работы которые нарушают порядок невозрастания. Заметим что &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; уменьшилась. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma2&lt;br /&gt;
|statement= В оптимальном расписании количество выполненных работ на любых двух станках отличается не более чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof= Пусть это не так. Как было отмечено в предыдущей лемме, каждая работа даёт вклад в &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; равный &amp;lt;tex&amp;gt;p_{i} \cdot b_{i}&amp;lt;/tex&amp;gt;. Найдём два станка количество работ на которых отличается больше чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Пусть это станки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Причём на стнаке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; выполняется больше работ. Тогда если отправить первую с начала работу со станка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; на станок &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; то  &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; уменьшится на разность количества работ на станках &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=theorem1&lt;br /&gt;
|statement= Алгоритм &amp;lt;tex&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt; строит оптимальное расписание.&lt;br /&gt;
|proof= Пусть это не так и оптимальное расписание отличается от расписания построенного алгоритмом. Заметим что расписание построенное алгоритмом удовлетворяет обеим леммам. Тогда можно воспользоваться одной из них чтобы улучшить оптимальное раписание. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие. }}&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54448</id>
		<title>PSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54448"/>
				<updated>2016-06-04T17:09:08Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: /* Доказательство корректности */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ с заданными временами выполнения &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.  И &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; параллельных станков с одинаковой скоростью выполнения работ.&amp;lt;br&amp;gt;Цель {{---}} составить такое расписание, чтобы суммарное время окончания всех работ было минимальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; заданы в порядке невозрастания (&amp;lt;tex&amp;gt;p_{0}  \geqslant p_{1} \geqslant \ldots \geqslant p_{n-1} &amp;lt;/tex&amp;gt;). Пусть теперь &amp;lt;tex&amp;gt;b_{i} = \left\lceil\dfrac{i}{m}\right\rceil&amp;lt;/tex&amp;gt;. Тогда в оптимальном расписании работа с номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; будет выполнена на станке с номером &amp;lt;tex&amp;gt;i \bmod m&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;b_{i}&amp;lt;/tex&amp;gt;-ой с конца.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Здесь предполагается что работы отсортирован в порядке неубывания времён выполнения.&lt;br /&gt;
&lt;br /&gt;
 list&amp;lt;int&amp;gt; schedule[m] &amp;lt;font color=green&amp;gt; //Заведём список работ для каждого станка. Ответ будет храниться в нём.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' n&lt;br /&gt;
         schedule[i mod m].push(i) &amp;lt;font color=green&amp;gt;//ставим работу с номером i на станок i mod m в конец.&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &amp;lt;font color=green&amp;gt;//Заметим что расписание для каждого станка получилось перевёрнутым&amp;lt;br&amp;gt;    //Поэтому развернём расписание для каждого станка.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' m&lt;br /&gt;
         schedule[i].reverse()&lt;br /&gt;
&lt;br /&gt;
=== Ассимптотика ===&lt;br /&gt;
Так как нам понадобится сортировка для массива &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, то итоговая ассимптотика будет &amp;lt;tex&amp;gt;\mathcal{O}(n\log{n})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
Докажем две леммы:&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|statement= В оптимальном расписании на каждом станке работы выполняются в порядке неубывания времён выполнения.&lt;br /&gt;
|proof= Пусть это не так. Заметим что &amp;lt;tex&amp;gt;\sum C_{i} = \sum p_{i} \cdot (b_{i} + 1)&amp;lt;/tex&amp;gt;. Следовательно каждая работа даёт вклад равный &amp;lt;tex&amp;gt;p_{i} \cdot (b_{i} + 1)&amp;lt;/tex&amp;gt;. Тогда поменяем местами две работы которые нарушают порядок невозрастания. Заметим что &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; уменьшилась. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma2&lt;br /&gt;
|statement= В оптимальном расписании количество выполненных работ на любых двух станках отличается не более чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof= Пусть это не так. Как было отмечено в предыдущей лемме, каждая работа даёт вклад в &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; равный &amp;lt;tex&amp;gt;p_{i} \cdot (b_{i} + 1)&amp;lt;/tex&amp;gt;. Найдём два станка количество работ на которых отличается больше чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Пусть это станки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Причём на стнаке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; выполняется больше работ. Тогда если отправить первую с начала работу со станка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; на станок &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; то  &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; уменьшится на разность количества работ на станках &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=theorem1&lt;br /&gt;
|statement= Алгоритм &amp;lt;tex&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt; строит оптимальное расписание.&lt;br /&gt;
|proof= Пусть это не так и оптимальное расписание отличается от расписания построенного алгоритмом. Заметим что расписание построенное алгоритмом удовлетворяет обеим леммам. Тогда можно воспользоваться одной из них чтобы улучшить оптимальное раписание. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие. }}&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54447</id>
		<title>PSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54447"/>
				<updated>2016-06-04T17:01:39Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: /* Доказательство корректности */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ с заданными временами выполнения &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.  И &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; параллельных станков с одинаковой скоростью выполнения работ.&amp;lt;br&amp;gt;Цель {{---}} составить такое расписание, чтобы суммарное время окончания всех работ было минимальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; заданы в порядке невозрастания (&amp;lt;tex&amp;gt;p_{0}  \geqslant p_{1} \geqslant \ldots \geqslant p_{n-1} &amp;lt;/tex&amp;gt;). Пусть теперь &amp;lt;tex&amp;gt;b_{i} = \left\lceil\dfrac{i}{m}\right\rceil&amp;lt;/tex&amp;gt;. Тогда в оптимальном расписании работа с номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; будет выполнена на станке с номером &amp;lt;tex&amp;gt;i \bmod m&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;b_{i}&amp;lt;/tex&amp;gt;-ой с конца.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Здесь предполагается что работы отсортирован в порядке неубывания времён выполнения.&lt;br /&gt;
&lt;br /&gt;
 list&amp;lt;int&amp;gt; schedule[m] &amp;lt;font color=green&amp;gt; //Заведём список работ для каждого станка. Ответ будет храниться в нём.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' n&lt;br /&gt;
         schedule[i mod m].push(i) &amp;lt;font color=green&amp;gt;//ставим работу с номером i на станок i mod m в конец.&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &amp;lt;font color=green&amp;gt;//Заметим что расписание для каждого станка получилось перевёрнутым&amp;lt;br&amp;gt;    //Поэтому развернём расписание для каждого станка.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' m&lt;br /&gt;
         schedule[i].reverse()&lt;br /&gt;
&lt;br /&gt;
=== Ассимптотика ===&lt;br /&gt;
Так как нам понадобится сортировка для массива &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, то итоговая ассимптотика будет &amp;lt;tex&amp;gt;\mathcal{O}(n\log{n})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
Докажем две леммы:&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|statement= В оптимальном расписании на каждом станке работы выполняются в порядке неубывания времён выполнения.&lt;br /&gt;
|proof= Пусть это не так. Заметим что каждая работа даёт вклад в &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; равный &amp;lt;tex&amp;gt;p_{i} \cdot (b_{i} + 1)&amp;lt;/tex&amp;gt;. Тогда поменяем местами две работы которые нарушают порядок невозрастания. Заметим что &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; уменьшилась. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma2&lt;br /&gt;
|statement= В оптимальном расписании количество выполненных работ на любых двух станках отличается не более чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof= Пусть это не так. Как было отмечено в предыдущей лемме, каждая работа даёт вклад в &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; равный &amp;lt;tex&amp;gt;p_{i} \cdot (b_{i} + 1)&amp;lt;/tex&amp;gt;. Найдём два станка количество работ на которых отличается больше чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Пусть это станки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Причём на стнаке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; выполняется больше работ. Тогда если отправить первую с начала работу со станка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; на станок &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; то  &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; уменьшится на разность количества работ на станках &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=theorem1&lt;br /&gt;
|statement= Алгоритм &amp;lt;tex&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt; строит оптимальное расписание.&lt;br /&gt;
|proof= Пусть это не так и оптимальное расписание отличается от расписания построенного алгоритмом. Заметим что расписание построенное алгоритмом удовлетворяет обеим леммам. Тогда можно воспользоваться одной из них чтобы улучшить оптимальное раписание. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие. }}&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54446</id>
		<title>PSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54446"/>
				<updated>2016-06-04T17:01:14Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: /* Идея */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ с заданными временами выполнения &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.  И &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; параллельных станков с одинаковой скоростью выполнения работ.&amp;lt;br&amp;gt;Цель {{---}} составить такое расписание, чтобы суммарное время окончания всех работ было минимальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; заданы в порядке невозрастания (&amp;lt;tex&amp;gt;p_{0}  \geqslant p_{1} \geqslant \ldots \geqslant p_{n-1} &amp;lt;/tex&amp;gt;). Пусть теперь &amp;lt;tex&amp;gt;b_{i} = \left\lceil\dfrac{i}{m}\right\rceil&amp;lt;/tex&amp;gt;. Тогда в оптимальном расписании работа с номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; будет выполнена на станке с номером &amp;lt;tex&amp;gt;i \bmod m&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;b_{i}&amp;lt;/tex&amp;gt;-ой с конца.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Здесь предполагается что работы отсортирован в порядке неубывания времён выполнения.&lt;br /&gt;
&lt;br /&gt;
 list&amp;lt;int&amp;gt; schedule[m] &amp;lt;font color=green&amp;gt; //Заведём список работ для каждого станка. Ответ будет храниться в нём.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' n&lt;br /&gt;
         schedule[i mod m].push(i) &amp;lt;font color=green&amp;gt;//ставим работу с номером i на станок i mod m в конец.&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &amp;lt;font color=green&amp;gt;//Заметим что расписание для каждого станка получилось перевёрнутым&amp;lt;br&amp;gt;    //Поэтому развернём расписание для каждого станка.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' m&lt;br /&gt;
         schedule[i].reverse()&lt;br /&gt;
&lt;br /&gt;
=== Ассимптотика ===&lt;br /&gt;
Так как нам понадобится сортировка для массива &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, то итоговая ассимптотика будет &amp;lt;tex&amp;gt;\mathcal{O}(n\log{n})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
Докажем две леммы:&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|statement= В оптимальном расписании на каждом станке работы выполняются в порядке неубывания.&lt;br /&gt;
|proof= Пусть это не так. Заметим что каждая работа даёт вклад в &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; равный &amp;lt;tex&amp;gt;p_{i} \cdot (b_{i} + 1)&amp;lt;/tex&amp;gt;. Тогда поменяем местами две работы которые нарушают порядок невозрастания. Заметим что &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; уменьшилась. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma2&lt;br /&gt;
|statement= В оптимальном расписании количество выполненных работ на любых двух станках отличается не более чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof= Пусть это не так. Как было отмечено в предыдущей лемме, каждая работа даёт вклад в &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; равный &amp;lt;tex&amp;gt;p_{i} \cdot (b_{i} + 1)&amp;lt;/tex&amp;gt;. Найдём два станка количество работ на которых отличается больше чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Пусть это станки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Причём на стнаке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; выполняется больше работ. Тогда если отправить первую с начала работу со станка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; на станок &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; то  &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; уменьшится на разность количества работ на станках &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=theorem1&lt;br /&gt;
|statement= Алгоритм &amp;lt;tex&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt; строит оптимальное расписание.&lt;br /&gt;
|proof= Пусть это не так и оптимальное расписание отличается от расписания построенного алгоритмом. Заметим что расписание построенное алгоритмом удовлетворяет обеим леммам. Тогда можно воспользоваться одной из них чтобы улучшить оптимальное раписание. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие. }}&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54444</id>
		<title>PSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54444"/>
				<updated>2016-06-04T16:52:23Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: /* Идея */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ с заданными временами выполнения &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.  И &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; параллельных станков с одинаковой скоростью выполнения работ.&amp;lt;br&amp;gt;Цель {{---}} составить такое расписание, чтобы суммарное время окончания всех работ было минимальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; заданы в порядке невозрастания (&amp;lt;tex&amp;gt;p_{0}  \geqslant p_{1} \geqslant \ldots \geqslant p_{n-1} &amp;lt;/tex&amp;gt;). Пусть теперь &amp;lt;tex&amp;gt;b_{k} = \left\lceil\dfrac{k}{m}\right\rceil&amp;lt;/tex&amp;gt;. Тогда в оптимальном расписании работа с номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; будет выполнена на станке с номером &amp;lt;tex&amp;gt;i \bmod m&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;b_{i}&amp;lt;/tex&amp;gt;-ой с конца.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Здесь предполагается что работы отсортирован в порядке неубывания времён выполнения.&lt;br /&gt;
&lt;br /&gt;
 list&amp;lt;int&amp;gt; schedule[m] &amp;lt;font color=green&amp;gt; //Заведём список работ для каждого станка. Ответ будет храниться в нём.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' n&lt;br /&gt;
         schedule[i mod m].push(i) &amp;lt;font color=green&amp;gt;//ставим работу с номером i на станок i mod m в конец.&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &amp;lt;font color=green&amp;gt;//Заметим что расписание для каждого станка получилось перевёрнутым&amp;lt;br&amp;gt;    //Поэтому развернём расписание для каждого станка.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' m&lt;br /&gt;
         schedule[i].reverse()&lt;br /&gt;
&lt;br /&gt;
=== Ассимптотика ===&lt;br /&gt;
Так как нам понадобится сортировка для массива &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, то итоговая ассимптотика будет &amp;lt;tex&amp;gt;\mathcal{O}(n\log{n})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
Докажем две леммы:&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|statement= В оптимальном расписании на каждом станке работы выполняются в порядке неубывания.&lt;br /&gt;
|proof= Пусть это не так. Заметим что каждая работа даёт вклад в &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; равный &amp;lt;tex&amp;gt;p_{i} \cdot (b_{i} + 1)&amp;lt;/tex&amp;gt;. Тогда поменяем местами две работы которые нарушают порядок невозрастания. Заметим что &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; уменьшилась. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma2&lt;br /&gt;
|statement= В оптимальном расписании количество выполненных работ на любых двух станках отличается не более чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof= Пусть это не так. Как было отмечено в предыдущей лемме, каждая работа даёт вклад в &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; равный &amp;lt;tex&amp;gt;p_{i} \cdot (b_{i} + 1)&amp;lt;/tex&amp;gt;. Найдём два станка количество работ на которых отличается больше чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Пусть это станки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Причём на стнаке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; выполняется больше работ. Тогда если отправить первую с начала работу со станка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; на станок &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; то  &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; уменьшится на разность количества работ на станках &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=theorem1&lt;br /&gt;
|statement= Алгоритм &amp;lt;tex&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt; строит оптимальное расписание.&lt;br /&gt;
|proof= Пусть это не так и оптимальное расписание отличается от расписания построенного алгоритмом. Заметим что расписание построенное алгоритмом удовлетворяет обеим леммам. Тогда можно воспользоваться одной из них чтобы улучшить оптимальное раписание. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие. }}&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54443</id>
		<title>PSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54443"/>
				<updated>2016-06-04T16:50:38Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: /* Псевдокод */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ с заданными временами выполнения &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.  И &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; параллельных станков с одинаковой скоростью выполнения работ.&amp;lt;br&amp;gt;Цель {{---}} составить такое расписание, чтобы суммарное время окончания всех работ было минимальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; заданы в порядке невозрастания (&amp;lt;tex&amp;gt;p_{1}  \geqslant p_{2} \geqslant \ldots \geqslant p_{n} &amp;lt;/tex&amp;gt;). Пусть теперь &amp;lt;tex&amp;gt;b_{k} = \left\lceil\dfrac{k}{m}\right\rceil&amp;lt;/tex&amp;gt;. Тогда в оптимальном расписании работа с номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; будет выполнена на станке с номером &amp;lt;tex&amp;gt;i \bmod m&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;b_{i}&amp;lt;/tex&amp;gt;-ой с конца.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Здесь предполагается что работы отсортирован в порядке неубывания времён выполнения.&lt;br /&gt;
&lt;br /&gt;
 list&amp;lt;int&amp;gt; schedule[m] &amp;lt;font color=green&amp;gt; //Заведём список работ для каждого станка. Ответ будет храниться в нём.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' n&lt;br /&gt;
         schedule[i mod m].push(i) &amp;lt;font color=green&amp;gt;//ставим работу с номером i на станок i mod m в конец.&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &amp;lt;font color=green&amp;gt;//Заметим что расписание для каждого станка получилось перевёрнутым&amp;lt;br&amp;gt;    //Поэтому развернём расписание для каждого станка.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' m&lt;br /&gt;
         schedule[i].reverse()&lt;br /&gt;
&lt;br /&gt;
=== Ассимптотика ===&lt;br /&gt;
Так как нам понадобится сортировка для массива &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, то итоговая ассимптотика будет &amp;lt;tex&amp;gt;\mathcal{O}(n\log{n})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
Докажем две леммы:&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|statement= В оптимальном расписании на каждом станке работы выполняются в порядке неубывания.&lt;br /&gt;
|proof= Пусть это не так. Заметим что каждая работа даёт вклад в &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; равный &amp;lt;tex&amp;gt;p_{i} \cdot (b_{i} + 1)&amp;lt;/tex&amp;gt;. Тогда поменяем местами две работы которые нарушают порядок невозрастания. Заметим что &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; уменьшилась. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma2&lt;br /&gt;
|statement= В оптимальном расписании количество выполненных работ на любых двух станках отличается не более чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof= Пусть это не так. Как было отмечено в предыдущей лемме, каждая работа даёт вклад в &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; равный &amp;lt;tex&amp;gt;p_{i} \cdot (b_{i} + 1)&amp;lt;/tex&amp;gt;. Найдём два станка количество работ на которых отличается больше чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Пусть это станки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Причём на стнаке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; выполняется больше работ. Тогда если отправить первую с начала работу со станка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; на станок &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; то  &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; уменьшится на разность количества работ на станках &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=theorem1&lt;br /&gt;
|statement= Алгоритм &amp;lt;tex&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt; строит оптимальное расписание.&lt;br /&gt;
|proof= Пусть это не так и оптимальное расписание отличается от расписания построенного алгоритмом. Заметим что расписание построенное алгоритмом удовлетворяет обеим леммам. Тогда можно воспользоваться одной из них чтобы улучшить оптимальное раписание. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие. }}&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54442</id>
		<title>PSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54442"/>
				<updated>2016-06-04T16:50:04Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: /* Псевдокод */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ с заданными временами выполнения &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.  И &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; параллельных станков с одинаковой скоростью выполнения работ.&amp;lt;br&amp;gt;Цель {{---}} составить такое расписание, чтобы суммарное время окончания всех работ было минимальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; заданы в порядке невозрастания (&amp;lt;tex&amp;gt;p_{1}  \geqslant p_{2} \geqslant \ldots \geqslant p_{n} &amp;lt;/tex&amp;gt;). Пусть теперь &amp;lt;tex&amp;gt;b_{k} = \left\lceil\dfrac{k}{m}\right\rceil&amp;lt;/tex&amp;gt;. Тогда в оптимальном расписании работа с номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; будет выполнена на станке с номером &amp;lt;tex&amp;gt;i \bmod m&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;b_{i}&amp;lt;/tex&amp;gt;-ой с конца.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
Здесь предполагается что массив &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; отсортирован в порядке неубывания времён выполнения.&lt;br /&gt;
&lt;br /&gt;
 list&amp;lt;int&amp;gt; schedule[m] &amp;lt;font color=green&amp;gt; //Заведём список работ для каждого станка. Ответ будет храниться в нём.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' n&lt;br /&gt;
         schedule[i mod m].push(i) &amp;lt;font color=green&amp;gt;//ставим работу с номером i на станок i mod m в конец.&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &amp;lt;font color=green&amp;gt;//Заметим что расписание для каждого станка получилось перевёрнутым&amp;lt;br&amp;gt;    //Поэтому развернём расписание для каждого станка.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' m&lt;br /&gt;
         schedule[i].reverse()&lt;br /&gt;
&lt;br /&gt;
=== Ассимптотика ===&lt;br /&gt;
Так как нам понадобится сортировка для массива &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, то итоговая ассимптотика будет &amp;lt;tex&amp;gt;\mathcal{O}(n\log{n})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
Докажем две леммы:&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|statement= В оптимальном расписании на каждом станке работы выполняются в порядке неубывания.&lt;br /&gt;
|proof= Пусть это не так. Заметим что каждая работа даёт вклад в &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; равный &amp;lt;tex&amp;gt;p_{i} \cdot (b_{i} + 1)&amp;lt;/tex&amp;gt;. Тогда поменяем местами две работы которые нарушают порядок невозрастания. Заметим что &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; уменьшилась. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma2&lt;br /&gt;
|statement= В оптимальном расписании количество выполненных работ на любых двух станках отличается не более чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof= Пусть это не так. Как было отмечено в предыдущей лемме, каждая работа даёт вклад в &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; равный &amp;lt;tex&amp;gt;p_{i} \cdot (b_{i} + 1)&amp;lt;/tex&amp;gt;. Найдём два станка количество работ на которых отличается больше чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Пусть это станки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Причём на стнаке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; выполняется больше работ. Тогда если отправить первую с начала работу со станка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; на станок &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; то  &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; уменьшится на разность количества работ на станках &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=theorem1&lt;br /&gt;
|statement= Алгоритм &amp;lt;tex&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt; строит оптимальное расписание.&lt;br /&gt;
|proof= Пусть это не так и оптимальное расписание отличается от расписания построенного алгоритмом. Заметим что расписание построенное алгоритмом удовлетворяет обеим леммам. Тогда можно воспользоваться одной из них чтобы улучшить оптимальное раписание. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие. }}&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54441</id>
		<title>PSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54441"/>
				<updated>2016-06-04T16:48:42Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: /* Идея */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ с заданными временами выполнения &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.  И &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; параллельных станков с одинаковой скоростью выполнения работ.&amp;lt;br&amp;gt;Цель {{---}} составить такое расписание, чтобы суммарное время окончания всех работ было минимальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; заданы в порядке невозрастания (&amp;lt;tex&amp;gt;p_{1}  \geqslant p_{2} \geqslant \ldots \geqslant p_{n} &amp;lt;/tex&amp;gt;). Пусть теперь &amp;lt;tex&amp;gt;b_{k} = \left\lceil\dfrac{k}{m}\right\rceil&amp;lt;/tex&amp;gt;. Тогда в оптимальном расписании работа с номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; будет выполнена на станке с номером &amp;lt;tex&amp;gt;i \bmod m&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;b_{i}&amp;lt;/tex&amp;gt;-ой с конца.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
&lt;br /&gt;
 list&amp;lt;int&amp;gt; schedule[m] &amp;lt;font color=green&amp;gt; //Заведём список работ для каждого станка. Ответ будет храниться в нём.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' n&lt;br /&gt;
         schedule[i mod m].push(i) &amp;lt;font color=green&amp;gt;//ставим работу с номером i на станок i mod m в конец.&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &amp;lt;font color=green&amp;gt;//Заметим что расписание для каждого станка получилось перевёрнутым&amp;lt;br&amp;gt;    //Поэтому развернём расписание для каждого станка.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' m&lt;br /&gt;
         schedule[i].reverse()&lt;br /&gt;
&lt;br /&gt;
=== Ассимптотика ===&lt;br /&gt;
Так как нам понадобится сортировка для массива &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, то итоговая ассимптотика будет &amp;lt;tex&amp;gt;\mathcal{O}(n\log{n})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
Докажем две леммы:&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|statement= В оптимальном расписании на каждом станке работы выполняются в порядке неубывания.&lt;br /&gt;
|proof= Пусть это не так. Заметим что каждая работа даёт вклад в &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; равный &amp;lt;tex&amp;gt;p_{i} \cdot (b_{i} + 1)&amp;lt;/tex&amp;gt;. Тогда поменяем местами две работы которые нарушают порядок невозрастания. Заметим что &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; уменьшилась. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma2&lt;br /&gt;
|statement= В оптимальном расписании количество выполненных работ на любых двух станках отличается не более чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof= Пусть это не так. Как было отмечено в предыдущей лемме, каждая работа даёт вклад в &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; равный &amp;lt;tex&amp;gt;p_{i} \cdot (b_{i} + 1)&amp;lt;/tex&amp;gt;. Найдём два станка количество работ на которых отличается больше чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Пусть это станки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Причём на стнаке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; выполняется больше работ. Тогда если отправить первую с начала работу со станка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; на станок &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; то  &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; уменьшится на разность количества работ на станках &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=theorem1&lt;br /&gt;
|statement= Алгоритм &amp;lt;tex&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt; строит оптимальное расписание.&lt;br /&gt;
|proof= Пусть это не так и оптимальное расписание отличается от расписания построенного алгоритмом. Заметим что расписание построенное алгоритмом удовлетворяет обеим леммам. Тогда можно воспользоваться одной из них чтобы улучшить оптимальное раписание. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие. }}&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54440</id>
		<title>PSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54440"/>
				<updated>2016-06-04T16:47:15Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: /* Доказательство корректности */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ с заданными временами выполнения &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.  И &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; параллельных станков с одинаковой скоростью выполнения работ.&amp;lt;br&amp;gt;Цель {{---}} составить такое расписание, чтобы суммарное время окончания всех работ было минимальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; заданы в порядке невозрастания (&amp;lt;tex&amp;gt;p_{1}  \geqslant p_{2} \geqslant \ldots \geqslant p_{n} &amp;lt;/tex&amp;gt;). Пусть теперь &amp;lt;tex&amp;gt;b_{k} = \left\lceil\dfrac{k}{m}\right\rceil&amp;lt;/tex&amp;gt;. Тогда в оптимальном расписании работа с номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; будет выполнена на станке &amp;lt;tex&amp;gt;i \bmod m&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;b_{i}&amp;lt;/tex&amp;gt;-ой с конца.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
&lt;br /&gt;
 list&amp;lt;int&amp;gt; schedule[m] &amp;lt;font color=green&amp;gt; //Заведём список работ для каждого станка. Ответ будет храниться в нём.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' n&lt;br /&gt;
         schedule[i mod m].push(i) &amp;lt;font color=green&amp;gt;//ставим работу с номером i на станок i mod m в конец.&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &amp;lt;font color=green&amp;gt;//Заметим что расписание для каждого станка получилось перевёрнутым&amp;lt;br&amp;gt;    //Поэтому развернём расписание для каждого станка.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' m&lt;br /&gt;
         schedule[i].reverse()&lt;br /&gt;
&lt;br /&gt;
=== Ассимптотика ===&lt;br /&gt;
Так как нам понадобится сортировка для массива &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, то итоговая ассимптотика будет &amp;lt;tex&amp;gt;\mathcal{O}(n\log{n})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;br /&gt;
Докажем две леммы:&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma1&lt;br /&gt;
|statement= В оптимальном расписании на каждом станке работы выполняются в порядке неубывания.&lt;br /&gt;
|proof= Пусть это не так. Заметим что каждая работа даёт вклад в &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; равный &amp;lt;tex&amp;gt;p_{i} \cdot (b_{i} + 1)&amp;lt;/tex&amp;gt;. Тогда поменяем местами две работы которые нарушают порядок невозрастания. Заметим что &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; уменьшилась. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma2&lt;br /&gt;
|statement= В оптимальном расписании количество выполненных работ на любых двух станках отличается не более чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof= Пусть это не так. Как было отмечено в предыдущей лемме, каждая работа даёт вклад в &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; равный &amp;lt;tex&amp;gt;p_{i} \cdot (b_{i} + 1)&amp;lt;/tex&amp;gt;. Найдём два станка количество работ на которых отличается больше чем на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Пусть это станки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Причём на стнаке &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; выполняется больше работ. Тогда если отправить первую с начала работу со станка &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; на станок &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; то  &amp;lt;tex&amp;gt;\sum C_{i}&amp;lt;/tex&amp;gt; уменьшится на разность количества работ на станках &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие.}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|id=theorem1&lt;br /&gt;
|statement= Алгоритм &amp;lt;tex&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt; строит оптимальное расписание.&lt;br /&gt;
|proof= Пусть это не так и оптимальное расписание отличается от расписания построенного алгоритмом. Заметим что расписание построенное алгоритмом удовлетворяет обеим леммам. Тогда можно воспользоваться одной из них чтобы улучшить оптимальное раписание. Следовательно {{---}} оптимальное расписание не оптимально. Противоречие. }}&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54439</id>
		<title>PSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54439"/>
				<updated>2016-06-04T16:23:43Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ с заданными временами выполнения &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.  И &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; параллельных станков с одинаковой скоростью выполнения работ.&amp;lt;br&amp;gt;Цель {{---}} составить такое расписание, чтобы суммарное время окончания всех работ было минимальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; заданы в порядке невозрастания (&amp;lt;tex&amp;gt;p_{1}  \geqslant p_{2} \geqslant \ldots \geqslant p_{n} &amp;lt;/tex&amp;gt;). Пусть теперь &amp;lt;tex&amp;gt;b_{k} = \left\lceil\dfrac{k}{m}\right\rceil&amp;lt;/tex&amp;gt;. Тогда в оптимальном расписании работа с номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; будет выполнена на станке &amp;lt;tex&amp;gt;i \bmod m&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;b_{i}&amp;lt;/tex&amp;gt;-ой с конца.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
&lt;br /&gt;
 list&amp;lt;int&amp;gt; schedule[m] &amp;lt;font color=green&amp;gt; //Заведём список работ для каждого станка. Ответ будет храниться в нём.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' n&lt;br /&gt;
         schedule[i mod m].push(i) &amp;lt;font color=green&amp;gt;//ставим работу с номером i на станок i mod m в конец.&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &amp;lt;font color=green&amp;gt;//Заметим что расписание для каждого станка получилось перевёрнутым&amp;lt;br&amp;gt;    //Поэтому развернём расписание для каждого станка.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' m&lt;br /&gt;
         schedule[i].reverse()&lt;br /&gt;
&lt;br /&gt;
=== Ассимптотика ===&lt;br /&gt;
Так как нам понадобится сортировка для массива &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, то итоговая ассимптотика будет &amp;lt;tex&amp;gt;\mathcal{O}(n\log{n})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Доказательство корректности ==&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54438</id>
		<title>PSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54438"/>
				<updated>2016-06-04T16:22:34Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: /* Идея */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ с заданными временами выполнения &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.  И &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; параллельных станков с одинаковой скоростью выполнения работ.&amp;lt;br&amp;gt;Цель {{---}} составить такое расписание, чтобы суммарное время окончания всех работ было минимальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; заданы в порядке невозрастания (&amp;lt;tex&amp;gt;p_{1}  \geqslant p_{2} \geqslant \ldots \geqslant p_{n} &amp;lt;/tex&amp;gt;). Пусть теперь &amp;lt;tex&amp;gt;b_{k} = \left\lceil\dfrac{k}{m}\right\rceil&amp;lt;/tex&amp;gt;. Тогда в оптимальном расписании работа с номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; будет выполнена на станке &amp;lt;tex&amp;gt;i \bmod m&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;b_{i}&amp;lt;/tex&amp;gt;-ой с конца.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
&lt;br /&gt;
 list&amp;lt;int&amp;gt; schedule[m] &amp;lt;font color=green&amp;gt; //Заведём список работ для каждого станка. Ответ будет храниться в нём.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' n&lt;br /&gt;
         schedule[i mod m].push(i) &amp;lt;font color=green&amp;gt;//ставим работу с номером i на станок i mod m в конец.&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &amp;lt;font color=green&amp;gt;//Заметим что расписание для каждого станка получилось перевёрнутым&amp;lt;br&amp;gt;    //Поэтому развернём расписание для каждого станка.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' m&lt;br /&gt;
         schedule[i].reverse()&lt;br /&gt;
&lt;br /&gt;
=== Ассимптотика ===&lt;br /&gt;
Так как нам понадобится сортировка для массива &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, то итоговая ассимптотика будет &amp;lt;tex&amp;gt;\mathcal{O}(n\log{n})&amp;lt;/tex&amp;gt;.&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54436</id>
		<title>PSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54436"/>
				<updated>2016-06-04T16:18:03Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: /* Описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ с заданными временами выполнения &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.  И &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; параллельных станков с одинаковой скоростью выполнения работ.&amp;lt;br&amp;gt;Цель {{---}} составить такое расписание, чтобы суммарное время окончания всех работ было минимальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; заданы в порядке невозрастания (&amp;lt;tex&amp;gt;p_{1}  \geqslant p_{2} \geqslant \ldots \geqslant p_{n} &amp;lt;/tex&amp;gt;). Пусть теперь &amp;lt;tex&amp;gt;b_{k} = \dfrac{k}{m}&amp;lt;/tex&amp;gt;. Тогда в оптимальном расписании работа с номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; будет выполнена на станке &amp;lt;tex&amp;gt;i \bmod m&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;b_{i}&amp;lt;/tex&amp;gt;-ой с конца.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
&lt;br /&gt;
 list&amp;lt;int&amp;gt; schedule[m] &amp;lt;font color=green&amp;gt; //Заведём список работ для каждого станка. Ответ будет храниться в нём.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' n&lt;br /&gt;
         schedule[i mod m].push(i) &amp;lt;font color=green&amp;gt;//ставим работу с номером i на станок i mod m в конец.&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &amp;lt;font color=green&amp;gt;//Заметим что расписание для каждого станка получилось перевёрнутым&amp;lt;br&amp;gt;    //Поэтому развернём расписание для каждого станка.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' m&lt;br /&gt;
         schedule[i].reverse()&lt;br /&gt;
&lt;br /&gt;
=== Ассимптотика ===&lt;br /&gt;
Так как нам понадобится сортировка для массива &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, то итоговая ассимптотика будет &amp;lt;tex&amp;gt;\mathcal{O}(n\log{n})&amp;lt;/tex&amp;gt;.&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54435</id>
		<title>PSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54435"/>
				<updated>2016-06-04T16:16:01Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ с заданными временами выполнения &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.  И &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; параллельных станков с одинаковой скоростью выполнения работ.&amp;lt;br&amp;gt;Цель {{---}} составить такое расписание, чтобы суммарное время окончания всех работ было минимальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
=== Идея ===&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; заданы в порядке невозрастания (&amp;lt;tex&amp;gt;p_{1}  \geqslant p_{2} \geqslant \ldots \geqslant p_{n} &amp;lt;/tex&amp;gt;). Пусть теперь &amp;lt;tex&amp;gt;b_{k} = \dfrac{k}{m}&amp;lt;/tex&amp;gt;. Тогда в оптимальном расписании работа с номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; будет выполнена на станке &amp;lt;tex&amp;gt;i \bmod m&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;b_{i}&amp;lt;/tex&amp;gt;-ой с конца.&lt;br /&gt;
&lt;br /&gt;
=== Псевдокод ===&lt;br /&gt;
&lt;br /&gt;
 list&amp;lt;int&amp;gt; schedule[m] &amp;lt;font color=green&amp;gt; //Заведём список работ для каждого станка. Ответ будет храниться в нём.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' n&lt;br /&gt;
         schedule[i mod m].push(i) &amp;lt;font color=green&amp;gt;//ставим работу с номером i на станок i mod m в конец.&amp;lt;/font&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
     &amp;lt;font color=green&amp;gt;//Заметим что расписание для каждого станка получилось перевёрнутым&amp;lt;br&amp;gt;    //Поэтому развернём расписание для каждого станка.&amp;lt;/font&amp;gt;&lt;br /&gt;
     '''for''' i = 0 '''to''' m&lt;br /&gt;
         schedule[i].reverse()&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54432</id>
		<title>PSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54432"/>
				<updated>2016-06-04T15:48:07Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;tex dpi = &amp;quot;200&amp;quot;&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt;&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ с заданными временами выполнения &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.  И &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; параллельных станков с одинаковой скоростью выполнения работ.&amp;lt;br&amp;gt;Цель {{---}} составить такое расписание, чтобы суммарное время окончания всех работ было минимальным.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Идея ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; заданы в порядке невозрастания (&amp;lt;tex&amp;gt;p_{1}  \geqslant p_{2} \geqslant \ldots \geqslant p_{n} &amp;lt;/tex&amp;gt;). Пусть теперь &amp;lt;tex&amp;gt;b_{k} = \dfrac{k}{m}&amp;lt;/tex&amp;gt;. Тогда в оптимальном расписании работа с номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; будет выполнена на станке &amp;lt;tex&amp;gt;i \bmod m&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;b_{i}&amp;lt;/tex&amp;gt;-ой с конца.&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54431</id>
		<title>PSumCi</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=PSumCi&amp;diff=54431"/>
				<updated>2016-06-04T15:42:11Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: Новая страница: «== Описание алгоритма == Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ с временами выполнения &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.  И &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; один...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Описание алгоритма ==&lt;br /&gt;
Дано &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ с временами выполнения &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.  И &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; одинаковых параллельных машин. Нужно минимизировать суммарные времена завершения.&lt;br /&gt;
&lt;br /&gt;
== Идея ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt; заданы в порядке невозрастания (&amp;lt;tex&amp;gt;p_{1}  \geqslant p_{2} \geqslant \ldots \geqslant p_{n} &amp;lt;/tex&amp;gt;). Пусть теперь &amp;lt;tex&amp;gt;b_{k} = \dfrac{k}{m}&amp;lt;/tex&amp;gt;. Тогда в оптимальном расписании работа с номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; будет выполнена на станке &amp;lt;tex&amp;gt;i \bmod m&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;b_{i}&amp;lt;/tex&amp;gt;-ой с конца.&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%94%D0%B8%D1%81%D0%BA%D1%80%D0%B5%D1%82%D0%BD%D0%B0%D1%8F_%D0%BC%D0%B0%D1%82%D0%B5%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0,_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D0%B8_%D1%81%D1%82%D1%80%D1%83%D0%BA%D1%82%D1%83%D1%80%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=54429</id>
		<title>Дискретная математика, алгоритмы и структуры данных</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%94%D0%B8%D1%81%D0%BA%D1%80%D0%B5%D1%82%D0%BD%D0%B0%D1%8F_%D0%BC%D0%B0%D1%82%D0%B5%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0,_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D0%B8_%D1%81%D1%82%D1%80%D1%83%D0%BA%D1%82%D1%83%D1%80%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=54429"/>
				<updated>2016-06-04T15:31:01Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: /* Задачи для произвольного числа станков */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
Убедительная просьба читать [[Обсуждение:Дискретная_математика_и_алгоритмы | правила оформления вики-конспектов]].&lt;br /&gt;
&lt;br /&gt;
Символом &amp;lt;tex&amp;gt; \star &amp;lt;/tex&amp;gt; помечены дополнительные темы (возможно, сложные), которые не были подробно рассмотрены (или вообще рассмотрены) в рамках курса.&lt;br /&gt;
&lt;br /&gt;
= Первый семестр =&lt;br /&gt;
&lt;br /&gt;
== Отношения ==&lt;br /&gt;
*[[Определение отношения]]&lt;br /&gt;
*[[Композиция отношений|Композиция отношений, степень отношения, обратное отношение]]&lt;br /&gt;
*[[Рефлексивное отношение|Рефлексивное отношение. Антирефлексивное отношение.]]&lt;br /&gt;
*[[Симметричное отношение]]&lt;br /&gt;
*[[Антисимметричное отношение]]&lt;br /&gt;
*[[Транзитивное отношение]]&lt;br /&gt;
*[[Отношение порядка]]&lt;br /&gt;
*[[Отношение эквивалентности]]&lt;br /&gt;
*[[Транзитивное замыкание|Транзитивное замыкание отношения]]&lt;br /&gt;
*[[Алгоритм Флойда — Уоршелла|Алгоритм Флойда-Уоршалла построения транзитивного замыкания отношения]]&lt;br /&gt;
*[[Транзитивный остов]]&lt;br /&gt;
&lt;br /&gt;
== Булевы функции ==&lt;br /&gt;
*[[Определение булевой функции]]&lt;br /&gt;
*[[Побитовые операции]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Суперпозиции]]&lt;br /&gt;
*[[ДНФ]]&lt;br /&gt;
*[[Сокращенная и минимальная ДНФ | Сокращенная и минимальная ДНФ, минимизация ДНФ методами гиперкубов, карт Карно, Квайна]]&lt;br /&gt;
*[[КНФ]]&lt;br /&gt;
*[[2-SAT]]&lt;br /&gt;
*[[Специальные формы КНФ|Специальные формы КНФ: КНФ в форме Хорна и КНФ в форме Крома]]&lt;br /&gt;
*[[Полином Жегалкина | Полином Жегалкина, преобразование Мёбиуса]]&lt;br /&gt;
*[[Полные системы функций. Теорема Поста о полной системе функций]]&lt;br /&gt;
*[[Представление функции класса DM с помощью медианы]]&lt;br /&gt;
*[[Пороговая функция]]&lt;br /&gt;
*[[Троичная логика]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Схемы из функциональных элементов ==&lt;br /&gt;
*[[Реализация булевой функции схемой из функциональных элементов]]&lt;br /&gt;
*[[Простейшие методы синтеза схем из функциональных элементов]]&lt;br /&gt;
*[[Метод Лупанова синтеза схем]]&lt;br /&gt;
*[[Cумматор]]&lt;br /&gt;
*[[Каскадный сумматор]]&lt;br /&gt;
*[[Двоичный каскадный сумматор]]&lt;br /&gt;
*[[Троичный сумматор]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Реализация вычитания сумматором]]&lt;br /&gt;
*[[Матричный умножитель]]&lt;br /&gt;
*[[Дерево Уоллеса]]&lt;br /&gt;
*[[Контактная схема]]&lt;br /&gt;
*[[Триггеры]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Квантовые гейты]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Представление информации ==&lt;br /&gt;
*[[Кодирование информации]]&lt;br /&gt;
*[[Представление целых чисел: прямой код, код со сдвигом, дополнительный код]]&lt;br /&gt;
*[[Представление вещественных чисел]]&lt;br /&gt;
*[[Представление символов, таблицы кодировок]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Алгоритмы сжатия ==&lt;br /&gt;
* [[Алгоритм Хаффмана]]&lt;br /&gt;
* [[Оптимальное хранение словаря в алгоритме Хаффмана]]&lt;br /&gt;
* [[Алгоритм Хаффмана за O(n)]]&lt;br /&gt;
* [[Алгоритм Ху-Таккера]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Неравенство Крафта]]&lt;br /&gt;
* [[Неравенство Макмиллана]]&lt;br /&gt;
* [[Код Шеннона]]&lt;br /&gt;
* [[Оптимальный префиксный код с длиной кодового слова не более L бит]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритмы LZ77 и LZ78]]&lt;br /&gt;
* [[Алгоритм LZW]]&lt;br /&gt;
* [[Алгоритм LZSS]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Преобразование Барроуза-Уиллера | Преобразование Барроуза-Уиллера и обратное ему]]&lt;br /&gt;
* [[Преобразование MTF]]&lt;br /&gt;
* [[Расстояние Хэмминга]]&lt;br /&gt;
* [[Избыточное кодирование, код Хэмминга]]&lt;br /&gt;
* [[Гамма-, дельта- и омега-код Элиаса]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Комбинаторика ==&lt;br /&gt;
=== Комбинаторные объекты ===&lt;br /&gt;
* [[Комбинаторные объекты]]&lt;br /&gt;
* [[Лексикографический порядок]]&lt;br /&gt;
* [[Коды Грея]]&lt;br /&gt;
* [[Коды Грея для перестановок]]&lt;br /&gt;
* [[Коды антигрея]]&lt;br /&gt;
* [[Цепные коды]]&lt;br /&gt;
* [[Правильные скобочные последовательности]]&lt;br /&gt;
&lt;br /&gt;
=== Генерация комбинаторных объектов ===&lt;br /&gt;
* [[Генерация комбинаторных объектов в лексикографическом порядке]]&lt;br /&gt;
* [[Получение номера по объекту]]&lt;br /&gt;
* [[Получение объекта по номеру]]&lt;br /&gt;
* [[Получение следующего объекта]]&lt;br /&gt;
* [[Получение предыдущего объекта]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;  &lt;br /&gt;
* [[Метод генерации случайной перестановки, алгоритм Фишера-Йетса]]&lt;br /&gt;
* [[Методы генерации случайного сочетания]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Подсчёт числа объектов ===&lt;br /&gt;
* [[Формула включения-исключения | Формула включения-исключения, подсчет числа беспорядков]]&lt;br /&gt;
* [[Нахождение количества разбиений числа на слагаемые | Нахождение количества разбиений числа на слагаемые. Пентагональная теорема Эйлера]]&lt;br /&gt;
* [[Производящая функция]]&lt;br /&gt;
* [[Лемма Бёрнсайда и Теорема Пойа]]&lt;br /&gt;
* [[Задача об ожерельях]]&lt;br /&gt;
* [[Числа Стирлинга первого рода]]&lt;br /&gt;
* [[Числа Стирлинга второго рода]]&lt;br /&gt;
* [[Числа Эйлера I и II рода | Числа Эйлера первого и второго рода. Подъемы в перестановках]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Числа Каталана]]&lt;br /&gt;
&lt;br /&gt;
=== Свойства комбинаторных объектов ===&lt;br /&gt;
* [[Умножение перестановок, обратная перестановка, группа перестановок]]&lt;br /&gt;
* [[Действие перестановки на набор из элементов, представление в виде циклов]]&lt;br /&gt;
* [[Таблица инверсий]]&lt;br /&gt;
* [[Теорема Кэли]]&lt;br /&gt;
* [[Матричное представление перестановок]]&lt;br /&gt;
* [[Задача о минимуме/максимуме скалярного произведения]]&lt;br /&gt;
* [[Задача о монотонных подпоследовательностях, теорема о связи длины НВП и НУП]]&lt;br /&gt;
&lt;br /&gt;
== [[Динамическое программирование]] ==&lt;br /&gt;
=== Классические задачи динамического программирования ===&lt;br /&gt;
*[[Кратчайший путь в ациклическом графе]]&lt;br /&gt;
*[[Задача о числе путей в ациклическом графе]]&lt;br /&gt;
*[[Задача о расстановке знаков в выражении]]&lt;br /&gt;
*[[Задача о порядке перемножения матриц]]&lt;br /&gt;
*[[Задача о наибольшей общей подпоследовательности]]&lt;br /&gt;
*[[Задача о наибольшей возрастающей подпоследовательности]]&lt;br /&gt;
*[[Задача коммивояжера, ДП по подмножествам]]&lt;br /&gt;
*[[Задача о редакционном расстоянии, алгоритм Вагнера-Фишера]]&lt;br /&gt;
*[[Задача о рюкзаке]]&lt;br /&gt;
&lt;br /&gt;
=== Способы оптимизации методов динамического программирования ===&lt;br /&gt;
*[[Метод четырех русских для умножения матриц]]&lt;br /&gt;
*[[Применение метода четырех русских в задачах ДП на примере задачи о НОП]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Задача об оптимальном префиксном коде с сохранением порядка. Монотонность точки разреза]]&lt;br /&gt;
*[[Meet-in-the-middle]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Другие задачи ===&lt;br /&gt;
*[[Задача о расстоянии Дамерау-Левенштейна]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Задача о выводе в контекстно-свободной грамматике, алгоритм Кока-Янгера-Касами]]&lt;br /&gt;
*[[Задача о наибольшей подпоследовательности-палиндроме]]&lt;br /&gt;
*[[Наибольшая общая возрастающая подпоследовательность]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Задача о наибольшей общей палиндромной подпоследовательности]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Динамическое программирование по профилю]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Динамика по поддеревьям]]&lt;br /&gt;
&lt;br /&gt;
== Теория вероятностей ==&lt;br /&gt;
*[[Вероятностное пространство, элементарный исход, событие]]&lt;br /&gt;
*[[Независимые события]]&lt;br /&gt;
*[[Условная вероятность]]&lt;br /&gt;
*[[Формула полной вероятности]]&lt;br /&gt;
*[[Формула Байеса]]&lt;br /&gt;
*[[Дискретная случайная величина]]&lt;br /&gt;
*[[Независимые случайные величины]]&lt;br /&gt;
*[[Математическое ожидание случайной величины]]&lt;br /&gt;
*[[Дисперсия случайной величины]]&lt;br /&gt;
*[[Ковариация случайных величин]]&lt;br /&gt;
*[[Корреляция случайных величин]]&lt;br /&gt;
*[[Неравенство Маркова]]&lt;br /&gt;
*[[Энтропия случайного источника]]&lt;br /&gt;
*[[Симуляция одним распределением другого]]&lt;br /&gt;
*[[Арифметическое кодирование]]&lt;br /&gt;
*[[Парадоксы теории вероятностей]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
*[[Схема Бернулли]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Марковские цепи ==&lt;br /&gt;
&lt;br /&gt;
* [[Марковская цепь]]&lt;br /&gt;
* [[Теорема о поглощении]]&lt;br /&gt;
* [[Фундаментальная матрица]]&lt;br /&gt;
* [[Математическое ожидание времени поглощения]]&lt;br /&gt;
* [[Расчет вероятности поглощения в состоянии]]&lt;br /&gt;
* [[Эргодическая марковская цепь]]&lt;br /&gt;
* [[Регулярная марковская цепь]]&lt;br /&gt;
* [[Примеры использования Марковских цепей]]&lt;br /&gt;
* [[Скрытые Марковские модели]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм Витерби]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм &amp;quot;Вперед-Назад&amp;quot;]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм Баума-Велша]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Второй семестр =&lt;br /&gt;
&lt;br /&gt;
== Амортизационный анализ ==&lt;br /&gt;
* [[Амортизационный анализ]]&lt;br /&gt;
* [[Динамический массив]]&lt;br /&gt;
* [[Hashed Array Tree]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Список]]&lt;br /&gt;
* [[Стек]]&lt;br /&gt;
* [[Очередь]]&lt;br /&gt;
* [[Дек]]&lt;br /&gt;
* [[Мажорирующий элемент]]&lt;br /&gt;
* [[Счетчик Кнута]]&lt;br /&gt;
* [[Мастер-теорема]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[List order maintenance]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Персистентные структуры данных ==&lt;br /&gt;
* [[Персистентные структуры данных]]&lt;br /&gt;
* [[Персистентный стек]]&lt;br /&gt;
* [[Персистентная очередь]]&lt;br /&gt;
* [[Персистентный дек]]&lt;br /&gt;
* [[Персистентная приоритетная очередь]]&lt;br /&gt;
&lt;br /&gt;
== [[Приоритетные очереди]] ==&lt;br /&gt;
* [[Двоичная куча]]&lt;br /&gt;
* [[Биномиальная куча]]&lt;br /&gt;
* [[Фибоначчиева куча]]&lt;br /&gt;
* [[Левосторонняя куча]]&lt;br /&gt;
* [[Тонкая куча]]&lt;br /&gt;
* [[Толстая куча на избыточном счетчике]]&lt;br /&gt;
* [[Куча Бродала-Окасаки]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Система непересекающихся множеств ==&lt;br /&gt;
* [[СНМ (наивные реализации) | Наивные реализации]]&lt;br /&gt;
* [[СНМ (списки с весовой эвристикой) | Списки с весовой эвристикой]]&lt;br /&gt;
* [[СНМ(реализация с помощью леса корневых деревьев) | Реализация с помощью леса корневых деревьев]]&lt;br /&gt;
* [[СНМ с операцией удаления за О(1)]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [[Поисковые структуры данных]] ==&lt;br /&gt;
* [[Упорядоченное множество]]&lt;br /&gt;
* [[Дерево поиска, наивная реализация]]&lt;br /&gt;
* [[АВЛ-дерево]]&lt;br /&gt;
* [[2-3 дерево]]&lt;br /&gt;
* [[B-дерево]]&lt;br /&gt;
* [[Красно-черное дерево]]&lt;br /&gt;
* [[Декартово дерево]]&lt;br /&gt;
* [[Декартово дерево по неявному ключу]]&lt;br /&gt;
* [[Splay-дерево]]&lt;br /&gt;
* [[Tango-дерево]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Рандомизированное бинарное дерево поиска]]&lt;br /&gt;
* [[Дерево ван Эмде Боаса]]&lt;br /&gt;
* [[Список с пропусками]]&lt;br /&gt;
* [[Fusion tree]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Сверхбыстрый цифровой бор]]&lt;br /&gt;
* [[Rope]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Дерево отрезков ==&lt;br /&gt;
&lt;br /&gt;
* [[Статистики на отрезках. Корневая эвристика]]&lt;br /&gt;
* [[Дерево отрезков. Построение]]&lt;br /&gt;
* [[Реализация запроса в дереве отрезков сверху]]&lt;br /&gt;
* [[Реализация запроса в дереве отрезков снизу]]&lt;br /&gt;
* [[Несогласованные поддеревья. Реализация массового обновления]]&lt;br /&gt;
* [[Многомерное дерево отрезков]]&lt;br /&gt;
* [[Сжатое многомерное дерево отрезков]]&lt;br /&gt;
&lt;br /&gt;
== Дерево Фенвика ==&lt;br /&gt;
* [[Дерево Фенвика]]&lt;br /&gt;
* [[Встречное дерево Фенвика]]&lt;br /&gt;
* [[Дерево Фенвика для некоммутативных операций]]&lt;br /&gt;
* [[Многомерное дерево Фенвика]]&lt;br /&gt;
&lt;br /&gt;
== Хеширование ==&lt;br /&gt;
* [[Хеш-таблица]]&lt;br /&gt;
* [[Разрешение коллизий]]&lt;br /&gt;
* [[Хеширование кукушки]]&lt;br /&gt;
* [[Идеальное хеширование]]&lt;br /&gt;
* [[Перехеширование]]&lt;br /&gt;
* [[Фильтр Блума]]&lt;br /&gt;
* [[Quotient filter]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Универсальное семейство хеш-функций]]&lt;br /&gt;
* [[Расширяемое хеширование]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [[Сортировки]] ==&lt;br /&gt;
=== Квадратичные сортировки ===&lt;br /&gt;
* [[Сортировка выбором]]&lt;br /&gt;
* [[Сортировка пузырьком]]&lt;br /&gt;
* [[Сортировка вставками]]&lt;br /&gt;
=== Сортировки на сравнениях ===&lt;br /&gt;
* [[Сортировка Шелла]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Сортировка кучей]]&lt;br /&gt;
* [[Быстрая сортировка]]&lt;br /&gt;
* [[Сортировка слиянием]]&lt;br /&gt;
* [[Cортировка слиянием с использованием O(1) дополнительной памяти]]&lt;br /&gt;
* [[Терпеливая сортировка]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Timsort]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Smoothsort]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Теорема о нижней оценке для сортировки сравнениями]]&lt;br /&gt;
&lt;br /&gt;
=== Многопоточные сортировки ===&lt;br /&gt;
* [[Многопоточная сортировка слиянием]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[PSRS-сортировка]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
=== Другие сортировки ===&lt;br /&gt;
* [[Поиск k-ой порядковой статистики]]&lt;br /&gt;
* [[Поиск k-ой порядковой статистики за линейное время]]&lt;br /&gt;
* [[Поиск k-ой порядковой статистики в двух массивах]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Сортировка подсчетом]]&lt;br /&gt;
* [[Цифровая сортировка]]&lt;br /&gt;
* [[Карманная сортировка]]&lt;br /&gt;
* [[Сортировка Хана]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Задача флага Нидерландов]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Блинная сортировка]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Сортирующие сети ==&lt;br /&gt;
* [[Сортирующие сети]]&lt;br /&gt;
* [[0-1 принцип | Проверка сети компараторов на то, что она сортирующая. 0-1 принцип]]&lt;br /&gt;
* [[Сортирующие сети для квадратичных сортировок]]&lt;br /&gt;
* [[Сортировочные сети с особыми свойствами]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Сеть Бетчера]]&lt;br /&gt;
&lt;br /&gt;
== Алгоритмы поиска ==&lt;br /&gt;
* [[Целочисленный двоичный поиск]]&lt;br /&gt;
* [[Поиск в матрице]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Вещественный двоичный поиск]]&lt;br /&gt;
* [[Троичный поиск]]&lt;br /&gt;
* [[Поиск с помощью золотого сечения]]&lt;br /&gt;
* [[Интерполяционный поиск]]&lt;br /&gt;
* [[Метод Фибоначчи]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Связь между структурами данных ==&lt;br /&gt;
* [[Связь между структурами данных]]&lt;br /&gt;
&lt;br /&gt;
= Третий семестр =&lt;br /&gt;
&lt;br /&gt;
== Основные определения теории графов ==&lt;br /&gt;
* [[Основные определения теории графов|Основные определения: граф, ребро, вершина, степень, петля, путь, цикл]]&lt;br /&gt;
* [[Лемма о рукопожатиях]]&lt;br /&gt;
* [[Теорема о существовании простого пути в случае существования пути]]&lt;br /&gt;
* [[Теорема о существовании простого цикла в случае существования цикла]]&lt;br /&gt;
* [[Матрица смежности графа]]&lt;br /&gt;
* [[Матрица инцидентности графа]]&lt;br /&gt;
* [[Циклическое пространство графа]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Фундаментальные циклы графа]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Дерево, эквивалентные определения]]&lt;br /&gt;
* [[Алгоритмы на деревьях]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Дополнительный, самодополнительный граф]]&lt;br /&gt;
* [[Теоретико-множественные операции над графами]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Рёберное ядро]]&lt;br /&gt;
* [[Факторизация графов]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Связность в графах ==&lt;br /&gt;
* [[Отношение связности, компоненты связности]]&lt;br /&gt;
* [[Отношение реберной двусвязности]]&lt;br /&gt;
* [[Отношение вершинной двусвязности]]&lt;br /&gt;
* [[Точка сочленения, эквивалентные определения]]&lt;br /&gt;
* [[Мост, эквивалентные определения]]&lt;br /&gt;
* [[Граф компонент реберной двусвязности]]&lt;br /&gt;
* [[Граф блоков-точек сочленения]]&lt;br /&gt;
* [[k-связность]]&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;
* [[Алгоритм построения Эйлерова цикла]]&lt;br /&gt;
* [[Произвольно вычерчиваемые из заданной вершины графы]]&lt;br /&gt;
=== Гамильтоновы графы ===&lt;br /&gt;
* [[Гамильтоновы графы]]&lt;br /&gt;
* [[Теорема Хватала]]&lt;br /&gt;
* [[Теорема Дирака]]&lt;br /&gt;
* [[Теорема Оре]]&lt;br /&gt;
* [[Теорема Поша]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Теорема Гуйя-Ури]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм нахождения Гамильтонова цикла в условиях теорем Дирака и Оре]]&lt;br /&gt;
* [[Теорема Гринберга]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Турниры]]&lt;br /&gt;
* [[Теорема Редеи-Камиона]]&lt;br /&gt;
&lt;br /&gt;
== Укладки графов ==&lt;br /&gt;
* [[Укладка графа на плоскости]]&lt;br /&gt;
* [[Формула Эйлера]]&lt;br /&gt;
* [[Непланарность K5 и K3,3|Непланарность &amp;lt;tex&amp;gt;K_5&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;K_{3,3}&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;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Двойственный граф планарного графа]]&lt;br /&gt;
* [[Теорема Фари]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Гамма-алгоритм]]&lt;br /&gt;
&lt;br /&gt;
== Раскраски графов ==&lt;br /&gt;
* [[Раскраска графа]]&lt;br /&gt;
* [[Двудольные графы и раскраска в 2 цвета]]&lt;br /&gt;
* [[Хроматический многочлен]]&lt;br /&gt;
* [[Формула Зыкова]]&lt;br /&gt;
* [[Формула Уитни]]&lt;br /&gt;
* [[Теорема Брукса]]&lt;br /&gt;
* [[Верхние и нижние оценки хроматического числа]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Хроматическое число планарного графа]]&lt;br /&gt;
* [[Многочлен Татта]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Теория Рамсея]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Обход в глубину ==&lt;br /&gt;
* [[Обход в глубину, цвета вершин]]&lt;br /&gt;
* [[Лемма о белых путях]]&lt;br /&gt;
* [[Использование обхода в глубину для проверки связности]]&lt;br /&gt;
* [[Использование обхода в глубину для поиска цикла]]&lt;br /&gt;
* [[Использование обхода в глубину для топологической сортировки]]&lt;br /&gt;
* [[Использование обхода в глубину для поиска компонент сильной связности]]&lt;br /&gt;
* [[Использование обхода в глубину для поиска точек сочленения]]&lt;br /&gt;
* [[Построение компонент вершинной двусвязности]]&lt;br /&gt;
* [[Использование обхода в глубину для поиска мостов]]&lt;br /&gt;
* [[Построение компонент реберной двусвязности]]&lt;br /&gt;
&lt;br /&gt;
== Кратчайшие пути в графах ==&lt;br /&gt;
* [[Обход в ширину]]&lt;br /&gt;
* [[Алгоритм Форда-Беллмана]]&lt;br /&gt;
* [[Алгоритм Дейкстры]]&lt;br /&gt;
* [[Алгоритм Флойда]]&lt;br /&gt;
* [[Алгоритм Джонсона]]&lt;br /&gt;
* [[Алгоритм Левита]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм A*]] &amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм D*]] &amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Эвристики для поиска кратчайших путей]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Задача о паросочетании ==&lt;br /&gt;
* [[Паросочетания: основные определения, теорема о максимальном паросочетании и дополняющих цепях]]&lt;br /&gt;
* [[Алгоритм Форда-Фалкерсона для поиска максимального паросочетания]]&lt;br /&gt;
* [[Алгоритм Куна для поиска максимального паросочетания]]&lt;br /&gt;
* [[Теорема Холла]]&lt;br /&gt;
* [[Связь максимального паросочетания и минимального вершинного покрытия в двудольных графах]]&lt;br /&gt;
* [[Связь вершинного покрытия и независимого множества]]&lt;br /&gt;
* [[Рёберное ядро]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Матрица Татта и связь с размером максимального паросочетания в двудольном графе]]&lt;br /&gt;
* [[Теорема Татта о существовании полного паросочетания]]&lt;br /&gt;
* [[Алгоритм вырезания соцветий|Паросочетания в недвудольных графах. Алгоритм вырезания соцветий]]&lt;br /&gt;
* [[Декомпозиция Эдмондса-Галлаи]]&lt;br /&gt;
* [[Задача об устойчивом паросочетании]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Совершенное паросочетание в кубическом графе]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Задача о максимальном потоке ==&lt;br /&gt;
* [[Определение сети, потока]]&lt;br /&gt;
* [[Разрез, лемма о потоке через разрез]]&lt;br /&gt;
* [[Дополняющая сеть, дополняющий путь]]&lt;br /&gt;
* [[Сложение и разность потоков]]&lt;br /&gt;
* [[Теорема Форда-Фалкерсона]]&lt;br /&gt;
* [[Алгоритм Форда-Фалкерсона, реализация с помощью поиска в глубину]]&lt;br /&gt;
* [[Алоритм Эдмондса-Карпа]]&lt;br /&gt;
* [[Алгоритм масштабирования потока]]&lt;br /&gt;
* [[Блокирующий поток]]&lt;br /&gt;
* [[Схема алгоритма Диница]]&lt;br /&gt;
* [[Теоремы Карзанова о числе итераций алгоритма Диница в сети с целочисленными пропускными способностями]]&lt;br /&gt;
* [[Алгоритм Голдберга-Тарьяна]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм поиска блокирующего потока в ациклической сети]]&lt;br /&gt;
* [[Метод проталкивания предпотока]]&lt;br /&gt;
* [[Алгоритм &amp;quot;поднять-в-начало&amp;quot;]]&lt;br /&gt;
* [[Теорема о декомпозиции]]&lt;br /&gt;
* [[Теорема о декомпозиционном барьере]]&lt;br /&gt;
* [[Циркуляция потока]]&lt;br /&gt;
* [[Алгоритм Каргера для нахождения минимального разреза]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Задача о потоке минимальной стоимости ==&lt;br /&gt;
* [[Поток минимальной стоимости]]&lt;br /&gt;
* [[Теорема Форда-Фалкерсона о потоке минимальной стоимости]]&lt;br /&gt;
* [[Лемма об эквивалентности свойства потока быть минимальной стоимости и отсутствии отрицательных циклов в остаточной сети]]&lt;br /&gt;
* [[Поиск потока минимальной стоимости методом дополнения вдоль путей минимальной стоимости]]&lt;br /&gt;
* [[Использование потенциалов Джонсона при поиске потока минимальной стоимости]]&lt;br /&gt;
* [[Сведение задачи о назначениях к задаче о потоке минимальной стоимости]]&lt;br /&gt;
* [[Венгерский алгоритм решения задачи о назначениях]]&lt;br /&gt;
&lt;br /&gt;
= Четвертый семестр =&lt;br /&gt;
&lt;br /&gt;
== Основные определения. Простые комбинаторные свойства слов ==&lt;br /&gt;
* [[Основные определения, связанные со строками]]&lt;br /&gt;
* [[Период и бордер, их связь]]&lt;br /&gt;
* [[Слово Фибоначчи]]&lt;br /&gt;
* [[Слово Туэ-Морса]]&lt;br /&gt;
* [[Декомпозиция Линдона]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм Ландау-Шмидта]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм Крочемора]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм Мейна-Лоренца]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм Манакера]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [[Поиск подстроки в строке]] ==&lt;br /&gt;
=== Точный поиск ===&lt;br /&gt;
* [[Наивный алгоритм поиска подстроки в строке]]&lt;br /&gt;
* [[Поиск подстроки в строке с использованием хеширования. Алгоритм Рабина-Карпа]]&lt;br /&gt;
* [[Поиск наибольшей общей подстроки двух строк с использованием хеширования]]&lt;br /&gt;
* [[Префикс-функция]]&lt;br /&gt;
* [[Алгоритм Кнута-Морриса-Пратта]]&lt;br /&gt;
* [[Автомат Кнута-Морриса-Пратта]]&lt;br /&gt;
* [[Z-функция]]&lt;br /&gt;
* [[Бор]]&lt;br /&gt;
* [[Алгоритм Ахо-Корасик]]&lt;br /&gt;
* [[Суффиксный автомат]]&lt;br /&gt;
* [[Алгоритм Бойера-Мура]]&lt;br /&gt;
* [[Алгоритм Апостолико-Крочемора]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм Колусси]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм Райта]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм Shift-And]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Двусторонний алгоритм]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Турбо-алгоритм Бойера-Мура]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Нечёткий поиск ===&lt;br /&gt;
* [[Алгоритм Ландау-Вишкина (k несовпадений)]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм Ландау-Вишкина (k различий)]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Суффиксное дерево ==&lt;br /&gt;
* [[Суффиксный бор]]&lt;br /&gt;
* [[Сжатое суффиксное дерево]]&lt;br /&gt;
* [[Алгоритм Укконена]]&lt;br /&gt;
* [[Алгоритм МакКрейта]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм Фарача]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Суффиксный массив ==&lt;br /&gt;
* [[Суффиксный массив]]&lt;br /&gt;
* [[Построение суффиксного массива с помощью стандартных методов сортировки]]&lt;br /&gt;
* [[Алгоритм цифровой сортировки суффиксов циклической строки]]&lt;br /&gt;
* [[Алгоритм Касаи и др.]]&lt;br /&gt;
* [[Алгоритм Карккайнена-Сандерса]]&lt;br /&gt;
* [[Алгоритм поиска подстроки в строке с помощью суффиксного массива]]&lt;br /&gt;
* [[Количество подпалиндромов в строке]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Задача о наименьшем общем предке ==&lt;br /&gt;
* [[Сведение задачи LCA к задаче RMQ]]&lt;br /&gt;
* [[Сведение задачи RMQ к задаче LCA]]&lt;br /&gt;
* [[Метод двоичного подъема]]&lt;br /&gt;
* [[Решение RMQ с помощью разреженной таблицы]]&lt;br /&gt;
* [[Алгоритм Фарака-Колтона и Бендера]] (решение +/-1 RMQ с помощью метода четырех русских)&lt;br /&gt;
* [[Алгоритм Хьюи]]&lt;br /&gt;
* [[Heavy-light декомпозиция]]&lt;br /&gt;
* [[Алгоритм Шибера-Вишкина]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Алгоритм Тарьяна поиска LCA за O(1) в оффлайн]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Link-Cut Tree]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
* [[Rake-Compress деревья]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Матроиды ==&lt;br /&gt;
=== Основные факты теории матроидов ===&lt;br /&gt;
* [[Определение матроида]]&lt;br /&gt;
* [[Примеры матроидов]]&lt;br /&gt;
* [[Прямая сумма матроидов]]&lt;br /&gt;
* [[Теорема Радо-Эдмондса (жадный алгоритм)]]&lt;br /&gt;
* [[Теорема о базах]]&lt;br /&gt;
* [[Аксиоматизация матроида базами]]&lt;br /&gt;
* [[Теорема о циклах]]&lt;br /&gt;
* [[Аксиоматизация матроида циклами]]&lt;br /&gt;
* [[Ранговая функция, полумодулярность]]&lt;br /&gt;
* [[Аксиоматизация матроида рангами]]&lt;br /&gt;
* [[Двойственный матроид]]&lt;br /&gt;
* [[Оператор замыкания для матроидов]]&lt;br /&gt;
* [[Покрытия, закрытые множества]]&lt;br /&gt;
* [[Матроид Вамоса]]&amp;lt;tex&amp;gt;^\star&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Пересечение матроидов ===&lt;br /&gt;
* [[Пересечение матроидов, определение, примеры]]&lt;br /&gt;
* [[Граф замен]]&lt;br /&gt;
* [[Алгоритм построения базы в пересечении матроидов]]&lt;br /&gt;
&lt;br /&gt;
=== Объединение матроидов ===&lt;br /&gt;
* [[Объединение матроидов, проверка множества на независимость]]&lt;br /&gt;
* [[Объединение матроидов, доказательство того, что объединение является матроидом]]&lt;br /&gt;
* [[Алгоритм построения базы в объединении матроидов]]&lt;br /&gt;
&lt;br /&gt;
== Теория расписаний ==&lt;br /&gt;
=== Общая теория ===&lt;br /&gt;
* [[Классификация задач]]&lt;br /&gt;
* [[Методы решения задач теории расписаний]]&lt;br /&gt;
* [[Правило Лаулера]]&lt;br /&gt;
&lt;br /&gt;
=== Задачи с одним станком ===&lt;br /&gt;
* [[1sumu|&amp;lt;tex&amp;gt;1 \mid \mid \sum U_{i}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1sumwu|&amp;lt;tex&amp;gt; 1 \mid\mid \sum w_i U_i &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1ripi1sumwc|&amp;lt;tex&amp;gt;1 \mid r_{i}, p_i=1\mid \sum w_{i}C_{i}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1ridipi1|&amp;lt;tex&amp;gt;1 \mid r_{i}, d_{i}, p_{i} = 1 \mid -&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1ripipsumwu|&amp;lt;tex&amp;gt; 1 \mid r_i,p_i=p \mid \sum w_i U_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1outtreesumwc | &amp;lt;tex&amp;gt;1 \mid outtree \mid \sum w_i C_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1pi1sumwu|&amp;lt;tex&amp;gt;1 \mid p_{i} = 1 \mid \sum w_{i}U_{i}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1precpmtnrifmax|&amp;lt;tex&amp;gt;1 \mid prec, pmtn, r_i \mid f_{\max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1ripi1sumf|&amp;lt;tex&amp;gt;1 \mid r_i, p_i = 1 \mid \sum f_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[1precripi1Lmax|&amp;lt;tex&amp;gt;1 \mid prec; r_i; p_i = 1 \mid L_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=== Специальные случаи задач для двух станков ===&lt;br /&gt;
* [[P2precpi1Lmax|&amp;lt;tex&amp;gt;P2 \mid prec, p_i = 1 \mid L_{\max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[R2Cmax|&amp;lt;tex&amp;gt;R2 \mid \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[F2Cmax|&amp;lt;tex&amp;gt;F2 \mid \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[O2Cmax|&amp;lt;tex&amp;gt;O2 \mid \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[J2ni2Cmax|&amp;lt;tex&amp;gt;J2 \mid n_{i} \leqslant 2 \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[J2pij1Lmax| &amp;lt;tex&amp;gt;J2\mid p_{ij} = 1\mid L_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=== Задачи для произвольного числа станков ===&lt;br /&gt;
* [[Flow shop]]&lt;br /&gt;
* [[Fpij1sumwu|&amp;lt;tex&amp;gt;F \mid p_{ij} = 1 \mid \sum w_i U_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[PSumCi|&amp;lt;tex&amp;gt;P \mid \mid \sum C_{i}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Pintreepi1Lmax|&amp;lt;tex&amp;gt;P \mid intree, p_{i} = 1 \mid L_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[PpmtnriLmax|&amp;lt;tex&amp;gt;P \mid pmtn, r_i \mid L_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Ppi1sumwu|&amp;lt;tex&amp;gt;P \mid p_i=1 \mid \sum w_i U_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[QpmtnCmax|&amp;lt;tex&amp;gt;Q \mid pmtn \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[QpmtnSumCi|&amp;lt;tex&amp;gt; Q \mid pmtn \mid \sum C_i &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[QpmtnriLmax|&amp;lt;tex&amp;gt;Q \mid pmtn, r_{i} \mid L_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[QSumCi|&amp;lt;tex&amp;gt;Q\mid\mid\sum{C_i}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opi1sumu|&amp;lt;tex&amp;gt;O \mid p_{ij} = 1 \mid \sum U_i&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1di|&amp;lt;tex&amp;gt;O \mid p_{ij} = 1, d_i \mid - &amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Opij1sumwu|&amp;lt;tex&amp;gt; O \mid p_{i,j} = 1 \mid \sum w_{i} U_{i} &amp;lt;/tex&amp;gt;]]&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=1sumu&amp;diff=54203</id>
		<title>1sumu</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=1sumu&amp;diff=54203"/>
				<updated>2016-05-23T13:09:53Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: /* Алгоритм */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Постановка задачи==&lt;br /&gt;
Дан один станок и &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; работ, для которых заданы их времена выполнения на этом станке &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt; и дедлайны &amp;lt;tex&amp;gt;d_i&amp;lt;/tex&amp;gt;. Нужно успеть выполнить как можно больше работ.&lt;br /&gt;
==Алгоритм==&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;, упорядоченных по неубыванию дедлайнов.&lt;br /&gt;
Будем добавлять в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; работы в порядке неубывания значений &amp;lt;tex&amp;gt;d_j&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;d_1 \leqslant d_2 \leqslant \dots \leqslant d_n&amp;lt;/tex&amp;gt;;&lt;br /&gt;
    &amp;lt;tex&amp;gt;S \leftarrow \varnothing&amp;lt;/tex&amp;gt;;&lt;br /&gt;
    &amp;lt;tex&amp;gt;time \leftarrow 0&amp;lt;/tex&amp;gt;;&lt;br /&gt;
    &amp;lt;tex&amp;gt;FOR&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;i := 1\dots n&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;DO&amp;lt;/tex&amp;gt;&lt;br /&gt;
        &amp;lt;tex&amp;gt;S \leftarrow S \cup \{ i \}&amp;lt;/tex&amp;gt;;&lt;br /&gt;
        &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; &amp;lt;code&amp;gt;+=&amp;lt;/code&amp;gt; &amp;lt;tex&amp;gt;p_i&amp;lt;/tex&amp;gt;;&lt;br /&gt;
        &amp;lt;tex&amp;gt;IF&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;t &amp;gt; d_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
            находим в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; с наибольшим &amp;lt;tex&amp;gt;p_j&amp;lt;/tex&amp;gt;;&lt;br /&gt;
            &amp;lt;tex&amp;gt;S = S \setminus\{j\}&amp;lt;/tex&amp;gt;;&lt;br /&gt;
            &amp;lt;tex&amp;gt;time&amp;lt;/tex&amp;gt; &amp;lt;code&amp;gt;-=&amp;lt;/code&amp;gt; &amp;lt;tex&amp;gt;p_j&amp;lt;/tex&amp;gt;;&lt;br /&gt;
Алгоритм будет работать за &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Этот алгоритм строит оптимальное расписание.&lt;br /&gt;
|proof=&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;F&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; - первая работа, которая была удалена из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Докажем, что существует оптимальное расписание &amp;lt;tex&amp;gt;P = (S, T)&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;j \in F&amp;lt;/tex&amp;gt;. Обозначим через &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; ту работу, которая была последней добавлена в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;p_j = \max\limits_{i = 1 \dots k} p_i&amp;lt;/tex&amp;gt;. При этом в последовательности работ &amp;lt;tex&amp;gt;1, 2, \dots, j-1 j+1, dots, k&amp;lt;/tex&amp;gt; не будет ни одной невыполненной работы, поскольку в последовательности &amp;lt;tex&amp;gt;1, 2, \dots, k-1&amp;lt;/tex&amp;gt; все работы выполняются вовремя и &amp;lt;tex&amp;gt;p_k \leqslant p_j&amp;lt;/tex&amp;gt;. Заменим &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; и отсортируем все работы. &lt;br /&gt;
Теперь рассмотрим оптимальное расписание &amp;lt;tex&amp;gt;P' = (S', F')&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;j \in S'&amp;lt;/tex&amp;gt;. В нём существует последовательность &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;\pi(1), \dots, \pi(m), \dots, \pi(r), \pi(r+1), \dots, \pi(n)&amp;lt;/tex&amp;gt;, такая, что&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex&amp;gt;F' = \{\pi(r+1), \dots, \pi(n)\}&amp;lt;/tex&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex&amp;gt;d_{\pi(1)} \leqslant \dots \leqslant d_{\pi(r)}&amp;lt;/tex&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex&amp;gt;\{\pi(1), \dots, \pi(m)\} \subseteq \{1, \dots, k\}&amp;lt;/tex&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex&amp;gt;\{\pi(m+1), \dots, \pi(r)\} \subseteq \{k+1, \dots, n\}&amp;lt;/tex&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex&amp;gt;j \in \{\pi(1), \dots, \pi(m)\}&amp;lt;/tex&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Такое &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; всегда найдётся, т.к. &amp;lt;tex&amp;gt;d_1 \leqslant d_2 \leqslant \dots \leqslant d_n&amp;lt;/tex&amp;gt;, а последнее будет следовать из того, что &amp;lt;tex&amp;gt;j \in S' \cap \{1, \dots, k\}&amp;lt;/tex&amp;gt;. Из того, что &amp;lt;tex&amp;gt;\{\pi(1), \dots, \pi(m)\} \subseteq S'&amp;lt;/tex&amp;gt; следует, что выполнятся все работы из &amp;lt;tex&amp;gt;\{\pi(1), \dots, \pi(m)\}&amp;lt;/tex&amp;gt;. С другой стороны, при любом расписании не будет выполнена какая-то работа из &amp;lt;tex&amp;gt;\{1, \dots, k\}&amp;lt;/tex&amp;gt;. Поэтому &amp;lt;tex&amp;gt;\{\pi(1), \dots, \pi(m)\} \subset \{1, \dots, k\}&amp;lt;/tex&amp;gt;, при этом существует работа &amp;lt;tex&amp;gt;h \notin \{\pi(1), \dots, \pi(m)\}&amp;lt;/tex&amp;gt;. Удалим работу &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; из &amp;lt;tex&amp;gt;\{\pi(1), \dots, \pi(m)\}&amp;lt;/tex&amp;gt; и заменим на &amp;lt;tex&amp;gt;h&amp;lt;/tex&amp;gt;. Если отсортируем получившееся множество, то все работы в нём выполнятся, т.к. &amp;lt;tex&amp;gt;\{\pi(1), \dots, \pi(m)\} \cup \{h\} \cap \{j\} \subseteq \{1, \dots, k\} \setminus \{j\}&amp;lt;/tex&amp;gt;, а оно обладает таким свойством. Если добавим работы &amp;lt;tex&amp;gt;\pi(m+1), \dots, \pi(r)&amp;lt;/tex&amp;gt; к множеству &amp;lt;tex&amp;gt;\{\pi(1), \dots, \pi(m)\} \cup \{h\} \cap \{j\}&amp;lt;/tex&amp;gt; и отсортируем его по неубыванию дедлайнов, то все работы в нём выполнятся, т.к. из &amp;lt;tex&amp;gt;p_h \leqslant p_j&amp;lt;/tex&amp;gt; следует, что &lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\sum_{i=1}^{m} p_{\pi(i)} - p_j + p_h \leqslant \sum_{i=1}^{m} p_{\pi(i)}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, мы получили оптимальное расписание &amp;lt;tex&amp;gt;P = (S, F)&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;j \in F&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Теперь докажем теорему индукцией по числу работ. Очевидно, при &amp;lt;tex&amp;gt;n = 1&amp;lt;/tex&amp;gt; она выполняется. Предположим, что алгоритм верен для &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; работы. Пусть &amp;lt;tex&amp;gt;P = (S, T)&amp;lt;/tex&amp;gt; - расписание, построенное алгоритмом, а &amp;lt;tex&amp;gt;P' = (S', T')&amp;lt;/tex&amp;gt; - оптимальное расписание с &amp;lt;tex&amp;gt;j \in F'&amp;lt;/tex&amp;gt;. Тогда, по отимальности, &amp;lt;tex&amp;gt;|S| \leqslant |S'|&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Если применить алгоритм ко множеству &amp;lt;tex&amp;gt;\{1, \dots, j-1, j+1, \dots, n\}&amp;lt;/tex&amp;gt;, то получим оптимальное расписание для &amp;lt;tex&amp;gt;(S, F\setminus \{j\})&amp;lt;/tex&amp;gt;. Т.к. для задачи с меньшим числом станков им будет являться &amp;lt;tex&amp;gt;(S', F' \setminus \{j\})&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;|S'| \leqslant |S|&amp;lt;/tex&amp;gt;, и, следовательно, &amp;lt;tex&amp;gt;|S| = |S'|&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является оптимальным расписанием.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* Peter Brucker. «Scheduling Algorithms» {{---}} «Springer», 2006 г. {{---}} 86 стр. {{---}} ISBN 978-3-540-69515-8&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Теория расписаний]]&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%83%D1%80%D0%B1%D0%BE-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D0%BE%D0%B9%D0%B5%D1%80%D0%B0-%D0%9C%D1%83%D1%80%D0%B0&amp;diff=53586</id>
		<title>Турбо-алгоритм Бойера-Мура</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%83%D1%80%D0%B1%D0%BE-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D0%BE%D0%B9%D0%B5%D1%80%D0%B0-%D0%9C%D1%83%D1%80%D0%B0&amp;diff=53586"/>
				<updated>2016-05-03T17:10:32Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: /* Описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Турбо-алгоритм Бойера-Мура''' (англ. ''Turbo Boyer-Moore'')  является улучшением [[Алгоритм Бойера-Мура|алгоритма Бойера-Мура]]. Турбо-алгоритм, разработанный группой учёных во главе с М.Крочемором, предлагает другой подход к коротким алфавитам и заодно решает вторую проблему — квадратичную сложность в худшем случае.&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;u&amp;lt;/tex&amp;gt; — запомненный сегмент, а &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; — cуффикс, совпавший во время текущей попытки, такой что &amp;lt;tex&amp;gt;uzv&amp;lt;/tex&amp;gt; — суффикс &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;av&amp;lt;/tex&amp;gt; — суффикс &amp;lt;tex&amp;gt;x&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;p&amp;lt;/tex&amp;gt; в тексте, и суффикс &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; длины &amp;lt;tex&amp;gt;|uzv|&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;|u| - |v|&amp;lt;/tex&amp;gt;  (его мы и называем турбо-сдвигом).[[Файл:Tbm1.png|600px|center]]&lt;br /&gt;
&lt;br /&gt;
===Применение турбо-сдвига в случае |v| &amp;lt; |u|===&lt;br /&gt;
При &amp;lt;tex&amp;gt;|v| &amp;lt; |u|&amp;lt;/tex&amp;gt;, если длина сдвига плохого символа больше, чем длина сдвига хорошего суффикса и длины турбо-сдвига, то длина фактического сдвига должна быть больше или равна &amp;lt;tex&amp;gt;|u| + 1&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;|u| +1&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;v&amp;lt;/tex&amp;gt;, в этом случае длина фактического сдвига должна быть по крайней мере равен &amp;lt;tex&amp;gt;|u| +1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Tbm2.png|600px|center]]&lt;br /&gt;
Нельзя совместить символы &amp;lt;tex&amp;gt;c \neq d&amp;lt;/tex&amp;gt; с одним и тем же символом &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Описание алгоритма===&lt;br /&gt;
В [[Алгоритм Бойера-Мура|алгоритм Бойера-Мура]] дополнительно добавится запоминание длины &amp;lt;tex&amp;gt;|u|&amp;lt;/tex&amp;gt; сегмента текста, который соответствует суффиксу шаблона во время последней попытки, который мы не будем лишний раз рассматривать при сравнении суффиксов двух подстрок, а также запоминании размера сдвига &amp;lt;tex&amp;gt;shift&amp;lt;/tex&amp;gt;, который мы совершили. Вычислять его будем следующим образом: &lt;br /&gt;
* Если текущем шаге у нас подстрока совпала с шаблоном &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;shift = bmGs[0]&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;bmGs[0]&amp;lt;/tex&amp;gt; равен периоду шаблона &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;), &amp;lt;tex&amp;gt;|u| = m - shift&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Иначе возможны два случая:&lt;br /&gt;
** Если сдвиг хорошего суффикса не меньше турбо-сдвига и сдвига плохого символа, тогда &amp;lt;tex&amp;gt;shift = bmGs[j+1]&amp;lt;/tex&amp;gt;,  &amp;lt;tex&amp;gt;|u| = min(m - shift, |v|)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; {{---}} текущая подстрока.&lt;br /&gt;
** В противном случае,  &amp;lt;tex&amp;gt;|u| = 0&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;shift = max(turboShift, bCShift)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;turboShift&amp;lt;/tex&amp;gt; {{---}} длина турбо-сдвига, &amp;lt;tex&amp;gt;bCShift&amp;lt;/tex&amp;gt; {{---}} длина сдвига плохого символа. Если турбо-сдвиг меньше сдвига плохого символа, то &amp;lt;tex&amp;gt;shift&amp;lt;/tex&amp;gt; должен быть не больше &amp;lt;tex&amp;gt;|u_0| + 1&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;u_0&amp;lt;/tex&amp;gt; {{---}} сегмент текста, рассматриваемый на прошлом шаге.&lt;br /&gt;
&lt;br /&gt;
==Псевдокод==&lt;br /&gt;
Стадия препроцессинга совпадает со стадией препроцессинга в [[Алгоритм Бойера-Мура|алгоритме Бойера-Мура]], функция вычислений сдвигов плохих символов и функция вычисления хороших суффиксов не меняются, меняется только сам алгоритм, в него добавляется обработка турбо-сдвигов.&lt;br /&gt;
 '''function''' TBM('''char'''[] x, '''char'''[] y, '''int''' n, '''int''' m): '''List&amp;lt;int&amp;gt;'''&lt;br /&gt;
    '''int''' i = 0&lt;br /&gt;
    '''int''' u = 0&lt;br /&gt;
    '''int''' shift = m&lt;br /&gt;
    '''List&amp;lt;int&amp;gt;''' answer;&lt;br /&gt;
 &lt;br /&gt;
    '''if''' (m == 0)&lt;br /&gt;
         '''return'''&lt;br /&gt;
         &lt;br /&gt;
    &amp;lt;font color=green&amp;gt;//Предварительные вычисления&amp;lt;/font&amp;gt;&lt;br /&gt;
    '''int''' bmBc[] = preBmBc(x, m)&lt;br /&gt;
    '''int''' bmGs[] = preBmGs(x, m)&lt;br /&gt;
 &lt;br /&gt;
    '''while''' (i &amp;lt;= n - m) &lt;br /&gt;
        '''int''' j = m - 1&lt;br /&gt;
        '''while''' (j &amp;gt;= 0 '''and''' x[j] == y[i + j])&lt;br /&gt;
            --j&lt;br /&gt;
            '''if''' (u != 0 '''and''' j == m - 1 - shift) &lt;br /&gt;
                j -= u&lt;br /&gt;
        '''if''' (j &amp;lt; 0) &lt;br /&gt;
            answer.add(i)&lt;br /&gt;
            shift = bmGs[0]&lt;br /&gt;
            u = m - shift&lt;br /&gt;
        '''else''' &lt;br /&gt;
            '''int''' v = m - 1 - j&lt;br /&gt;
            '''int''' turboShift = u - v&lt;br /&gt;
            '''int''' bCShift = bmBc[y[i + j]] - m + j + 1&lt;br /&gt;
            shift = max(turboShift, bCShift, bmGs[j + 1])&lt;br /&gt;
            '''if''' (shift == bmGs[j + 1])&lt;br /&gt;
                u = min((m - shift), v)&lt;br /&gt;
            '''else''' &lt;br /&gt;
                '''if''' (turboShift &amp;lt; bcShift) &lt;br /&gt;
                    shift = min(shift, (u + 1))&lt;br /&gt;
                u = 0&lt;br /&gt;
        i += shift&lt;br /&gt;
    '''return''' answer&lt;br /&gt;
&lt;br /&gt;
==Асимптотика==&lt;br /&gt;
{{Утверждение|statement= Фаза препроцессинга требует &amp;lt;tex&amp;gt;O(m + \sigma)&amp;lt;/tex&amp;gt; времени и памяти, где &amp;lt;tex&amp;gt;\sigma&amp;lt;/tex&amp;gt; {{---}} размер алфавита, &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; {{---}} длина шаблона. &lt;br /&gt;
|proof= Стадия препроцессинга совпадает со стадией препроцессинга в [[Алгоритм Бойера-Мура|алгоритме Бойера-Мура]], поэтому рассмотрим только стадию поиска.}}&lt;br /&gt;
{{Утверждение|statement= Фаза поиска требует &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; времени, где &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} длина строки, в которой выполняется поиск.&lt;br /&gt;
}}&lt;br /&gt;
{{Утверждение|statement= В худшем случае поиск требует &amp;lt;tex&amp;gt;O(2n)&amp;lt;/tex&amp;gt; сравнений.&lt;br /&gt;
|proof= Так как мы запоминаем последний просмотренный сегмент текста, совпадающий с суффиксом шаблона, это позволяет нам пропускать его при нахождении очередного (нам незачем второй раз просматривать сегмент, про который известно, что он совпадает), что уменьшет число сравнений и хождений по строке. Докажем, что число сравнений после такой оптимизаций будет &amp;lt;tex&amp;gt;O(2n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Разобьём поиск на шаги, каждый из которых будет состоять из двух операций: сканирования и сдвига. На шаге &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; мы будем называть &amp;lt;tex&amp;gt;suf_k&amp;lt;/tex&amp;gt; длину суффикса шаблона, что совпадает с текстом, перед суффиксом шаблона будет символ, который не совпадает с соответствующим символом в тексте (в случае когда &amp;lt;tex&amp;gt;suf_k&amp;lt;/tex&amp;gt; не соответствует длине шаблона). Мы также будем называть &amp;lt;tex&amp;gt;shift_k&amp;lt;/tex&amp;gt; длину сдвига, сделанного на шаге &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим три типа шагов в зависимости от характера сканирования и сдвига. Мы говорим, что сдвиг на шаге &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; короткий, если &amp;lt;tex&amp;gt;2shift_k &amp;lt; suf_k + 1&amp;lt;/tex&amp;gt;. Тогда эти три типа будут: &lt;br /&gt;
# Шаг с последующим шагом с прыжком.&lt;br /&gt;
# Шаг с длинным сдвигом, без последующего шага с прыжком.&lt;br /&gt;
# Шаг с коротким сдвигом, без последующего шага с прыжком.&lt;br /&gt;
Идея доказательства состоит в [[Амортизационный_анализ|амортизации]] стоимости сравнения со сдвигами. Определим стоимость шага &amp;lt;tex&amp;gt;cost_k&amp;lt;/tex&amp;gt; следующим образом:&lt;br /&gt;
* Если шаг &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; имеет тип (1), &amp;lt;tex&amp;gt;cost_k = 1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Если шаг &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; имеет тип (2) или (3), стоимость &amp;lt;tex&amp;gt;cost_k = suf_k + 1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Общее количество сравнений, выполняемых алгоритмом {{---}} сумма стоимостей шагов. Мы хотим доказать, что &amp;lt;tex&amp;gt; \sum cost &amp;lt; 2 \sum shifts&amp;lt;/tex&amp;gt;. Во второй &amp;lt;tex&amp;gt; \sum &amp;lt;/tex&amp;gt; длину последнего сдвига заменим &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;.&lt;br /&gt;
В случае шага типа (1), стоимость соответствует единственному сравнению несовпадающих символов. Другие сравнения, проведенные в течение того же шага, являются&lt;br /&gt;
стоимостью последующих шагов.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим каждый тип шага:&lt;br /&gt;
# &amp;lt;tex&amp;gt;cost_k = 1&amp;lt;/tex&amp;gt; очевидным образом меньше, чем &amp;lt;tex&amp;gt;2shift_k&amp;lt;/tex&amp;gt;, так как &amp;lt;tex&amp;gt;shift_k &amp;gt; 0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# &amp;lt;tex&amp;gt;cost_k = suf_k + 1 \leqslant 2 shift_k&amp;lt;/tex&amp;gt;, по определению длинных сдвигов.&lt;br /&gt;
# Так как в этой ситуации мы имеем &amp;lt;tex&amp;gt;shift_k &amp;lt; suf_k&amp;lt;/tex&amp;gt;, единственный возможный вариант, это когда обычный сдвиг применяется на шаге &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;. Тогда мы должны это запомнить. На следующем шаге, &amp;lt;tex&amp;gt;k + 1&amp;lt;/tex&amp;gt;, мы что-то запомнили, что приводит к возможному турбо-сдвигу. Ситуация на шаге &amp;lt;tex&amp;gt;k + 1&amp;lt;/tex&amp;gt; {{---}} основная ситуация, когда турбо-сдвиг возможен. Прежде чем продолжить доказательство, мы сначала рассмотрим два случая и установим неравенства (по стоимости шага &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;), которые используем позже.&lt;br /&gt;
#* Случай (а): &amp;lt;tex&amp;gt;suf_k + shift_k \leqslant |p|&amp;lt;/tex&amp;gt;. По определению турбо-сдвига, мы имеем &amp;lt;tex&amp;gt;suf_k - suf_{k+1} &amp;lt; shift_{k + 1}&amp;lt;/tex&amp;gt;. Таким образом, &amp;lt;tex&amp;gt;cost_k = sufk + 1 \leqslant suf_{k+1} + shift_{k+1} + 1 \leqslant shift_k + shift_{k + 1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
#* Случай (б): &amp;lt;tex&amp;gt;suf_k + shift_k &amp;gt; |p|&amp;lt;/tex&amp;gt;. По определению турбо-сдвига, мы имеем &amp;lt;tex&amp;gt;suf_{k+1} + shift_k + shift_{k + 1} \geqslant m&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;cost_k \leqslant m \leqslant 2shift_k - 1 + shift_{k + 1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
: Можно считать, что на шаге &amp;lt;tex&amp;gt;k + 1&amp;lt;/tex&amp;gt; случай (б) имеет место, потому что это дает нам верхнюю границу &amp;lt;tex&amp;gt;cost_k&amp;lt;/tex&amp;gt; (это верно, если &amp;lt;tex&amp;gt;shift_k \geqslant 2&amp;lt;/tex&amp;gt;, случай &amp;lt;tex&amp;gt;shift_k = 1&amp;lt;/tex&amp;gt; можно обрабатывать напрямую). Если шаг &amp;lt;tex&amp;gt;k + 1&amp;lt;/tex&amp;gt; типа (1), то &amp;lt;tex&amp;gt;cost_{k + 1} = 1&amp;lt;/tex&amp;gt;, а затем &amp;lt;tex&amp;gt;cost_k + cost_{k+1} \leqslant 2shift_k + shift_{k+1}&amp;lt;/tex&amp;gt;, что даже лучше, чем ожидалось. Если на шаге &amp;lt;tex&amp;gt;k + 1&amp;lt;/tex&amp;gt; мы имеем &amp;lt;tex&amp;gt;suf_{k + 1} \leqslant shift_{k + 1}&amp;lt;/tex&amp;gt;, то мы получим то, что ожидалось: &amp;lt;tex&amp;gt;cost_k + cost_{k + 1} \leqslant 2shift_k + 2shift_{k + 1}&amp;lt;/tex&amp;gt;. Последняя ситуация для рассмотрения, когда на шаге &amp;lt;tex&amp;gt;k + 1&amp;lt;/tex&amp;gt; мы имеем &amp;lt;tex&amp;gt;suf_{k + 1} &amp;gt; shift_{k + 1}&amp;lt;/tex&amp;gt;. Это означает, что, как уже упоминалось ранее, обычный сдвиг применяется на шаге &amp;lt;tex&amp;gt;k + 1&amp;lt;/tex&amp;gt;. Таким образом, приведенный выше анализ также применяется на шаге &amp;lt;tex&amp;gt;k + 1&amp;lt;/tex&amp;gt;, и, так как только случай (а) может произойти, мы получаем &amp;lt;tex&amp;gt;cost_{k + 1} \leqslant shift_{k + 1} + shift_{k + 2}&amp;lt;/tex&amp;gt;. Мы, наконец, получаем &amp;lt;tex&amp;gt;cost_k + cost_{k + 1} \leqslant 2shift_k + 2shift_{k + 1} + shift_{k + 2}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Покажем правильность шагов по индукции: если все шаги &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;k + j&amp;lt;/tex&amp;gt; таковы, что &amp;lt;tex&amp;gt;suf_k &amp;gt; shift_k,... , suf_{k + j} &amp;gt; shift_{k + j}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;cost_k + ... + cost_{k + j} \leqslant 2shift_k + ... + 2shift_{k + j} + shift_{k + j + 1}&amp;lt;/tex&amp;gt;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;k'&amp;lt;/tex&amp;gt; первый этап после этапа &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; такой, что &amp;lt;tex&amp;gt;suf_{k'} \leqslant shift_{k'}&amp;lt;/tex&amp;gt;. Целое число &amp;lt;tex&amp;gt;k'&amp;lt;/tex&amp;gt; существует потому, что иначе получим бесконечную последовательность сдвигов с уменьшающейся длиной. После этого мы получим &amp;lt;tex&amp;gt;cost_k + ... + cost_{k'} \leqslant 2shift_k + ... + 2shift_{k'}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Это показывает нам, что &amp;lt;tex&amp;gt; \sum cost_k \leqslant 2 \sum shift_k&amp;lt;/tex&amp;gt;, что и требовалось.}}&lt;br /&gt;
&lt;br /&gt;
==Пример работы==&lt;br /&gt;
Пусть нам дана строка &amp;lt;tex&amp;gt;y = GCATCGCAGAGAGTATACAGTACG&amp;lt;/tex&amp;gt; и образец &amp;lt;tex&amp;gt;x=GCAGAGAG&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Построим массив &amp;lt;tex&amp;gt;bmBc&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
[[Файл:RaitaPre.png|250px]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим шаги алгоритма:&lt;br /&gt;
&lt;br /&gt;
{| class = &amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Изображение !! &amp;lt;tex&amp;gt;(j, bmBc[y[j]])&amp;lt;/tex&amp;gt; !! Описание&lt;br /&gt;
|-align=&amp;quot;center&amp;quot;&lt;br /&gt;
|[[Файл:Raita1.png|550px]]&lt;br /&gt;
|&amp;lt;tex&amp;gt;(7, 1)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|Делаем сравнение последних символов, оно неудачно, сдвигаемся на &amp;lt;tex&amp;gt;bmGs[7] = bmBc[A]-8+8 = 1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|-align=&amp;quot;center&amp;quot;&lt;br /&gt;
|[[Файл:Tbme2.PNG|550px]]&lt;br /&gt;
|&amp;lt;tex&amp;gt;(8, 2)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|Последние два символа совпали, сдвигаемся на &amp;lt;tex&amp;gt;bmGs[5] = bmBc[C] - 8 + 6 = 4&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|-align=&amp;quot;center&amp;quot;&lt;br /&gt;
|[[Файл:Tbme3.PNG|550px]]&lt;br /&gt;
|&amp;lt;tex&amp;gt;(12, 2)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|Все символы совпали, Продолжим работу (для примера, в обычном варианте на этом этапе мы можем выйти, если требуется найти только одно вхождение) и сдвинемся на &amp;lt;tex&amp;gt;bmGs[0] = 7&amp;lt;/tex&amp;gt;. &lt;br /&gt;
|-align=&amp;quot;center&amp;quot;&lt;br /&gt;
|[[Файл:Tbme4.PNG|550px]]&lt;br /&gt;
|&amp;lt;tex&amp;gt;(19, 2)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|Последние два символа совпали, сдвигаемся на &amp;lt;tex&amp;gt;bmGs[5] = bmBc[C] - 8 + 6 = 4&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|-align=&amp;quot;center&amp;quot;&lt;br /&gt;
|[[Файл:Tbme5.PNG|550px]]&lt;br /&gt;
|&amp;lt;tex&amp;gt;(23, 1)&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;m = 8&amp;lt;/tex&amp;gt; в образце длиной &amp;lt;tex&amp;gt;n = 24&amp;lt;/tex&amp;gt; нам понадобилось &amp;lt;tex&amp;gt;15&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;
* [[wikipedia:ru:Алгоритм_Бойера_—_Мура|Википедия {{---}} Алгоритм Бойера-Мура]]&lt;br /&gt;
* [[wikipedia:Boyer–Moore_string_search_algorithm|Wikipedia {{---}} Boyer–Moore string search algorithm]]&lt;br /&gt;
* [http://www-igm.univ-mlv.fr/~lecroq/string/node15.html#SECTION00150 Turbo Boyer-Moore algorithm]&lt;br /&gt;
* [http://algolist.manual.ru/search/esearch/turbo_bm.php Турбо Боуер-Мур]&lt;br /&gt;
* [http://igm.univ-mlv.fr/~mac/Articles-PDF/CCGJLPR94algo-speedup.pdf Speeding Up Two String-Matching Algorithms]&lt;br /&gt;
&lt;br /&gt;
[[Категория:Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория:Поиск подстроки в строке]]&lt;br /&gt;
[[Категория:Точный поиск]]&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%83%D1%80%D0%B1%D0%BE-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D0%BE%D0%B9%D0%B5%D1%80%D0%B0-%D0%9C%D1%83%D1%80%D0%B0&amp;diff=53585</id>
		<title>Турбо-алгоритм Бойера-Мура</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%83%D1%80%D0%B1%D0%BE-%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D0%BE%D0%B9%D0%B5%D1%80%D0%B0-%D0%9C%D1%83%D1%80%D0%B0&amp;diff=53585"/>
				<updated>2016-05-03T17:05:48Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: /* Асимптотика */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Турбо-алгоритм Бойера-Мура''' (англ. ''Turbo Boyer-Moore'')  является улучшением [[Алгоритм Бойера-Мура|алгоритма Бойера-Мура]]. Турбо-алгоритм, разработанный группой учёных во главе с М.Крочемором, предлагает другой подход к коротким алфавитам и заодно решает вторую проблему — квадратичную сложность в худшем случае.&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;u&amp;lt;/tex&amp;gt; — запомненный сегмент, а &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; — cуффикс, совпавший во время текущей попытки, такой что &amp;lt;tex&amp;gt;uzv&amp;lt;/tex&amp;gt; — суффикс &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;av&amp;lt;/tex&amp;gt; — суффикс &amp;lt;tex&amp;gt;x&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;p&amp;lt;/tex&amp;gt; в тексте, и суффикс &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; длины &amp;lt;tex&amp;gt;|uzv|&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;|u| - |v|&amp;lt;/tex&amp;gt;  (его мы и называем турбо-сдвигом).[[Файл:Tbm1.png|600px|center]]&lt;br /&gt;
&lt;br /&gt;
===Применение турбо-сдвига в случае |v| &amp;lt; |u|===&lt;br /&gt;
При &amp;lt;tex&amp;gt;|v| &amp;lt; |u|&amp;lt;/tex&amp;gt;, если длина сдвига плохого символа больше, чем длина сдвига хорошего суффикса и длины турбо-сдвига, то длина фактического сдвига должна быть больше или равна &amp;lt;tex&amp;gt;|u| + 1&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;|u| +1&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;v&amp;lt;/tex&amp;gt;, в этом случае длина фактического сдвига должна быть по крайней мере равен &amp;lt;tex&amp;gt;|u| +1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Tbm2.png|600px|center]]&lt;br /&gt;
Нельзя совместить символы &amp;lt;tex&amp;gt;c \neq d&amp;lt;/tex&amp;gt; с одним и тем же символом &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Описание алгоритма===&lt;br /&gt;
В [[Алгоритм Бойера-Мура|алгоритм Бойера-Мура]] дополнительно добавится запоминание длины &amp;lt;tex&amp;gt;|u|&amp;lt;/tex&amp;gt; сегмента текста, который соответствует суффиксу шаблона во время последней попытки, который мы не будем лишний раз рассматривать при сравнении суффиксов двух подстрок, а также запоминании размера сдвига &amp;lt;tex&amp;gt;shift&amp;lt;/tex&amp;gt;, который мы совершили. Вычислять его будем следующим образом: &lt;br /&gt;
* Если текущем шаге у нас подстрока совпала с шаблоном &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;shift = bmGs[0]&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;bmGs[0]&amp;lt;/tex&amp;gt; равен периоду шаблона &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;), &amp;lt;tex&amp;gt;|u| = m - shift&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Иначе возможны два случая:&lt;br /&gt;
** Если сдвиг хорошего суффикса не меньше турбо-сдвига и сдвига плохого символа, тогда &amp;lt;tex&amp;gt;shift = bmGs[j+1]&amp;lt;/tex&amp;gt;,  &amp;lt;tex&amp;gt;|u| = min(m - shift, |v|)&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; текущая подстрока).&lt;br /&gt;
** В противном случае,  &amp;lt;tex&amp;gt;|u| = 0)&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;shift = max(turboShift, bCShift)&amp;lt;/tex&amp;gt;(&amp;lt;tex&amp;gt;turboShift&amp;lt;/tex&amp;gt; длина турбо-сдвига, &amp;lt;tex&amp;gt;bCShift&amp;lt;/tex&amp;gt; длина сдвига плохого символа), если турбо-сдвиг меньше сдвига плохого символа, то &amp;lt;tex&amp;gt;shift&amp;lt;/tex&amp;gt; должен быть не больше &amp;lt;tex&amp;gt;|u_0| + 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;u_0&amp;lt;/tex&amp;gt; сегмент текста, рассматриваемый на прошлом шаге).&lt;br /&gt;
&lt;br /&gt;
==Псевдокод==&lt;br /&gt;
Стадия препроцессинга совпадает со стадией препроцессинга в [[Алгоритм Бойера-Мура|алгоритме Бойера-Мура]], функция вычислений сдвигов плохих символов и функция вычисления хороших суффиксов не меняются, меняется только сам алгоритм, в него добавляется обработка турбо-сдвигов.&lt;br /&gt;
 '''function''' TBM('''char'''[] x, '''char'''[] y, '''int''' n, '''int''' m): '''List&amp;lt;int&amp;gt;'''&lt;br /&gt;
    '''int''' i = 0&lt;br /&gt;
    '''int''' u = 0&lt;br /&gt;
    '''int''' shift = m&lt;br /&gt;
    '''List&amp;lt;int&amp;gt;''' answer;&lt;br /&gt;
 &lt;br /&gt;
    '''if''' (m == 0)&lt;br /&gt;
         '''return'''&lt;br /&gt;
         &lt;br /&gt;
    &amp;lt;font color=green&amp;gt;//Предварительные вычисления&amp;lt;/font&amp;gt;&lt;br /&gt;
    '''int''' bmBc[] = preBmBc(x, m)&lt;br /&gt;
    '''int''' bmGs[] = preBmGs(x, m)&lt;br /&gt;
 &lt;br /&gt;
    '''while''' (i &amp;lt;= n - m) &lt;br /&gt;
        '''int''' j = m - 1&lt;br /&gt;
        '''while''' (j &amp;gt;= 0 '''and''' x[j] == y[i + j])&lt;br /&gt;
            --j&lt;br /&gt;
            '''if''' (u != 0 '''and''' j == m - 1 - shift) &lt;br /&gt;
                j -= u&lt;br /&gt;
        '''if''' (j &amp;lt; 0) &lt;br /&gt;
            answer.add(i)&lt;br /&gt;
            shift = bmGs[0]&lt;br /&gt;
            u = m - shift&lt;br /&gt;
        '''else''' &lt;br /&gt;
            '''int''' v = m - 1 - j&lt;br /&gt;
            '''int''' turboShift = u - v&lt;br /&gt;
            '''int''' bCShift = bmBc[y[i + j]] - m + j + 1&lt;br /&gt;
            shift = max(turboShift, bCShift, bmGs[j + 1])&lt;br /&gt;
            '''if''' (shift == bmGs[j + 1])&lt;br /&gt;
                u = min((m - shift), v)&lt;br /&gt;
            '''else''' &lt;br /&gt;
                '''if''' (turboShift &amp;lt; bcShift) &lt;br /&gt;
                    shift = min(shift, (u + 1))&lt;br /&gt;
                u = 0&lt;br /&gt;
        i += shift&lt;br /&gt;
    '''return''' answer&lt;br /&gt;
&lt;br /&gt;
==Асимптотика==&lt;br /&gt;
{{Утверждение|statement= Фаза препроцессинга требует &amp;lt;tex&amp;gt;O(m + \sigma)&amp;lt;/tex&amp;gt; времени и памяти, где &amp;lt;tex&amp;gt;\sigma&amp;lt;/tex&amp;gt; {{---}} размер алфавита, &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; {{---}} длина шаблона. &lt;br /&gt;
|proof= Стадия препроцессинга совпадает со стадией препроцессинга в [[Алгоритм Бойера-Мура|алгоритме Бойера-Мура]], поэтому рассмотрим только стадию поиска.}}&lt;br /&gt;
{{Утверждение|statement= Фаза поиска требует &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; времени, где &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} длина строки, в которой выполняется поиск.&lt;br /&gt;
}}&lt;br /&gt;
{{Утверждение|statement= В худшем случае поиск требует &amp;lt;tex&amp;gt;O(2n)&amp;lt;/tex&amp;gt; сравнений.&lt;br /&gt;
|proof= Так как мы запоминаем последний просмотренный сегмент текста, совпадающий с суффиксом шаблона, это позволяет нам пропускать его при нахождении очередного (нам незачем второй раз просматривать сегмент, про который известно, что он совпадает), что уменьшет число сравнений и хождений по строке. Докажем, что число сравнений после такой оптимизаций будет &amp;lt;tex&amp;gt;O(2n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Разобьём поиск на шаги, каждый из которых будет состоять из двух операций: сканирования и сдвига. На шаге &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; мы будем называть &amp;lt;tex&amp;gt;suf_k&amp;lt;/tex&amp;gt; длину суффикса шаблона, что совпадает с текстом, перед суффиксом шаблона будет символ, который не совпадает с соответствующим символом в тексте (в случае когда &amp;lt;tex&amp;gt;suf_k&amp;lt;/tex&amp;gt; не соответствует длине шаблона). Мы также будем называть &amp;lt;tex&amp;gt;shift_k&amp;lt;/tex&amp;gt; длину сдвига, сделанного на шаге &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим три типа шагов в зависимости от характера сканирования и сдвига. Мы говорим, что сдвиг на шаге &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; короткий, если &amp;lt;tex&amp;gt;2shift_k &amp;lt; suf_k + 1&amp;lt;/tex&amp;gt;. Тогда эти три типа будут: &lt;br /&gt;
# Шаг с последующим шагом с прыжком.&lt;br /&gt;
# Шаг с длинным сдвигом, без последующего шага с прыжком.&lt;br /&gt;
# Шаг с коротким сдвигом, без последующего шага с прыжком.&lt;br /&gt;
Идея доказательства состоит в [[Амортизационный_анализ|амортизации]] стоимости сравнения со сдвигами. Определим стоимость шага &amp;lt;tex&amp;gt;cost_k&amp;lt;/tex&amp;gt; следующим образом:&lt;br /&gt;
* Если шаг &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; имеет тип (1), &amp;lt;tex&amp;gt;cost_k = 1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Если шаг &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; имеет тип (2) или (3), стоимость &amp;lt;tex&amp;gt;cost_k = suf_k + 1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Общее количество сравнений, выполняемых алгоритмом {{---}} сумма стоимостей шагов. Мы хотим доказать, что &amp;lt;tex&amp;gt; \sum cost &amp;lt; 2 \sum shifts&amp;lt;/tex&amp;gt;. Во второй &amp;lt;tex&amp;gt; \sum &amp;lt;/tex&amp;gt; длину последнего сдвига заменим &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt;.&lt;br /&gt;
В случае шага типа (1), стоимость соответствует единственному сравнению несовпадающих символов. Другие сравнения, проведенные в течение того же шага, являются&lt;br /&gt;
стоимостью последующих шагов.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим каждый тип шага:&lt;br /&gt;
# &amp;lt;tex&amp;gt;cost_k = 1&amp;lt;/tex&amp;gt; очевидным образом меньше, чем &amp;lt;tex&amp;gt;2shift_k&amp;lt;/tex&amp;gt;, так как &amp;lt;tex&amp;gt;shift_k &amp;gt; 0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# &amp;lt;tex&amp;gt;cost_k = suf_k + 1 \leqslant 2 shift_k&amp;lt;/tex&amp;gt;, по определению длинных сдвигов.&lt;br /&gt;
# Так как в этой ситуации мы имеем &amp;lt;tex&amp;gt;shift_k &amp;lt; suf_k&amp;lt;/tex&amp;gt;, единственный возможный вариант, это когда обычный сдвиг применяется на шаге &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;. Тогда мы должны это запомнить. На следующем шаге, &amp;lt;tex&amp;gt;k + 1&amp;lt;/tex&amp;gt;, мы что-то запомнили, что приводит к возможному турбо-сдвигу. Ситуация на шаге &amp;lt;tex&amp;gt;k + 1&amp;lt;/tex&amp;gt; {{---}} основная ситуация, когда турбо-сдвиг возможен. Прежде чем продолжить доказательство, мы сначала рассмотрим два случая и установим неравенства (по стоимости шага &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;), которые используем позже.&lt;br /&gt;
#* Случай (а): &amp;lt;tex&amp;gt;suf_k + shift_k \leqslant |p|&amp;lt;/tex&amp;gt;. По определению турбо-сдвига, мы имеем &amp;lt;tex&amp;gt;suf_k - suf_{k+1} &amp;lt; shift_{k + 1}&amp;lt;/tex&amp;gt;. Таким образом, &amp;lt;tex&amp;gt;cost_k = sufk + 1 \leqslant suf_{k+1} + shift_{k+1} + 1 \leqslant shift_k + shift_{k + 1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
#* Случай (б): &amp;lt;tex&amp;gt;suf_k + shift_k &amp;gt; |p|&amp;lt;/tex&amp;gt;. По определению турбо-сдвига, мы имеем &amp;lt;tex&amp;gt;suf_{k+1} + shift_k + shift_{k + 1} \geqslant m&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;cost_k \leqslant m \leqslant 2shift_k - 1 + shift_{k + 1}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
: Можно считать, что на шаге &amp;lt;tex&amp;gt;k + 1&amp;lt;/tex&amp;gt; случай (б) имеет место, потому что это дает нам верхнюю границу &amp;lt;tex&amp;gt;cost_k&amp;lt;/tex&amp;gt; (это верно, если &amp;lt;tex&amp;gt;shift_k \geqslant 2&amp;lt;/tex&amp;gt;, случай &amp;lt;tex&amp;gt;shift_k = 1&amp;lt;/tex&amp;gt; можно обрабатывать напрямую). Если шаг &amp;lt;tex&amp;gt;k + 1&amp;lt;/tex&amp;gt; типа (1), то &amp;lt;tex&amp;gt;cost_{k + 1} = 1&amp;lt;/tex&amp;gt;, а затем &amp;lt;tex&amp;gt;cost_k + cost_{k+1} \leqslant 2shift_k + shift_{k+1}&amp;lt;/tex&amp;gt;, что даже лучше, чем ожидалось. Если на шаге &amp;lt;tex&amp;gt;k + 1&amp;lt;/tex&amp;gt; мы имеем &amp;lt;tex&amp;gt;suf_{k + 1} \leqslant shift_{k + 1}&amp;lt;/tex&amp;gt;, то мы получим то, что ожидалось: &amp;lt;tex&amp;gt;cost_k + cost_{k + 1} \leqslant 2shift_k + 2shift_{k + 1}&amp;lt;/tex&amp;gt;. Последняя ситуация для рассмотрения, когда на шаге &amp;lt;tex&amp;gt;k + 1&amp;lt;/tex&amp;gt; мы имеем &amp;lt;tex&amp;gt;suf_{k + 1} &amp;gt; shift_{k + 1}&amp;lt;/tex&amp;gt;. Это означает, что, как уже упоминалось ранее, обычный сдвиг применяется на шаге &amp;lt;tex&amp;gt;k + 1&amp;lt;/tex&amp;gt;. Таким образом, приведенный выше анализ также применяется на шаге &amp;lt;tex&amp;gt;k + 1&amp;lt;/tex&amp;gt;, и, так как только случай (а) может произойти, мы получаем &amp;lt;tex&amp;gt;cost_{k + 1} \leqslant shift_{k + 1} + shift_{k + 2}&amp;lt;/tex&amp;gt;. Мы, наконец, получаем &amp;lt;tex&amp;gt;cost_k + cost_{k + 1} \leqslant 2shift_k + 2shift_{k + 1} + shift_{k + 2}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Покажем правильность шагов по индукции: если все шаги &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;k + j&amp;lt;/tex&amp;gt; таковы, что &amp;lt;tex&amp;gt;suf_k &amp;gt; shift_k,... , suf_{k + j} &amp;gt; shift_{k + j}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;cost_k + ... + cost_{k + j} \leqslant 2shift_k + ... + 2shift_{k + j} + shift_{k + j + 1}&amp;lt;/tex&amp;gt;. &amp;lt;br /&amp;gt;&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;k'&amp;lt;/tex&amp;gt; первый этап после этапа &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; такой, что &amp;lt;tex&amp;gt;suf_{k'} \leqslant shift_{k'}&amp;lt;/tex&amp;gt;. Целое число &amp;lt;tex&amp;gt;k'&amp;lt;/tex&amp;gt; существует потому, что иначе получим бесконечную последовательность сдвигов с уменьшающейся длиной. После этого мы получим &amp;lt;tex&amp;gt;cost_k + ... + cost_{k'} \leqslant 2shift_k + ... + 2shift_{k'}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Это показывает нам, что &amp;lt;tex&amp;gt; \sum cost_k \leqslant 2 \sum shift_k&amp;lt;/tex&amp;gt;, что и требовалось.}}&lt;br /&gt;
&lt;br /&gt;
==Пример работы==&lt;br /&gt;
Пусть нам дана строка &amp;lt;tex&amp;gt;y = GCATCGCAGAGAGTATACAGTACG&amp;lt;/tex&amp;gt; и образец &amp;lt;tex&amp;gt;x=GCAGAGAG&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Построим массив &amp;lt;tex&amp;gt;bmBc&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
[[Файл:RaitaPre.png|250px]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим шаги алгоритма:&lt;br /&gt;
&lt;br /&gt;
{| class = &amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Изображение !! &amp;lt;tex&amp;gt;(j, bmBc[y[j]])&amp;lt;/tex&amp;gt; !! Описание&lt;br /&gt;
|-align=&amp;quot;center&amp;quot;&lt;br /&gt;
|[[Файл:Raita1.png|550px]]&lt;br /&gt;
|&amp;lt;tex&amp;gt;(7, 1)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|Делаем сравнение последних символов, оно неудачно, сдвигаемся на &amp;lt;tex&amp;gt;bmGs[7] = bmBc[A]-8+8 = 1&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|-align=&amp;quot;center&amp;quot;&lt;br /&gt;
|[[Файл:Tbme2.PNG|550px]]&lt;br /&gt;
|&amp;lt;tex&amp;gt;(8, 2)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|Последние два символа совпали, сдвигаемся на &amp;lt;tex&amp;gt;bmGs[5] = bmBc[C] - 8 + 6 = 4&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|-align=&amp;quot;center&amp;quot;&lt;br /&gt;
|[[Файл:Tbme3.PNG|550px]]&lt;br /&gt;
|&amp;lt;tex&amp;gt;(12, 2)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|Все символы совпали, Продолжим работу (для примера, в обычном варианте на этом этапе мы можем выйти, если требуется найти только одно вхождение) и сдвинемся на &amp;lt;tex&amp;gt;bmGs[0] = 7&amp;lt;/tex&amp;gt;. &lt;br /&gt;
|-align=&amp;quot;center&amp;quot;&lt;br /&gt;
|[[Файл:Tbme4.PNG|550px]]&lt;br /&gt;
|&amp;lt;tex&amp;gt;(19, 2)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|Последние два символа совпали, сдвигаемся на &amp;lt;tex&amp;gt;bmGs[5] = bmBc[C] - 8 + 6 = 4&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|-align=&amp;quot;center&amp;quot;&lt;br /&gt;
|[[Файл:Tbme5.PNG|550px]]&lt;br /&gt;
|&amp;lt;tex&amp;gt;(23, 1)&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;m = 8&amp;lt;/tex&amp;gt; в образце длиной &amp;lt;tex&amp;gt;n = 24&amp;lt;/tex&amp;gt; нам понадобилось &amp;lt;tex&amp;gt;15&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;
* [[wikipedia:ru:Алгоритм_Бойера_—_Мура|Википедия {{---}} Алгоритм Бойера-Мура]]&lt;br /&gt;
* [[wikipedia:Boyer–Moore_string_search_algorithm|Wikipedia {{---}} Boyer–Moore string search algorithm]]&lt;br /&gt;
* [http://www-igm.univ-mlv.fr/~lecroq/string/node15.html#SECTION00150 Turbo Boyer-Moore algorithm]&lt;br /&gt;
* [http://algolist.manual.ru/search/esearch/turbo_bm.php Турбо Боуер-Мур]&lt;br /&gt;
* [http://igm.univ-mlv.fr/~mac/Articles-PDF/CCGJLPR94algo-speedup.pdf Speeding Up Two String-Matching Algorithms]&lt;br /&gt;
&lt;br /&gt;
[[Категория:Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория:Поиск подстроки в строке]]&lt;br /&gt;
[[Категория:Точный поиск]]&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D0%BD%D1%82%D0%B5%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%BD%D1%8B%D0%B5_%D0%BF%D1%80%D0%BE%D1%82%D0%BE%D0%BA%D0%BE%D0%BB%D1%8B._%D0%9A%D0%BB%D0%B0%D1%81%D1%81_IP._%D0%9A%D0%BB%D0%B0%D1%81%D1%81_AM&amp;diff=53499</id>
		<title>Интерактивные протоколы. Класс IP. Класс AM</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%98%D0%BD%D1%82%D0%B5%D1%80%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%BD%D1%8B%D0%B5_%D0%BF%D1%80%D0%BE%D1%82%D0%BE%D0%BA%D0%BE%D0%BB%D1%8B._%D0%9A%D0%BB%D0%B0%D1%81%D1%81_IP._%D0%9A%D0%BB%D0%B0%D1%81%D1%81_AM&amp;diff=53499"/>
				<updated>2016-04-29T20:26:46Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Определения ==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
&amp;lt;b&amp;gt;Интерактивным протоколом&amp;lt;/b&amp;gt;, разрешающим язык &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;, называется абстрактная машина (см. рисунок), моделирующая вычисления как обмен сообщениями между двумя программами (&amp;lt;tex&amp;gt;\mathit{Prover}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathit{Verifier}&amp;lt;/tex&amp;gt;), такими, что&lt;br /&gt;
# &amp;lt;tex&amp;gt;\mathit{Prover}&amp;lt;/tex&amp;gt; заинтересован в том, чтобы &amp;lt;tex&amp;gt;\mathit{Verifier}&amp;lt;/tex&amp;gt; решил, что слово &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; принадлежит языку;&lt;br /&gt;
# &amp;lt;tex&amp;gt;\mathit{Prover}&amp;lt;/tex&amp;gt; не ограничен в вычислительной мощности;&lt;br /&gt;
# &amp;lt;tex&amp;gt;\mathit{Verifier}&amp;lt;/tex&amp;gt; заинтересован установить, действительно ли слово &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; принадлежит языку;&lt;br /&gt;
# &amp;lt;tex&amp;gt;\mathit{Verifier}&amp;lt;/tex&amp;gt; — [[Вероятностные вычисления. Вероятностная машина Тьюринга|вероятностная машина Тьюринга]];&lt;br /&gt;
# &amp;lt;tex&amp;gt;\mathit{Verifier}&amp;lt;/tex&amp;gt; ограничен полиномиальным временем работы.&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:IPS.png|250px|thumb|right|Схема интерактивного протокола.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathit{Verifier}&amp;lt;/tex&amp;gt;, обменивающийся сообщениями с &amp;lt;tex&amp;gt;\mathit{Prover}&amp;lt;/tex&amp;gt;, будем обозначать &amp;lt;tex&amp;gt;\mathit{Verifier^{Prover}}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Интерактивные протоколы делятся на два типа в зависимости от доступа &amp;lt;tex&amp;gt;\mathit{Prover}&amp;lt;/tex&amp;gt; к вероятностной ленте &amp;lt;tex&amp;gt;\mathit{Verifier}&amp;lt;/tex&amp;gt;:&lt;br /&gt;
# &amp;lt;b&amp;gt; public coins &amp;lt;/b&amp;gt; — &amp;lt;tex&amp;gt;\mathit{Prover}&amp;lt;/tex&amp;gt; может видеть вероятностную ленту &amp;lt;tex&amp;gt;\mathit{Verifier}&amp;lt;/tex&amp;gt;;&lt;br /&gt;
# &amp;lt;b&amp;gt; private coins &amp;lt;/b&amp;gt; — &amp;lt;tex&amp;gt;\mathit{Prover}&amp;lt;/tex&amp;gt; &amp;lt;b&amp;gt;не&amp;lt;/b&amp;gt; может видеть вероятностную ленту &amp;lt;tex&amp;gt;\mathit{Verifier}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{IP}[f] = \{L\bigm|\exists \langle \mathit{Verifier}, \mathit{Prover} \rangle : &amp;lt;/tex&amp;gt; &amp;lt;br/&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt;\mathit{Prover}&amp;lt;/tex&amp;gt; не имеет доступа к вероятностной ленте &amp;lt;tex&amp;gt;\mathit{Verifier}&amp;lt;/tex&amp;gt; (private coins);&lt;br /&gt;
# &amp;lt;tex&amp;gt; \forall x \in L \Rightarrow P(\mathit{Verifier^{Prover}}(x) = 1) \geqslant \frac{2}{3} &amp;lt;/tex&amp;gt;;&amp;lt;br/&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt; \forall x \notin L \Rightarrow P(\mathit{Verifier^{Prover}}(x) = 1) \leqslant \frac{1}{3} &amp;lt;/tex&amp;gt;;&amp;lt;br/&amp;gt;&lt;br /&gt;
# число раундов интерактивного протокола &amp;lt;tex&amp;gt; O(f(n)), n = |x|\}&amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = &amp;lt;tex&amp;gt;\mathrm{IP}=\bigcup\limits_{p(n) \in poly} \mathrm{IP} [p(n)] &amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Язык &amp;lt;tex&amp;gt;\mathrm{AM}&amp;lt;/tex&amp;gt; (&amp;lt;i&amp;gt;Arthur–Merlin games&amp;lt;/i&amp;gt;) отличается от &amp;lt;tex&amp;gt;\mathrm{IP}&amp;lt;/tex&amp;gt; лишь тем, что &amp;lt;tex&amp;gt;\mathit{Prover}&amp;lt;/tex&amp;gt; может видеть вероятностную ленту &amp;lt;tex&amp;gt;\mathit{Verifier}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{AM}[f] = \{L\bigm|\exists \langle \mathit{Verifier}, \mathit{Prover} \rangle : &amp;lt;/tex&amp;gt; &amp;lt;br/&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt;\mathit{Prover}&amp;lt;/tex&amp;gt; может читать вероятностную ленту &amp;lt;tex&amp;gt;\mathit{Verifier}&amp;lt;/tex&amp;gt; (public coins);&lt;br /&gt;
# &amp;lt;tex&amp;gt; \forall x \in L \Rightarrow P(\mathit{Verifier^{Prover}}(x) = 1) \geqslant \frac{2}{3} &amp;lt;/tex&amp;gt;;&amp;lt;br/&amp;gt;&lt;br /&gt;
# &amp;lt;tex&amp;gt; \forall x \notin L \Rightarrow P(\mathit{Verifier^{Prover}}(x) = 1) \leqslant \frac{1}{3} &amp;lt;/tex&amp;gt;;&amp;lt;br/&amp;gt;&lt;br /&gt;
# число раундов интерактивного протокола &amp;lt;tex&amp;gt; O(f(n)), n = |x|\} &amp;lt;/tex&amp;gt;.&amp;lt;br/&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition = &amp;lt;tex&amp;gt;\mathrm{AM}=\bigcup\limits_{p(n) \in poly} \mathrm{AM} [p(n)] &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; \forall x \in L \Rightarrow P(\mathit{Verifier^{Prover}}(x) = 1) = 1 &amp;lt;/tex&amp;gt;, то говорят, что он обладает свойством &amp;lt;b&amp;gt; completeness &amp;lt;/b&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
Если для интерактивного протокола выполняется &amp;lt;tex&amp;gt; \forall x \notin L \Rightarrow P(\mathit{Verifier^{Prover}}(x) = 1) = 0 &amp;lt;/tex&amp;gt;, то говорят, что он обладает свойством &amp;lt;b&amp;gt; soundness &amp;lt;/b&amp;gt;.&lt;br /&gt;
}} &lt;br /&gt;
Свойство completeness можно достичь, а soundness достичь нельзя.&lt;br /&gt;
&lt;br /&gt;
== Соотношения с другими классами теории сложности ==&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&amp;lt;tex&amp;gt;\mathrm{BPP} \subset \mathrm{IP}[0]&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathit{Verifier}&amp;lt;/tex&amp;gt; сам по себе является вероятностной машиной Тьюринга и поэтому может разрешить язык из &amp;lt;tex&amp;gt;\mathrm{BPP}&amp;lt;/tex&amp;gt; не прибегая к общению с &amp;lt;tex&amp;gt;\mathit{Prover}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&amp;lt;tex&amp;gt;\mathrm{NP} \subset \mathrm{IP}[1]&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
Для разрешения языка из &amp;lt;tex&amp;gt;\mathrm{NP}&amp;lt;/tex&amp;gt; будем использовать следующий протокол:&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathit{Verifier}&amp;lt;/tex&amp;gt; будет проверять на принадлежность слова &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; используя сертификат, который он запросит у &amp;lt;tex&amp;gt;\mathit{Prover}&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;\mathit{Prover}&amp;lt;/tex&amp;gt; не ограничен в вычислительной мощности, он может подобрать подходящий сертификат и именно его и сообщит, так как он заинтересован в том, чтобы &amp;lt;tex&amp;gt;\mathit{Verifier}&amp;lt;/tex&amp;gt; принял слово. Для этого требуется лишь один раунд интерактивного протокола.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Язык GNI ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{GNI}&amp;lt;/tex&amp;gt; расшифровывается как Graph Non Isomorphism. Это язык пар неизоморфных друг другу графов.&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{GNI}=\{ \langle G, H \rangle, &amp;lt;/tex&amp;gt; графы &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; не изоморфны &amp;lt;tex&amp;gt;\}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&amp;lt;tex&amp;gt;\mathrm{GNI} \in \mathrm{IP}[1]&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
Будем использовать следующий алгоритм для &amp;lt;tex&amp;gt;\mathit{Verifier}&amp;lt;/tex&amp;gt;:&lt;br /&gt;
# Возьмём случайное число &amp;lt;tex&amp;gt;i \in \{0, 1\}&amp;lt;/tex&amp;gt; и случайную перестановку &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt; с вероятностной ленты; &amp;lt;br/&amp;gt;&lt;br /&gt;
# Создадим новый граф, перемешав вершины графа c номером &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; перестановкой &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;; &amp;lt;br/&amp;gt;&lt;br /&gt;
# Перешлём &amp;lt;tex&amp;gt;\mathit{Prover}&amp;lt;/tex&amp;gt; полученный граф с просьбой определить, из какого из исходных графов он был получен; &amp;lt;br/&amp;gt;&lt;br /&gt;
# Получив ответ, сравним его с правильным ответом — числом &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;; &amp;lt;br/&amp;gt;&lt;br /&gt;
# Если полученный ответ не совпадёт с &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, то вернём &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;; &amp;lt;br/&amp;gt;&lt;br /&gt;
# Иначе повторим первые пять шагов ещё раз и перейдём к последнему шагу; &amp;lt;br/&amp;gt;&lt;br /&gt;
# Если мы ещё не вернули &amp;lt;tex&amp;gt;0&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{IP}[1]&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Во-первых, очевидно, что число раундов не превосходит двух. &amp;lt;br/&amp;gt;&lt;br /&gt;
Рассмотрим теперь случаи&lt;br /&gt;
* &amp;lt;tex&amp;gt; \langle G, H \rangle \in \mathrm{GNI}&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; неизоморфны и &amp;lt;tex&amp;gt;\mathit{Prover}&amp;lt;/tex&amp;gt; сможет определить какой граф был перемешан &amp;lt;tex&amp;gt;\mathit{Verifier}&amp;lt;/tex&amp;gt;. Таким образом, &amp;lt;tex&amp;gt;\mathit{Prover}&amp;lt;/tex&amp;gt; сможет два раза подряд вернуть правильный ответ и в итоге &amp;lt;tex&amp;gt;\mathit{Verifier}&amp;lt;/tex&amp;gt; вернёт 1.&lt;br /&gt;
* &amp;lt;tex&amp;gt; \langle G, H \rangle \notin \mathrm{GNI}&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; изоморфны и &amp;lt;tex&amp;gt;\mathit{Prover}&amp;lt;/tex&amp;gt; не сможет определить какой граф был перемешан &amp;lt;tex&amp;gt;\mathit{Verifier}&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;\mathit{Prover}&amp;lt;/tex&amp;gt; заинтересован в том, чтобы &amp;lt;tex&amp;gt;\mathit{Verifier}&amp;lt;/tex&amp;gt; принял слово, ему необходимо угадать правильный ответ (иначе &amp;lt;tex&amp;gt;\mathit{Verifier}&amp;lt;/tex&amp;gt; просто вернёт &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;). Вероятность того, что &amp;lt;tex&amp;gt;\mathit{Verifier}&amp;lt;/tex&amp;gt; примет слово &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, когда оно не принадлежит языку (то есть &amp;lt;tex&amp;gt;\mathit{Prover}&amp;lt;/tex&amp;gt; два раза подряд верно угадает номер графа), равна &amp;lt;tex&amp;gt;\frac{1}{4}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Таким образом, построенный протокол удовлетворяет условию теоремы.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Вероятностные вычисления. Вероятностная машина Тьюринга]]&lt;br /&gt;
*[[Классы NP и Σ₁]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория сложности]]&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D0%B5%D0%BE%D1%80%D0%B5%D0%BC%D0%B0_%D0%9C%D0%B0%D1%85%D1%8D%D0%BD%D0%B8&amp;diff=53442</id>
		<title>Теорема Махэни</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D0%B5%D0%BE%D1%80%D0%B5%D0%BC%D0%B0_%D0%9C%D0%B0%D1%85%D1%8D%D0%BD%D0%B8&amp;diff=53442"/>
				<updated>2016-04-25T19:15:53Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Теорема Махэни, доказанная Стефаном Махэни в 1982 году, утверждает, что если хотя бы один [[#Sparse|редкий язык]] {{---}} [[Сведение_относительно_класса_функций._Сведение_по_Карпу._Трудные_и_полные_задачи#.D0.9E.D0.BF.D1.80.D0.B5.D0.B4.D0.B5.D0.BB.D0.B5.D0.BD.D0.B8.D1.8F_.D1.82.D1.80.D1.83.D0.B4.D0.BD.D1.8B.D1.85_.D0.B8_.D0.BF.D0.BE.D0.BB.D0.BD.D1.8B.D1.85_.D0.B7.D0.B0.D0.B4.D0.B0.D1.87 | &amp;lt;tex&amp;gt; \mathrm{NP} &amp;lt;/tex&amp;gt;{{---}}полный ]], то &amp;lt;tex&amp;gt; \mathrm{P} = \mathrm{NP} &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Подготовка к доказательству==&lt;br /&gt;
&lt;br /&gt;
Введём вспомогательный язык &amp;lt;tex&amp;gt;\mathrm{LSAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{LSAT} = \{\langle \varphi, y \rangle \mid \exists x: x \leqslant_{lex} y, \varphi(x) = 1\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt; \varphi &amp;lt;/tex&amp;gt; {{---}} [[Определение_булевой_функции | булева формула]] из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; переменных, &amp;lt;tex&amp;gt;x, y \in \{0,1\}^{n} &amp;lt;/tex&amp;gt; и отношение &amp;lt;tex&amp;gt; \leqslant_{lex} &amp;lt;/tex&amp;gt; задает [[Лексикографический порядок | лексикографический порядок]].&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|about=1&lt;br /&gt;
|statement=&amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPC}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
#Очевидно, что &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NP}&amp;lt;/tex&amp;gt; (в качестве [[Классы_NP,_coNP,_Σ₁,_Π₁#.D0.9E.D0.BF.D1.80.D0.B5.D0.B4.D0.B5.D0.BB.D0.B5.D0.BD.D0.B8.D1.8F.2C_.D1.81.D0.B2.D1.8F.D0.B7.D1.8C_.CE.A3.E2.82.81_.D0.B8_NP|сертификата]] можно запросить &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;).&lt;br /&gt;
#[[Сведение относительно класса функций. Сведение по Карпу. Трудные и полные задачи | Сведём]] &amp;lt;tex&amp;gt;\mathrm{SAT}&amp;lt;/tex&amp;gt; к &amp;lt;tex&amp;gt;\mathrm{LSAT}&amp;lt;/tex&amp;gt;. Для этого рассмотрим отображение &amp;lt;tex&amp;gt;\varphi \mapsto \langle \varphi, 1^{|\varphi|}\rangle&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;|\varphi|&amp;lt;/tex&amp;gt; — количество различных переменных в формуле &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt;. Ясно, что данное преобразование можно сделать за полиномиальное время. Теперь докажем, что сведение верное. &lt;br /&gt;
#*Если &amp;lt;tex&amp;gt;\varphi \in \mathrm{SAT}&amp;lt;/tex&amp;gt;, то формула &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt; удовлетворима, а значит &amp;lt;tex&amp;gt;\exists x: x \leqslant_{lex} 1^{|\varphi|}, \varphi(x)=1&amp;lt;/tex&amp;gt;. Такой &amp;lt;tex&amp;gt; x &amp;lt;/tex&amp;gt; cуществует, потому что формула удовлетворима и любой вектор длины &amp;lt;tex&amp;gt; |\varphi| &amp;lt;/tex&amp;gt; меньше либо равен единичному, значит мы переберем всевозможые вектора. Следовательно, &amp;lt;tex&amp;gt;\langle \varphi, 1^{|\varphi|}\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
#*Если &amp;lt;tex&amp;gt;\langle \varphi, 1^{|\varphi|}\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\exists x: x \leqslant_{lex} 1^{|\varphi|}, \varphi(x)=1&amp;lt;/tex&amp;gt;. Значит формула &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt; удовлетворима, и &amp;lt;tex&amp;gt;\varphi \in \mathrm{SAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
:Таким образом, &amp;lt;tex&amp;gt;\mathrm{SAT} \leqslant \mathrm{LSAT}&amp;lt;/tex&amp;gt;. Но [[Теорема Кука | по теореме Кука ]]&amp;lt;tex&amp;gt;\mathrm{SAT} \in \mathrm{NPC}&amp;lt;/tex&amp;gt;, а значит для любого &amp;lt;tex&amp;gt;L \in \mathrm{NP} &amp;lt;/tex&amp;gt; выполнено &amp;lt;tex&amp;gt; L \leqslant \mathrm{SAT}&amp;lt;/tex&amp;gt;. Тогда в силу транзитивности &amp;lt;tex&amp;gt;\forall L \in \mathrm{NP} \; L \leqslant \mathrm{LSAT}&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPH}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Итого, мы доказали, что &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPH}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NP}&amp;lt;/tex&amp;gt;. Тогда по определению &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPC}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=&amp;lt;tex&amp;gt;\langle\varphi,y\rangle \in \mathrm{LSAT}, y&amp;lt;_{lex}z&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;\langle\varphi,z\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&amp;lt;tex&amp;gt;\langle\varphi,y\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;\exists x: x\leqslant_{lex}y, \varphi(x) = 1&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;y&amp;lt;_{lex}z&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\exists x: x&amp;lt;_{lex}z, \varphi(x) = 1&amp;lt;/tex&amp;gt;, следовательно &amp;lt;tex&amp;gt;\langle\varphi,z\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Редкие языки==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|id = Sparse&lt;br /&gt;
|definition=&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{SPARSE}=\{L \mid \exists&amp;lt;/tex&amp;gt; полином &amp;lt;tex&amp;gt; p: \forall n \, |L \cap \Sigma^n| \leqslant p(n)\}&amp;lt;/tex&amp;gt; {{---}} множество '''редких''' (англ. ''sparse'') языков.&lt;br /&gt;
}}&lt;br /&gt;
То есть множество языков таких, что множество слов длины &amp;lt;tex&amp;gt; n &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; n &amp;lt;/tex&amp;gt; всего &amp;lt;tex&amp;gt; 2^{n} &amp;lt;/tex&amp;gt;, и если язык содержит только полином от этого числа, то при большом &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; эта часть стремится к нулю.&lt;br /&gt;
&lt;br /&gt;
'''Пример:''' Согласно [[Машина_Тьюринга#.D0.9C.D0.BD.D0.BE.D0.B3.D0.BE.D0.BB.D0.B5.D0.BD.D1.82.D0.BE.D1.87.D0.BD.D0.B0.D1.8F_.D0.BC.D0.B0.D1.88.D0.B8.D0.BD.D0.B0_.D0.A2.D1.8C.D1.8E.D1.80.D0.B8.D0.BD.D0.B3.D0.B0 | тезису Чёрча {{---}} Тьюринга]], существует биекция между машинами Тьюринга и программами. Зафиксировав алфавит, можно занумеровать программы (программа будет иметь номер &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, если ее код {{---}} &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;{{---}}е слово среди всех слов над алфавитом, отсортированных сначала по возрастанию длины, а при равной длине {{---}} в лексикографическом порядке), а следовательно и машины Тьюринга. Рассмотрим язык &amp;lt;tex&amp;gt; \{1^{n} \mid n&amp;lt;/tex&amp;gt;{{---}}я [[Машина Тьюринга | машина Тьюринга]] останавливается в допускающем состоянии &amp;lt;tex&amp;gt; \} &amp;lt;/tex&amp;gt;. Просто приняв &amp;lt;tex&amp;gt; p(n) = 1 &amp;lt;/tex&amp;gt;, получим, что он принадлежит &amp;lt;tex&amp;gt; \mathrm{SPARSE}&amp;lt;/tex&amp;gt;. Более того, любой унарный язык принадлежит &amp;lt;tex&amp;gt;\mathrm{SPARSE} &amp;lt;/tex&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
==Теорема==&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|author=Махэни&lt;br /&gt;
|statement=&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{NPC} \cap \mathrm{SPARSE} \ne \varnothing \Rightarrow \mathrm{P}=\mathrm{NP}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=Пусть &amp;lt;tex&amp;gt;S \in \mathrm{NPC} \cap \mathrm{SPARSE}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;S\in \mathrm{NPC}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPC}&amp;lt;/tex&amp;gt;, то существует полиномиальная функция сведения &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; такая, что &amp;lt;tex&amp;gt;\langle \varphi, y \rangle \in \mathrm{LSAT} \Leftrightarrow f(\langle \varphi, y \rangle) \in S&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как функция &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; работает полиномиальное время, то &amp;lt;tex&amp;gt;f(\langle\varphi,y\rangle) \leqslant q(|\varphi|)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; — полином.&lt;br /&gt;
&amp;lt;tex&amp;gt;S\in \mathrm{SPARSE}&amp;lt;/tex&amp;gt;, следовательно &amp;lt;tex&amp;gt;\forall n \; |S \cap \Sigma^n|\leqslant p(n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; — некоторый полином. &lt;br /&gt;
&lt;br /&gt;
Тогда &amp;lt;tex&amp;gt;|\{x\in S \mid |x| \leqslant q(|\varphi|)\}|  = \displaystyle\sum\limits_{i=1}^{q(|\varphi|)}|S \cap \Sigma^i| \leqslant \displaystyle\sum\limits_{i=1}^{q(|\varphi|)} p(i) = r(|\varphi|)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; — также полином.&lt;br /&gt;
&lt;br /&gt;
Опишем алгоритм для нахождения лексикографически минимальной строки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, удовлетворяющей формуле &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;n=|\varphi|, r=r(|\varphi|)&amp;lt;/tex&amp;gt;. Изначально область поиска для &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; — все строки длины &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. Опишем одну итерацию поиска.&lt;br /&gt;
&lt;br /&gt;
Разобьём текущее множество строк на &amp;lt;tex&amp;gt;r+1&amp;lt;/tex&amp;gt; подотрезок примерно равной длины. Обозначим концы полученных подотрезков &amp;lt;tex&amp;gt;w_0, \ldots ,w_{r+1}&amp;lt;/tex&amp;gt;. И &amp;lt;tex&amp;gt;w_0 &amp;lt; w_1 &amp;lt; \ldots &amp;lt; w_{r+1} &amp;lt;/tex&amp;gt;. Пусть теперь &amp;lt;tex&amp;gt;z_i=f(\langle\varphi,w_i\rangle)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Из леммы (2) мы знаем, что, начиная с некоторого &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, все пары &amp;lt;tex&amp;gt;\langle\varphi, w_l\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;. Тогда по сведению &amp;lt;tex&amp;gt;z_j \in S&amp;lt;/tex&amp;gt; для всех &amp;lt;tex&amp;gt;j\geqslant l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим два случая:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tex&amp;gt;z_i=z_j&amp;lt;/tex&amp;gt; для некоторого &amp;lt;tex&amp;gt; j &amp;gt; i &amp;lt;/tex&amp;gt; . Строки &amp;lt;tex&amp;gt;z_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;z_j&amp;lt;/tex&amp;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;z_i, z_j \in S&amp;lt;/tex&amp;gt;, то по сведению &amp;lt;tex&amp;gt; \langle \varphi, w_i \rangle, \langle \varphi, w_j \rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;, то есть получаем &amp;lt;tex&amp;gt; x \leqslant w_i &amp;lt; w_j &amp;lt;/tex&amp;gt;. Тогда по вышеуказанной причине &amp;lt;tex&amp;gt;x\notin (w_i, w_j]&amp;lt;/tex&amp;gt;. Значит мы можем исключить этот полуинтервал из рассматриваемого множества. Таким образом, мы удаляем не менее &amp;lt;tex&amp;gt;\dfrac 1{r+1}&amp;lt;/tex&amp;gt; часть множества подстановок.&lt;br /&gt;
# &amp;lt;tex&amp;gt;z_i \ne z_j \, \forall i \ne j&amp;lt;/tex&amp;gt;. Как было показано выше, если &amp;lt;tex&amp;gt;x \in [w_0, w_1]&amp;lt;/tex&amp;gt;, то все &amp;lt;tex&amp;gt;z_i&amp;lt;/tex&amp;gt;, начиная с &amp;lt;tex&amp;gt;z_1&amp;lt;/tex&amp;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;r+1&amp;lt;/tex&amp;gt; строку длины не более, чем &amp;lt;tex&amp;gt;q(|\varphi|)&amp;lt;/tex&amp;gt;, что противоречит условию &amp;lt;tex&amp;gt;|\{x\in S \mid |x| \leqslant q(|\varphi|)\}| \leqslant r(|\varphi|)&amp;lt;/tex&amp;gt;. Следовательно, &amp;lt;tex&amp;gt;x\notin[w_0,w_1]&amp;lt;/tex&amp;gt;, то есть его можно убрать из рассмотрения.&lt;br /&gt;
&lt;br /&gt;
В обоих случаях мы сузили область поиска как минимум на &amp;lt;tex&amp;gt;\dfrac 1{r+1}&amp;lt;/tex&amp;gt; её размера. &lt;br /&gt;
&lt;br /&gt;
Будем повторять эту процедуру до тех пор, пока не останется не более &amp;lt;tex&amp;gt;r+1&amp;lt;/tex&amp;gt; строки, которые мы можем проверить за полиномиальное время. Если какая{{---}}то из них удовлетворила формуле &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;x=\min(w_i), w_i&amp;lt;/tex&amp;gt; удовлетворяет &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt;. Иначе, &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; не существует.&lt;br /&gt;
&lt;br /&gt;
Оценим время работы нашего алгоритма. После &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; итераций у нас останется не более &amp;lt;tex&amp;gt;2^n\left(1-\dfrac1{r+1}\right)^k&amp;lt;/tex&amp;gt; строк. Оценим &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Нам нужно, чтобы &amp;lt;tex&amp;gt;2^n\left(1-\dfrac1{r+1}\right)^k \simeq 1&amp;lt;/tex&amp;gt;. Отсюда &amp;lt;tex&amp;gt;k=O(rn)&amp;lt;/tex&amp;gt; (это можно получить, выразив &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; через &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; и воспользовавшись [[Формула Тейлора для произвольной функции | формулой Тейлора]] для логарифма). &lt;br /&gt;
&lt;br /&gt;
Таким образом, мы можем разрешить язык &amp;lt;tex&amp;gt;\mathrm{LSAT}&amp;lt;/tex&amp;gt; за полиномиальное время, найдя лексикографически минимальную строку, удовлетворяющую формуле, и сравнив её с нашим аргументом. Так как &amp;lt;tex&amp;gt;\mathrm{LSAT}\in \mathrm{NPC}&amp;lt;/tex&amp;gt;, то мы можем решить любую задачу из &amp;lt;tex&amp;gt;\mathrm{NP}&amp;lt;/tex&amp;gt; за полиномиальное время, а значит &amp;lt;tex&amp;gt;\mathrm{P}=\mathrm{NP}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Класс P]]&lt;br /&gt;
*[[Классы NP и Σ₁]]&lt;br /&gt;
*[[Сведение относительно класса функций. Сведение по Карпу. Трудные и полные задачи]]&lt;br /&gt;
*[[Теорема Бермана — Форчуна]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [http://blog.computationalcomplexity.org/2011/09/mahaneys-theorem.html Блог Computational Complexity]&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Sparse_language Wikipedia — Sparse language]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория сложности]]&lt;br /&gt;
[[Категория: Детерминированные и недетерминированные вычисления, сложность по времени и по памяти]]&lt;br /&gt;
[[Категория: Классы P и NP, NP{{---}}полнота]]&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D0%B5%D0%BE%D1%80%D0%B5%D0%BC%D0%B0_%D0%9C%D0%B0%D1%85%D1%8D%D0%BD%D0%B8&amp;diff=53430</id>
		<title>Теорема Махэни</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D0%B5%D0%BE%D1%80%D0%B5%D0%BC%D0%B0_%D0%9C%D0%B0%D1%85%D1%8D%D0%BD%D0%B8&amp;diff=53430"/>
				<updated>2016-04-24T20:35:18Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Теорема Махэни, доказанная Стефаном Махэни в 1982 году, утверждает, что если хотя бы один [[#Sparse|редкий язык]] {{---}} [[Сведение_относительно_класса_функций._Сведение_по_Карпу._Трудные_и_полные_задачи#.D0.9E.D0.BF.D1.80.D0.B5.D0.B4.D0.B5.D0.BB.D0.B5.D0.BD.D0.B8.D1.8F_.D1.82.D1.80.D1.83.D0.B4.D0.BD.D1.8B.D1.85_.D0.B8_.D0.BF.D0.BE.D0.BB.D0.BD.D1.8B.D1.85_.D0.B7.D0.B0.D0.B4.D0.B0.D1.87 | &amp;lt;tex&amp;gt; \mathrm{NP} &amp;lt;/tex&amp;gt;-полный ]], то &amp;lt;tex&amp;gt; \mathrm{P} = \mathrm{NP} &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Подготовка к доказательству==&lt;br /&gt;
&lt;br /&gt;
Введём вспомогательный язык &amp;lt;tex&amp;gt;\mathrm{LSAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{LSAT} = \{\langle \varphi, y \rangle \mid \exists x: x \leqslant_{lex} y, \varphi(x) = 1\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt; \varphi &amp;lt;/tex&amp;gt; {{---}} [[Определение_булевой_функции | булева формула]] из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; переменных, &amp;lt;tex&amp;gt;x, y \in \{0,1\}^{n} &amp;lt;/tex&amp;gt; и отношение &amp;lt;tex&amp;gt; \leqslant_{lex} &amp;lt;/tex&amp;gt; задает [[Лексикографический порядок | лексикографический порядок]].&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|about=1&lt;br /&gt;
|statement=&amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPC}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
#Очевидно, что &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NP}&amp;lt;/tex&amp;gt; (в качестве [[Классы_NP,_coNP,_Σ₁,_Π₁#.D0.9E.D0.BF.D1.80.D0.B5.D0.B4.D0.B5.D0.BB.D0.B5.D0.BD.D0.B8.D1.8F.2C_.D1.81.D0.B2.D1.8F.D0.B7.D1.8C_.CE.A3.E2.82.81_.D0.B8_NP|сертификата]] можно запросить &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;).&lt;br /&gt;
#[[Сведение относительно класса функций. Сведение по Карпу. Трудные и полные задачи | Сведём]] &amp;lt;tex&amp;gt;\mathrm{SAT}&amp;lt;/tex&amp;gt; к &amp;lt;tex&amp;gt;\mathrm{LSAT}&amp;lt;/tex&amp;gt;. Для этого рассмотрим отображение &amp;lt;tex&amp;gt;\varphi \mapsto \langle \varphi, 1^{|\varphi|}\rangle&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;|\varphi|&amp;lt;/tex&amp;gt; — количество различных переменных в формуле &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt;. Ясно, что данное преобразование можно сделать за полиномиальное время. Теперь докажем, что сведение верное. &lt;br /&gt;
#*Если &amp;lt;tex&amp;gt;\varphi \in \mathrm{SAT}&amp;lt;/tex&amp;gt;, то формула &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt; удовлетворима, а значит &amp;lt;tex&amp;gt;\exists x: x \leqslant_{lex} 1^{|\varphi|}, \varphi(x)=1&amp;lt;/tex&amp;gt;. Такой &amp;lt;tex&amp;gt; x &amp;lt;/tex&amp;gt; cуществует, потому что формула удовлетворима и любой вектор длины &amp;lt;tex&amp;gt; |\varphi| &amp;lt;/tex&amp;gt; меньше либо равен единичному, значит мы переберем всевозможые вектора. Следовательно, &amp;lt;tex&amp;gt;\langle \varphi, 1^{|\varphi|}\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
#*Если &amp;lt;tex&amp;gt;\langle \varphi, 1^{|\varphi|}\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\exists x: x \leqslant_{lex} 1^{|\varphi|}, \varphi(x)=1&amp;lt;/tex&amp;gt;. Значит формула &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt; удовлетворима, и &amp;lt;tex&amp;gt;\varphi \in \mathrm{SAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
:Таким образом, &amp;lt;tex&amp;gt;\mathrm{SAT} \leqslant \mathrm{LSAT}&amp;lt;/tex&amp;gt;. Но [[Теорема Кука | по теореме Кука ]]&amp;lt;tex&amp;gt;\mathrm{SAT} \in \mathrm{NPC}&amp;lt;/tex&amp;gt;, а значит для любого &amp;lt;tex&amp;gt;L \in \mathrm{NP} &amp;lt;/tex&amp;gt; выполнено &amp;lt;tex&amp;gt; L \leqslant \mathrm{SAT}&amp;lt;/tex&amp;gt;. Тогда в силу транзитивности &amp;lt;tex&amp;gt;\forall L \in \mathrm{NP} \; L \leqslant \mathrm{LSAT}&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPH}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Итого, мы доказали, что &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPH}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NP}&amp;lt;/tex&amp;gt;. Тогда по определению &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPC}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=&amp;lt;tex&amp;gt;\langle\varphi,y\rangle \in \mathrm{LSAT}, y&amp;lt;_{lex}z&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;\langle\varphi,z\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&amp;lt;tex&amp;gt;\langle\varphi,y\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;\exists x: x\leqslant_{lex}y, \varphi(x) = 1&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;y&amp;lt;_{lex}z&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\exists x: x&amp;lt;_{lex}z, \varphi(x) = 1&amp;lt;/tex&amp;gt;, следовательно &amp;lt;tex&amp;gt;\langle\varphi,z\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Редкие языки==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|id = Sparse&lt;br /&gt;
|definition=&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{SPARSE}=\{L \mid \exists&amp;lt;/tex&amp;gt; полином &amp;lt;tex&amp;gt; p: \forall n \, |L \cap \Sigma^n| \leqslant p(n)\}&amp;lt;/tex&amp;gt; {{---}} множество '''редких''' (англ. ''sparse'') языков.&lt;br /&gt;
}}&lt;br /&gt;
То есть множество языков таких, что множество слов длины &amp;lt;tex&amp;gt; n &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; n &amp;lt;/tex&amp;gt; всего &amp;lt;tex&amp;gt; 2^{n} &amp;lt;/tex&amp;gt;, и если язык содержит только полином от этого числа, то при большом &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; эта часть стремится к нулю.&lt;br /&gt;
&lt;br /&gt;
'''Пример:''' Согласно [https://en.wikipedia.org/wiki/Church%E2%80%93Turing_thesis тезису Чёрча - Тьюринга], существует биекция между машинами Тьюринга и программами. Зафиксировав алфавит, можно занумеровать программы (программа будет иметь номер &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, если ее код {{---}} &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-е слово среди всех слов над алфавитом, отсортированных сначала по возрастанию длины, а при равной длине - в лексикографическом порядке), а следовательно и машины Тьюринга. Рассмотрим язык &amp;lt;tex&amp;gt; \{1^{n} \mid n&amp;lt;/tex&amp;gt;-я [[Машина Тьюринга | машина Тьюринга]] останавливается в допускающем состоянии &amp;lt;tex&amp;gt; \} &amp;lt;/tex&amp;gt;. Просто приняв &amp;lt;tex&amp;gt; p(n) = 1 &amp;lt;/tex&amp;gt;, получим, что он принадлежит &amp;lt;tex&amp;gt; \mathrm{SPARSE}&amp;lt;/tex&amp;gt;. Более того, любой унарный язык принадлежит &amp;lt;tex&amp;gt;\mathrm{SPARSE} &amp;lt;/tex&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
==Теорема==&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|author=Махэни&lt;br /&gt;
|statement=&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{NPC} \cap \mathrm{SPARSE} \ne \varnothing \Rightarrow \mathrm{P}=\mathrm{NP}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=Пусть &amp;lt;tex&amp;gt;S \in \mathrm{NPC} \cap \mathrm{SPARSE}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;S\in \mathrm{NPC}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPC}&amp;lt;/tex&amp;gt;, то существует полиномиальная функция сведения &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; такая, что &amp;lt;tex&amp;gt;\langle \varphi, y \rangle \in \mathrm{LSAT} \Leftrightarrow f(\langle \varphi, y \rangle) \in S&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как функция &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; работает полиномиальное время, то &amp;lt;tex&amp;gt;f(\langle\varphi,y\rangle) \leqslant q(|\varphi|)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; — полином.&lt;br /&gt;
&amp;lt;tex&amp;gt;S\in \mathrm{SPARSE}&amp;lt;/tex&amp;gt;, следовательно &amp;lt;tex&amp;gt;\forall n \; |S \cap \Sigma^n|\leqslant p(n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; — некоторый полином. &lt;br /&gt;
&lt;br /&gt;
Тогда &amp;lt;tex&amp;gt;|\{x\in S \mid |x| \leqslant q(|\varphi|)\}|  = \displaystyle\sum\limits_{i=1}^{q(|\varphi|)}|S \cap \Sigma^i| \leqslant \displaystyle\sum\limits_{i=1}^{q(|\varphi|)} p(i) = r(|\varphi|)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; — также полином.&lt;br /&gt;
&lt;br /&gt;
Опишем алгоритм для нахождения лексикографически минимальной строки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, удовлетворяющей формуле &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;n=|\varphi|, r=r(|\varphi|)&amp;lt;/tex&amp;gt;. Изначально область поиска для &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; — все строки длины &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. Опишем одну итерацию поиска.&lt;br /&gt;
&lt;br /&gt;
Разобьём текущее множество строк на &amp;lt;tex&amp;gt;r+1&amp;lt;/tex&amp;gt; подотрезок примерно равной длины. Обозначим концы полученных подотрезков &amp;lt;tex&amp;gt;w_0, \ldots ,w_{r+1}&amp;lt;/tex&amp;gt;. И &amp;lt;tex&amp;gt;w_0 &amp;lt; w_1 &amp;lt; \ldots &amp;lt; w_{r+1} &amp;lt;/tex&amp;gt;. Пусть теперь &amp;lt;tex&amp;gt;z_i=f(\langle\varphi,w_i\rangle)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Из леммы (2) мы знаем, что, начиная с некоторого &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, все пары &amp;lt;tex&amp;gt;\langle\varphi, w_l\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;. Тогда по сведению &amp;lt;tex&amp;gt;z_j \in S&amp;lt;/tex&amp;gt; для всех &amp;lt;tex&amp;gt;j\geqslant l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим два случая:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tex&amp;gt;z_i=z_j&amp;lt;/tex&amp;gt; для некоторого &amp;lt;tex&amp;gt; j &amp;gt; i &amp;lt;/tex&amp;gt; . Строки &amp;lt;tex&amp;gt;z_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;z_j&amp;lt;/tex&amp;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;z_i, z_j \in S&amp;lt;/tex&amp;gt;, то по сведению &amp;lt;tex&amp;gt; \langle \varphi, w_i \rangle, \langle \varphi, w_j \rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;, то есть получаем &amp;lt;tex&amp;gt; x \leqslant w_i &amp;lt; w_j &amp;lt;/tex&amp;gt;. Тогда по вышеуказанной причине &amp;lt;tex&amp;gt;x\notin (w_i, w_j]&amp;lt;/tex&amp;gt;. Значит мы можем исключить этот полуинтервал из рассматриваемого множества. Таким образом, мы удаляем не менее &amp;lt;tex&amp;gt;\dfrac 1{r+1}&amp;lt;/tex&amp;gt; часть множества подстановок.&lt;br /&gt;
# &amp;lt;tex&amp;gt;z_i \ne z_j \, \forall i \ne j&amp;lt;/tex&amp;gt;. Как было показано выше, если &amp;lt;tex&amp;gt;x \in [w_0, w_1]&amp;lt;/tex&amp;gt;, то все &amp;lt;tex&amp;gt;z_i&amp;lt;/tex&amp;gt;, начиная с &amp;lt;tex&amp;gt;z_1&amp;lt;/tex&amp;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;r+1&amp;lt;/tex&amp;gt; строку длины не более, чем &amp;lt;tex&amp;gt;q(|\varphi|)&amp;lt;/tex&amp;gt;, что противоречит условию &amp;lt;tex&amp;gt;|\{x\in S \mid |x| \leqslant q(|\varphi|)\}| \leqslant r(|\varphi|)&amp;lt;/tex&amp;gt;. Следовательно, &amp;lt;tex&amp;gt;x\notin[w_0,w_1]&amp;lt;/tex&amp;gt;, то есть его можно убрать из рассмотрения.&lt;br /&gt;
&lt;br /&gt;
В обоих случаях мы сузили область поиска как минимум на &amp;lt;tex&amp;gt;\dfrac 1{r+1}&amp;lt;/tex&amp;gt; её размера. &lt;br /&gt;
&lt;br /&gt;
Будем повторять эту процедуру до тех пор, пока не останется не более &amp;lt;tex&amp;gt;r+1&amp;lt;/tex&amp;gt; строки, которые мы можем проверить за полиномиальное время. Если какая-то из них удовлетворила формуле &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;x=\min(w_i), w_i&amp;lt;/tex&amp;gt; удовлетворяет &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt;. Иначе, &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; не существует.&lt;br /&gt;
&lt;br /&gt;
Оценим время работы нашего алгоритма. После &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; итераций у нас останется не более &amp;lt;tex&amp;gt;2^n\left(1-\dfrac1{r+1}\right)^k&amp;lt;/tex&amp;gt; строк. Оценим &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Нам нужно, чтобы &amp;lt;tex&amp;gt;2^n\left(1-\dfrac1{r+1}\right)^k \simeq 1&amp;lt;/tex&amp;gt;. Отсюда &amp;lt;tex&amp;gt;k=O(rn)&amp;lt;/tex&amp;gt; (это можно получить, выразив &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; через &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; и воспользовавшись [[Формула Тейлора для произвольной функции | формулой Тейлора]] для логарифма). &lt;br /&gt;
&lt;br /&gt;
Таким образом, мы можем разрешить язык &amp;lt;tex&amp;gt;\mathrm{LSAT}&amp;lt;/tex&amp;gt; за полиномиальное время, найдя лексикографически минимальную строку, удовлетворяющую формуле, и сравнив её с нашим аргументом. Так как &amp;lt;tex&amp;gt;\mathrm{LSAT}\in \mathrm{NPC}&amp;lt;/tex&amp;gt;, то мы можем решить любую задачу из &amp;lt;tex&amp;gt;\mathrm{NP}&amp;lt;/tex&amp;gt; за полиномиальное время, а значит &amp;lt;tex&amp;gt;\mathrm{P}=\mathrm{NP}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Класс P]]&lt;br /&gt;
*[[Классы NP и Σ₁]]&lt;br /&gt;
*[[Сведение относительно класса функций. Сведение по Карпу. Трудные и полные задачи]]&lt;br /&gt;
*[[Теорема Бермана — Форчуна]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [http://blog.computationalcomplexity.org/2011/09/mahaneys-theorem.html Блог Computational Complexity]&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Sparse_language Wikipedia — Sparse language]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория сложности]]&lt;br /&gt;
[[Категория: Детерминированные и недетерминированные вычисления, сложность по времени и по памяти]]&lt;br /&gt;
[[Категория: Классы P и NP, NP-полнота]]&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%B5%D0%BC%D0%BC%D0%B0_%D0%BE_%D0%BF%D0%B0%D1%80%D0%BE%D1%81%D0%BE%D1%87%D0%B5%D1%82%D0%B0%D0%BD%D0%B8%D0%B8_%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%B5_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD&amp;diff=53376</id>
		<title>Лемма о паросочетании в графе замен</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%B5%D0%BC%D0%BC%D0%B0_%D0%BE_%D0%BF%D0%B0%D1%80%D0%BE%D1%81%D0%BE%D1%87%D0%B5%D1%82%D0%B0%D0%BD%D0%B8%D0%B8_%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%B5_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD&amp;diff=53376"/>
				<updated>2016-04-18T22:12:51Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Лемма&lt;br /&gt;
|about=&lt;br /&gt;
о паросочетании в графе замен&lt;br /&gt;
|statement= Пусть &amp;lt;tex&amp;gt;M = \langle X,I \rangle &amp;lt;/tex&amp;gt; &amp;amp;mdash;  матроид. Множества &amp;lt;tex&amp;gt;A, B \in I&amp;lt;/tex&amp;gt; {{---}} независимы, причем &amp;lt;tex&amp;gt;|A| = |B|&amp;lt;/tex&amp;gt;. Тогда двудольный граф &amp;lt;tex&amp;gt;D_{M}(I)&amp;lt;/tex&amp;gt;  содержит полное паросочетание на &amp;lt;tex&amp;gt;A \bigtriangleup B&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof= &lt;br /&gt;
&amp;lt;tex&amp;gt;D_{M}(I)&amp;lt;/tex&amp;gt; {{---}} это двудольный граф с долями &amp;lt;tex&amp;gt;I&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;S \setminus I&amp;lt;/tex&amp;gt; с рёбрами между &amp;lt;tex&amp;gt;y \in I&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;x \in S \setminus I&amp;lt;/tex&amp;gt; если &amp;lt;tex&amp;gt; (I \setminus y) \cup x \in \mathcal{I} &amp;lt;/tex&amp;gt;&lt;br /&gt;
Индукция по &amp;lt;tex&amp;gt;|A \bigtriangleup B|&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
* База &lt;br /&gt;
*: В случае, когда &amp;lt;tex&amp;gt;|A \bigtriangleup B| = 0 &amp;lt;/tex&amp;gt;, есть пустое паросочетание. &lt;br /&gt;
* Переход&lt;br /&gt;
*:  &lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;k = |A| = |B|&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
Рассмотрим &amp;lt;tex&amp;gt;|A \bigtriangleup B| \geq 1&amp;lt;/tex&amp;gt;.  &lt;br /&gt;
 &lt;br /&gt;
Рассмотрим матроид &amp;lt;tex&amp;gt;M_1 = \langle X, \{ A | A \in I, A \leq k \} \rangle&amp;lt;/tex&amp;gt;. Множества &amp;lt;tex&amp;gt;A, B \in I&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;|A| = |B|&amp;lt;/tex&amp;gt;, а значит они являются   &lt;br /&gt;
базами для матроида &amp;lt;tex&amp;gt;M_1&amp;lt;/tex&amp;gt;. Тогда по [[Теорема о базах|теореме о базах]] &amp;lt;tex&amp;gt;\forall x \in A \setminus B: \exists y \in B \setminus A : (A \setminus x) \cup y &lt;br /&gt;
\in I&amp;lt;/tex&amp;gt;, поэтому &amp;lt;tex&amp;gt;(x, y) \in G_M(A)&amp;lt;/tex&amp;gt;. Множества &amp;lt;tex&amp;gt;A' = A - x + y &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;B' = B + x - y&amp;lt;/tex&amp;gt; являются независимыми как подмножества независимых и их &amp;lt;tex&amp;gt;|A' \bigtriangleup B'| \leq |A \bigtriangleup B|&amp;lt;/tex&amp;gt;  Тогда по предположению индукции на их &amp;lt;tex&amp;gt;| A' \bigtriangleup B'|&amp;lt;/tex&amp;gt; есть полное паросочетание &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;N \cup {(x, y)}&amp;lt;/tex&amp;gt; составляет полное паросочетание на &amp;lt;tex&amp;gt;|A \bigtriangleup B|&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;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D0%B5%D0%BE%D1%80%D0%B5%D0%BC%D0%B0_%D0%9C%D0%B0%D1%85%D1%8D%D0%BD%D0%B8&amp;diff=53161</id>
		<title>Теорема Махэни</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D0%B5%D0%BE%D1%80%D0%B5%D0%BC%D0%B0_%D0%9C%D0%B0%D1%85%D1%8D%D0%BD%D0%B8&amp;diff=53161"/>
				<updated>2016-04-09T19:56:16Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Теорема Махэни, доказанная Стефаном Махэни в 1982 году, утверждает, что если хотя бы один [[#Sparse|редкий язык]] {{---}} [[Сведение_относительно_класса_функций._Сведение_по_Карпу._Трудные_и_полные_задачи#.D0.9E.D0.BF.D1.80.D0.B5.D0.B4.D0.B5.D0.BB.D0.B5.D0.BD.D0.B8.D1.8F_.D1.82.D1.80.D1.83.D0.B4.D0.BD.D1.8B.D1.85_.D0.B8_.D0.BF.D0.BE.D0.BB.D0.BD.D1.8B.D1.85_.D0.B7.D0.B0.D0.B4.D0.B0.D1.87 | &amp;lt;tex&amp;gt; \mathrm{NP} &amp;lt;/tex&amp;gt;-полный ]], то &amp;lt;tex&amp;gt; \mathrm{P} = \mathrm{NP} &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Подготовка к доказательству==&lt;br /&gt;
&lt;br /&gt;
Введём вспомогательный язык &amp;lt;tex&amp;gt;\mathrm{LSAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{LSAT} = \{\langle \varphi, y \rangle \mid \exists x: x \leqslant_{lex} y, \varphi(x) = 1\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt; \varphi &amp;lt;/tex&amp;gt; {{---}} [[Определение_булевой_функции | булева формула]] из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; переменных, &amp;lt;tex&amp;gt;x, y \in \{0,1\}^{n} &amp;lt;/tex&amp;gt; и отношение &amp;lt;tex&amp;gt; \leqslant_{lex} &amp;lt;/tex&amp;gt; задает [[Лексикографический порядок | лексикографический порядок]].&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|about=1&lt;br /&gt;
|statement=&amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPC}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
#Очевидно, что &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NP}&amp;lt;/tex&amp;gt; (в качестве [[Классы_NP,_coNP,_Σ₁,_Π₁#.D0.9E.D0.BF.D1.80.D0.B5.D0.B4.D0.B5.D0.BB.D0.B5.D0.BD.D0.B8.D1.8F.2C_.D1.81.D0.B2.D1.8F.D0.B7.D1.8C_.CE.A3.E2.82.81_.D0.B8_NP|сертификата]] можно запросить &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;).&lt;br /&gt;
#[[Сведение относительно класса функций. Сведение по Карпу. Трудные и полные задачи | Сведём]] &amp;lt;tex&amp;gt;\mathrm{SAT}&amp;lt;/tex&amp;gt; к &amp;lt;tex&amp;gt;\mathrm{LSAT}&amp;lt;/tex&amp;gt;. Для этого рассмотрим отображение &amp;lt;tex&amp;gt;\varphi \mapsto \langle \varphi, 1^{|\varphi|}\rangle&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;|\varphi|&amp;lt;/tex&amp;gt; — количество различных переменных в формуле &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt;. Ясно, что данное преобразование можно сделать за полиномиальное время. Теперь докажем, что сведение верное. &lt;br /&gt;
#*Если &amp;lt;tex&amp;gt;\varphi \in \mathrm{SAT}&amp;lt;/tex&amp;gt;, то формула &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt; удовлетворима, а значит &amp;lt;tex&amp;gt;\exists x: x \leqslant_{lex} 1^{|\varphi|}, \varphi(x)=1&amp;lt;/tex&amp;gt;. Такой &amp;lt;tex&amp;gt; x &amp;lt;/tex&amp;gt; cуществует, потому что формула удовлетворима и любой вектор длины &amp;lt;tex&amp;gt; |\varphi| &amp;lt;/tex&amp;gt; меньше либо равен единичному, значит мы переберем всевозможые вектора. Следовательно, &amp;lt;tex&amp;gt;\langle \varphi, 1^{|\varphi|}\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
#*Если &amp;lt;tex&amp;gt;\langle \varphi, 1^{|\varphi|}\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\exists x: x \leqslant_{lex} 1^{|\varphi|}, \varphi(x)=1&amp;lt;/tex&amp;gt;. Значит формула &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt; удовлетворима, и &amp;lt;tex&amp;gt;\varphi \in \mathrm{SAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
:Таким образом, &amp;lt;tex&amp;gt;\mathrm{SAT} \leqslant \mathrm{LSAT}&amp;lt;/tex&amp;gt;. Но [[Теорема Кука | по теореме Кука ]]&amp;lt;tex&amp;gt;\mathrm{SAT} \in \mathrm{NPC}&amp;lt;/tex&amp;gt;, а значит для любого &amp;lt;tex&amp;gt;L \in \mathrm{NP} &amp;lt;/tex&amp;gt; выполнено &amp;lt;tex&amp;gt; L \leqslant \mathrm{SAT}&amp;lt;/tex&amp;gt;. Тогда в силу транзитивности &amp;lt;tex&amp;gt;\forall L \in \mathrm{NP} \; L \leqslant \mathrm{LSAT}&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPH}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Итого, мы доказали, что &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPH}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NP}&amp;lt;/tex&amp;gt;. Тогда по определению &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPC}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=&amp;lt;tex&amp;gt;\langle\varphi,y\rangle \in \mathrm{LSAT}, y&amp;lt;_{lex}z&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;\langle\varphi,z\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&amp;lt;tex&amp;gt;\langle\varphi,y\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;\exists x: x\leqslant_{lex}y, \varphi(x) = 1&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;y&amp;lt;_{lex}z&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\exists x: x&amp;lt;_{lex}z, \varphi(x) = 1&amp;lt;/tex&amp;gt;, следовательно &amp;lt;tex&amp;gt;\langle\varphi,z\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Редкие языки==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|id = Sparse&lt;br /&gt;
|definition=&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{SPARSE}=\{L \mid \exists&amp;lt;/tex&amp;gt; полином &amp;lt;tex&amp;gt; p: \forall n \, |L \cap \Sigma^n| \leqslant p(n)\}&amp;lt;/tex&amp;gt; {{---}} множество '''редких''' (англ. ''sparse'') языков.&lt;br /&gt;
}}&lt;br /&gt;
То есть множество языков таких, что множество слов длины &amp;lt;tex&amp;gt; n &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; n &amp;lt;/tex&amp;gt; всего &amp;lt;tex&amp;gt; 2^{n} &amp;lt;/tex&amp;gt;, и если язык содержит только полином от этого числа, то при большом &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; эта часть стремится к нулю.&lt;br /&gt;
&lt;br /&gt;
'''Пример:''' Согласно [https://en.wikipedia.org/wiki/Church%E2%80%93Turing_thesis тезису Чёрча - Тьюринга], существует биекция между машинами Тьюринга и программами. Зафиксировав алфавит, можно занумеровать программы (программа будет иметь номер &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, если ее код {{---}} &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-е слово среди всех слов над алфавитом, отсортированных сначала по возрастанию длины, а при равной длине - в лексикографическом порядке), а следовательно и машины Тьюринга. Рассмотрим язык &amp;lt;tex&amp;gt; \{1^{n} \mid n&amp;lt;/tex&amp;gt;-я [[Машина Тьюринга | машина Тьюринга]] останавливается в допускающем состоянии &amp;lt;tex&amp;gt; \} &amp;lt;/tex&amp;gt;. Просто приняв &amp;lt;tex&amp;gt; p(n) = 1 &amp;lt;/tex&amp;gt;, получим, что он принадлежит &amp;lt;tex&amp;gt; \mathrm{SPARSE}&amp;lt;/tex&amp;gt;. Более того, любой унарный язык принадлежит &amp;lt;tex&amp;gt;\mathrm{SPARSE} &amp;lt;/tex&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
==Теорема==&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|author=Махэни&lt;br /&gt;
|statement=&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{NPC} \cap \mathrm{SPARSE} \ne \varnothing \Rightarrow \mathrm{P}=\mathrm{NP}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=Пусть &amp;lt;tex&amp;gt;S \in \mathrm{NPC} \cap \mathrm{SPARSE}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;S\in \mathrm{NPC}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPC}&amp;lt;/tex&amp;gt;, то существует полиномиальная функция сведения &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; такая, что &amp;lt;tex&amp;gt;\langle \varphi, y \rangle \in \mathrm{LSAT} \Leftrightarrow f(\langle \varphi, y \rangle) \in S&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как функция &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; работает полиномиальное время, и &amp;lt;tex&amp;gt;|\varphi|\geqslant|y|&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;|y|&amp;lt;/tex&amp;gt; — длина вектора &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;), то &amp;lt;tex&amp;gt;f(\langle\varphi,y\rangle) \leqslant q(|\varphi|)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; — полином.&lt;br /&gt;
&amp;lt;tex&amp;gt;S\in \mathrm{SPARSE}&amp;lt;/tex&amp;gt;, следовательно &amp;lt;tex&amp;gt;\forall n \; |S \cap \Sigma^n|\leqslant p(n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; — некоторый полином. &lt;br /&gt;
&lt;br /&gt;
Тогда &amp;lt;tex&amp;gt;|\{x\in S \mid |x| \leqslant q(|\varphi|)\}|  = \displaystyle\sum\limits_{i=1}^{q(|\varphi|)}|S \cap \Sigma^i| \leqslant \displaystyle\sum\limits_{i=1}^{q(|\varphi|)} p(i) = r(|\varphi|)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; — также полином.&lt;br /&gt;
&lt;br /&gt;
Опишем алгоритм для нахождения лексикографически минимальной строки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, удовлетворяющей формуле &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;n=|\varphi|, r=r(|\varphi|)&amp;lt;/tex&amp;gt;. Изначально область поиска для &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; — все строки длины &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. Опишем одну итерацию поиска.&lt;br /&gt;
&lt;br /&gt;
Разобьём текущее множество строк на &amp;lt;tex&amp;gt;r+1&amp;lt;/tex&amp;gt; подотрезок примерно равной длины. Обозначим концы полученных подотрезков &amp;lt;tex&amp;gt;w_0, \ldots ,w_{r+1}&amp;lt;/tex&amp;gt;. И &amp;lt;tex&amp;gt;w_0 &amp;lt; w_1 &amp;lt; \ldots &amp;lt; w_{r+1} &amp;lt;/tex&amp;gt;. Пусть теперь &amp;lt;tex&amp;gt;z_i=f(\langle\varphi,w_i\rangle)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Из леммы (2) мы знаем, что, начиная с некоторого &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, все пары &amp;lt;tex&amp;gt;\langle\varphi, w_l\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;. Тогда по сведению &amp;lt;tex&amp;gt;z_j \in S&amp;lt;/tex&amp;gt; для всех &amp;lt;tex&amp;gt;j\geqslant l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим два случая:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tex&amp;gt;z_i=z_j&amp;lt;/tex&amp;gt; для некоторого &amp;lt;tex&amp;gt; j &amp;gt; i &amp;lt;/tex&amp;gt; . Строки &amp;lt;tex&amp;gt;z_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;z_j&amp;lt;/tex&amp;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;z_i, z_j \in S&amp;lt;/tex&amp;gt;, то по сведению &amp;lt;tex&amp;gt; \langle \varphi, w_i \rangle, \langle \varphi, w_j \rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;, то есть получаем &amp;lt;tex&amp;gt; x \leqslant w_i &amp;lt; w_j &amp;lt;/tex&amp;gt;. Тогда по вышеуказанной причине &amp;lt;tex&amp;gt;x\notin (w_i, w_j]&amp;lt;/tex&amp;gt;. Значит мы можем исключить этот полуинтервал из рассматриваемого множества. Таким образом, мы удаляем не менее &amp;lt;tex&amp;gt;\dfrac 1{r+1}&amp;lt;/tex&amp;gt; часть множества подстановок.&lt;br /&gt;
# &amp;lt;tex&amp;gt;z_i \ne z_j \, \forall i \ne j&amp;lt;/tex&amp;gt;. Как было показано выше, если &amp;lt;tex&amp;gt;x \in [w_0, w_1]&amp;lt;/tex&amp;gt;, то все &amp;lt;tex&amp;gt;z_i&amp;lt;/tex&amp;gt;, начиная с &amp;lt;tex&amp;gt;z_1&amp;lt;/tex&amp;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;r+1&amp;lt;/tex&amp;gt; строку длины не более, чем &amp;lt;tex&amp;gt;q(|\varphi|)&amp;lt;/tex&amp;gt;, что противоречит условию &amp;lt;tex&amp;gt;|\{x\in S \mid |x| \leqslant q(|\varphi|)\}| \leqslant r(|\varphi|)&amp;lt;/tex&amp;gt;. Следовательно, &amp;lt;tex&amp;gt;x\notin[w_0,w_1]&amp;lt;/tex&amp;gt;, то есть его можно убрать из рассмотрения.&lt;br /&gt;
&lt;br /&gt;
В обоих случаях мы сузили область поиска как минимум на &amp;lt;tex&amp;gt;\dfrac 1{r+1}&amp;lt;/tex&amp;gt; её размера. &lt;br /&gt;
&lt;br /&gt;
Будем повторять эту процедуру до тех пор, пока не останется не более &amp;lt;tex&amp;gt;r+1&amp;lt;/tex&amp;gt; строки, которые мы можем проверить за полиномиальное время. Если какая-то из них удовлетворила формуле &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;x=\min(w_i), w_i&amp;lt;/tex&amp;gt; удовлетворяет &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt;. Иначе, &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; не существует.&lt;br /&gt;
&lt;br /&gt;
Оценим время работы нашего алгоритма. После &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; итераций у нас останется не более &amp;lt;tex&amp;gt;2^n\left(1-\dfrac1{r+1}\right)^k&amp;lt;/tex&amp;gt; строк. Оценим &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;2^n\left(1-\dfrac1{r+1}\right)^k \simeq 1&amp;lt;/tex&amp;gt;. Отсюда &amp;lt;tex&amp;gt;k=O(rn)&amp;lt;/tex&amp;gt; (это можно получить, выразив &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; через &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; и воспользовавшись [[Формула Тейлора для произвольной функции | формулой Тейлора]] для логарифма). &lt;br /&gt;
&lt;br /&gt;
Таким образом, мы можем разрешить язык &amp;lt;tex&amp;gt;\mathrm{LSAT}&amp;lt;/tex&amp;gt; за полиномиальное время, найдя лексикографически минимальную строку, удовлетворяющую формуле, и сравнив её с нашим аргументом. Так как &amp;lt;tex&amp;gt;\mathrm{LSAT}\in \mathrm{NPC}&amp;lt;/tex&amp;gt;, то мы можем решить любую задачу из &amp;lt;tex&amp;gt;\mathrm{NP}&amp;lt;/tex&amp;gt; за полиномиальное время, а значит &amp;lt;tex&amp;gt;\mathrm{P}=\mathrm{NP}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Класс P]]&lt;br /&gt;
*[[Классы NP и Σ₁]]&lt;br /&gt;
*[[Сведение относительно класса функций. Сведение по Карпу. Трудные и полные задачи]]&lt;br /&gt;
*[[Теорема Бермана — Форчуна]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [http://blog.computationalcomplexity.org/2011/09/mahaneys-theorem.html Блог Computational Complexity]&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Sparse_language Wikipedia — Sparse language]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория сложности]]&lt;br /&gt;
[[Категория: Детерминированные и недетерминированные вычисления, сложность по времени и по памяти]]&lt;br /&gt;
[[Категория: Классы P и NP, NP-полнота]]&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D0%B5%D0%BE%D1%80%D0%B5%D0%BC%D0%B0_%D0%9C%D0%B0%D1%85%D1%8D%D0%BD%D0%B8&amp;diff=53044</id>
		<title>Теорема Махэни</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D0%B5%D0%BE%D1%80%D0%B5%D0%BC%D0%B0_%D0%9C%D0%B0%D1%85%D1%8D%D0%BD%D0%B8&amp;diff=53044"/>
				<updated>2016-04-05T13:52:05Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Теорема Махэни, доказанная Стефаном Махэни в 1982 году, утверждает, что если хотя бы один [[#Sparse|редкий язык]] {{---}} [[Сведение_относительно_класса_функций._Сведение_по_Карпу._Трудные_и_полные_задачи#.D0.9E.D0.BF.D1.80.D0.B5.D0.B4.D0.B5.D0.BB.D0.B5.D0.BD.D0.B8.D1.8F_.D1.82.D1.80.D1.83.D0.B4.D0.BD.D1.8B.D1.85_.D0.B8_.D0.BF.D0.BE.D0.BB.D0.BD.D1.8B.D1.85_.D0.B7.D0.B0.D0.B4.D0.B0.D1.87 | &amp;lt;tex&amp;gt; \mathrm{NP} &amp;lt;/tex&amp;gt;-полный ]], то &amp;lt;tex&amp;gt; \mathrm{P} = \mathrm{NP} &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Подготовка к доказательству==&lt;br /&gt;
&lt;br /&gt;
Введём вспомогательный язык &amp;lt;tex&amp;gt;\mathrm{LSAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{LSAT} = \{\langle \varphi, y \rangle \mid \exists x: x \leqslant_{lex} y, \varphi(x) = 1\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt; \varphi &amp;lt;/tex&amp;gt; {{---}} [[Определение_булевой_функции | булева формула]] из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; переменных, &amp;lt;tex&amp;gt;x, y \in \{0,1\}^{n} &amp;lt;/tex&amp;gt; и отношение &amp;lt;tex&amp;gt; \leqslant_{lex} &amp;lt;/tex&amp;gt; задает [[Лексикографический порядок | лексикографический порядок]].&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|about=1&lt;br /&gt;
|statement=&amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPC}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
#Очевидно, что &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NP}&amp;lt;/tex&amp;gt; (в качестве [[Классы_NP,_coNP,_Σ₁,_Π₁#.D0.9E.D0.BF.D1.80.D0.B5.D0.B4.D0.B5.D0.BB.D0.B5.D0.BD.D0.B8.D1.8F.2C_.D1.81.D0.B2.D1.8F.D0.B7.D1.8C_.CE.A3.E2.82.81_.D0.B8_NP|сертификата]] можно запросить &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;).&lt;br /&gt;
#[[Сведение относительно класса функций. Сведение по Карпу. Трудные и полные задачи | Сведём]] &amp;lt;tex&amp;gt;\mathrm{SAT}&amp;lt;/tex&amp;gt; к &amp;lt;tex&amp;gt;\mathrm{LSAT}&amp;lt;/tex&amp;gt;. Для этого рассмотрим отображение &amp;lt;tex&amp;gt;\varphi \mapsto \langle \varphi, 1^{|\varphi|}\rangle&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;|\varphi|&amp;lt;/tex&amp;gt; — количество различных переменных в формуле &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt;. Ясно, что данное преобразование можно сделать за полиномиальное время. Теперь докажем, что сведение верное. &lt;br /&gt;
#*Если &amp;lt;tex&amp;gt;\varphi \in \mathrm{SAT}&amp;lt;/tex&amp;gt;, то формула &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt; удовлетворима, а значит &amp;lt;tex&amp;gt;\exists x: x \leqslant_{lex} 1^{|\varphi|}, \varphi(x)=1&amp;lt;/tex&amp;gt;. Такой &amp;lt;tex&amp;gt; x &amp;lt;/tex&amp;gt; cуществует, потому что формула удовлетворима и любой вектор длины &amp;lt;tex&amp;gt; |\varphi| &amp;lt;/tex&amp;gt; меньше либо равен единичному, значит мы переберем всевозможые вектора. Следовательно, &amp;lt;tex&amp;gt;\langle \varphi, 1^{|\varphi|}\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
#*Если &amp;lt;tex&amp;gt;\langle \varphi, 1^{|\varphi|}\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\exists x: x \leqslant_{lex} 1^{|\varphi|}, \varphi(x)=1&amp;lt;/tex&amp;gt;. Значит формула &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt; удовлетворима, и &amp;lt;tex&amp;gt;\varphi \in \mathrm{SAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
:Таким образом, &amp;lt;tex&amp;gt;\mathrm{SAT} \leqslant \mathrm{LSAT}&amp;lt;/tex&amp;gt;. Но [[Теорема Кука | по теореме Кука ]]&amp;lt;tex&amp;gt;\mathrm{SAT} \in \mathrm{NPC}&amp;lt;/tex&amp;gt;, а значит для любого &amp;lt;tex&amp;gt;L \in \mathrm{NP} &amp;lt;/tex&amp;gt; выполнено &amp;lt;tex&amp;gt; L \leqslant \mathrm{SAT}&amp;lt;/tex&amp;gt;. Тогда в силу транзитивности &amp;lt;tex&amp;gt;\forall L \in \mathrm{NP} \; L \leqslant \mathrm{LSAT}&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPH}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Итого, мы доказали, что &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPH}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NP}&amp;lt;/tex&amp;gt;. Тогда по определению &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPC}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=&amp;lt;tex&amp;gt;\langle\varphi,y\rangle \in \mathrm{LSAT}, y&amp;lt;_{lex}z&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;\langle\varphi,z\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&amp;lt;tex&amp;gt;\langle\varphi,y\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;\exists x: x\leqslant_{lex}y, \varphi(x) = 1&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;y&amp;lt;_{lex}z&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\exists x: x&amp;lt;_{lex}z, \varphi(x) = 1&amp;lt;/tex&amp;gt;, следовательно &amp;lt;tex&amp;gt;\langle\varphi,z\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Редкие языки==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|id = Sparse&lt;br /&gt;
|definition=&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{SPARSE}=\{L \mid \exists&amp;lt;/tex&amp;gt; полином &amp;lt;tex&amp;gt; p: \forall n \, |L \cap \Sigma^n| \leqslant p(n)\}&amp;lt;/tex&amp;gt; {{---}} множество '''редких''' (англ. ''sparse'') языков.&lt;br /&gt;
}}&lt;br /&gt;
То есть множество языков таких, что множество слов длины &amp;lt;tex&amp;gt; n &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; n &amp;lt;/tex&amp;gt; всего &amp;lt;tex&amp;gt; 2^{n} &amp;lt;/tex&amp;gt;, и если язык содержит только полином от этого числа, то при большом &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; эта часть стремится к нулю.&lt;br /&gt;
&lt;br /&gt;
'''Пример:''' Согласно [https://en.wikipedia.org/wiki/Church%E2%80%93Turing_thesis тезису Чёрча - Тьюринга], существует биекция между машинами Тьюринга и программами. Зафиксировав алфавит, можно занумеровать программы (программа будет иметь номер &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, если ее код {{---}} &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-е слово среди всех слов над алфавитом, отсортированных сначала по возрастанию длины, а при равной длине - в лексикографическом порядке), а следовательно и машины Тьюринга. Рассмотрим язык &amp;lt;tex&amp;gt; \{1^{n} \mid n&amp;lt;/tex&amp;gt;-я [[Машина Тьюринга | машина Тьюринга]] останавливается в допускающем состоянии &amp;lt;tex&amp;gt; \} &amp;lt;/tex&amp;gt;. Просто приняв &amp;lt;tex&amp;gt; p(n) = 1 &amp;lt;/tex&amp;gt;, получим, что он принадлежит &amp;lt;tex&amp;gt; \mathrm{SPARSE}&amp;lt;/tex&amp;gt;. Более того, любой унарный язык принадлежит &amp;lt;tex&amp;gt;\mathrm{SPARSE} &amp;lt;/tex&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
==Теорема==&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|author=Махэни&lt;br /&gt;
|statement=&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{NPC} \cap \mathrm{SPARSE} \ne \varnothing \Rightarrow \mathrm{P}=\mathrm{NP}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=Пусть &amp;lt;tex&amp;gt;S \in \mathrm{NPC} \cap \mathrm{SPARSE}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;S\in \mathrm{NPC}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPC}&amp;lt;/tex&amp;gt;, то существует полиномиальная функция сведения &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; такая, что &amp;lt;tex&amp;gt;\langle \varphi, y \rangle \in \mathrm{LSAT} \Leftrightarrow f(\langle \varphi, y \rangle) \in S&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как функция &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; работает полиномиальное время, и &amp;lt;tex&amp;gt;|\varphi|\geqslant|y|&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;|y|&amp;lt;/tex&amp;gt; — длина вектора &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;), то &amp;lt;tex&amp;gt;f(\langle\varphi,y\rangle) \leqslant q(|\varphi|)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; — полином.&lt;br /&gt;
&amp;lt;tex&amp;gt;S\in \mathrm{SPARSE}&amp;lt;/tex&amp;gt;, следовательно &amp;lt;tex&amp;gt;\forall n \; |S \cap \Sigma^n|\leqslant p(n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; — некоторый полином. &lt;br /&gt;
&lt;br /&gt;
Тогда &amp;lt;tex&amp;gt;|\{x\in S \mid |x| \leqslant q(|\varphi|)\}| \leqslant \displaystyle\sum\limits_{i=1}^{q(|\varphi|)} p(i) = r(|\varphi|)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; — также полином.&lt;br /&gt;
&lt;br /&gt;
Опишем алгоритм для нахождения лексикографически минимальной строки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, удовлетворяющей формуле &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;n=|\varphi|, r=r(|\varphi|)&amp;lt;/tex&amp;gt;. Изначально область поиска для &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; — все строки длины &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. Опишем одну итерацию поиска.&lt;br /&gt;
&lt;br /&gt;
Разобьём текущее множество строк на &amp;lt;tex&amp;gt;r+1&amp;lt;/tex&amp;gt; подотрезок примерно равной длины. Обозначим концы полученных подотрезков &amp;lt;tex&amp;gt;w_0, \ldots ,w_{r+1}&amp;lt;/tex&amp;gt;. Пусть теперь &amp;lt;tex&amp;gt;z_i=f(\langle\varphi,w_i\rangle)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Из леммы (2) мы знаем, что, начиная с некоторого &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, все пары &amp;lt;tex&amp;gt;\langle\varphi, w_l\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;. Тогда по сведению &amp;lt;tex&amp;gt;z_j \in S&amp;lt;/tex&amp;gt; для всех &amp;lt;tex&amp;gt;j\geqslant l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим два случая:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tex&amp;gt;\exists i \ne j : z_i=z_j&amp;lt;/tex&amp;gt;. Строки &amp;lt;tex&amp;gt;z_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;z_j&amp;lt;/tex&amp;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;x\notin (w_i, w_j]&amp;lt;/tex&amp;gt;. Значит мы можем исключить этот полуинтервал из рассматриваемого множества. Таким образом, мы удаляем не менее &amp;lt;tex&amp;gt;\dfrac 1{r+1}&amp;lt;/tex&amp;gt; часть множества подстановок.&lt;br /&gt;
# &amp;lt;tex&amp;gt;z_i \ne z_j \, \forall i \ne j&amp;lt;/tex&amp;gt;. Как было показано выше, если &amp;lt;tex&amp;gt;x \in [w_0, w_1]&amp;lt;/tex&amp;gt;, то все &amp;lt;tex&amp;gt;z_i&amp;lt;/tex&amp;gt;, начиная с &amp;lt;tex&amp;gt;z_1&amp;lt;/tex&amp;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;r+1&amp;lt;/tex&amp;gt; строку длины не более, чем &amp;lt;tex&amp;gt;q(|\varphi|)&amp;lt;/tex&amp;gt;, что противоречит условию &amp;lt;tex&amp;gt;|\{x\in S \mid |x| \leqslant q(|\varphi|)\}| \leqslant r(|\varphi|)&amp;lt;/tex&amp;gt;. Следовательно, &amp;lt;tex&amp;gt;x\notin[w_0,w_1]&amp;lt;/tex&amp;gt;, то есть его можно убрать из рассмотрения.&lt;br /&gt;
&lt;br /&gt;
В обоих случаях мы сузили область поиска как минимум на &amp;lt;tex&amp;gt;\dfrac 1{r+1}&amp;lt;/tex&amp;gt; её размера. &lt;br /&gt;
&lt;br /&gt;
Будем повторять эту процедуру до тех пор, пока не останется не более &amp;lt;tex&amp;gt;r+1&amp;lt;/tex&amp;gt; строки, которые мы можем проверить за полиномиальное время. Если какая-то из них удовлетворила формуле &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;x=\min(w_i), w_i&amp;lt;/tex&amp;gt; удовлетворяет &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt;. Иначе, &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; не существует.&lt;br /&gt;
&lt;br /&gt;
Оценим время работы нашего алгоритма. После &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; итераций у нас останется не более &amp;lt;tex&amp;gt;2^n\left(1-\dfrac1{r+1}\right)^k&amp;lt;/tex&amp;gt; строк. Оценим &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;2^n\left(1-\dfrac1{r+1}\right)^k \simeq 1&amp;lt;/tex&amp;gt;. Отсюда &amp;lt;tex&amp;gt;k=O(rn)&amp;lt;/tex&amp;gt; (это можно получить, выразив &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; через &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; и воспользовавшись [[Формула Тейлора для произвольной функции | формулой Тейлора]] для логарифма). &lt;br /&gt;
&lt;br /&gt;
Таким образом, мы можем разрешить язык &amp;lt;tex&amp;gt;\mathrm{LSAT}&amp;lt;/tex&amp;gt; за полиномиальное время, найдя лексикографически минимальную строку, удовлетворяющую формуле, и сравнив её с нашим аргументом. Так как &amp;lt;tex&amp;gt;\mathrm{LSAT}\in \mathrm{NPC}&amp;lt;/tex&amp;gt;, то мы можем решить любую задачу из &amp;lt;tex&amp;gt;\mathrm{NP}&amp;lt;/tex&amp;gt; за полиномиальное время, а значит &amp;lt;tex&amp;gt;\mathrm{P}=\mathrm{NP}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Класс P]]&lt;br /&gt;
*[[Классы NP и Σ₁]]&lt;br /&gt;
*[[Сведение относительно класса функций. Сведение по Карпу. Трудные и полные задачи]]&lt;br /&gt;
*[[Теорема Бермана — Форчуна]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [http://blog.computationalcomplexity.org/2011/09/mahaneys-theorem.html Блог Computational Complexity]&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Sparse_language Wikipedia — Sparse language]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория сложности]]&lt;br /&gt;
[[Категория: Детерминированные и недетерминированные вычисления, сложность по времени и по памяти]]&lt;br /&gt;
[[Категория: Классы P и NP, NP-полнота]]&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D0%B5%D0%BE%D1%80%D0%B5%D0%BC%D0%B0_%D0%9C%D0%B0%D1%85%D1%8D%D0%BD%D0%B8&amp;diff=53020</id>
		<title>Теорема Махэни</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D0%B5%D0%BE%D1%80%D0%B5%D0%BC%D0%B0_%D0%9C%D0%B0%D1%85%D1%8D%D0%BD%D0%B8&amp;diff=53020"/>
				<updated>2016-04-04T09:36:10Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Теорема Махэни, доказанная Стефаном Махэни в 1982 году, утверждает, что если хотя бы один [[#Sparse|редкий язык]] {{---}} &amp;lt;tex&amp;gt; \mathrm{NP} &amp;lt;/tex&amp;gt;-полный, то &amp;lt;tex&amp;gt; \mathrm{P} = \mathrm{NP} &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Подготовка к доказательству==&lt;br /&gt;
&lt;br /&gt;
Введём вспомогательный язык &amp;lt;tex&amp;gt;\mathrm{LSAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{LSAT} = \{\langle \varphi, y \rangle \mid \exists x: x \leqslant_{lex} y, \varphi(x) = 1\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt; \varphi &amp;lt;/tex&amp;gt; {{---}} булева формула из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; переменных, &amp;lt;tex&amp;gt;x, y \in \{0,1\}^{n} &amp;lt;/tex&amp;gt; и отношение &amp;lt;tex&amp;gt; \leqslant_{lex} &amp;lt;/tex&amp;gt; задает [[Лексикографический порядок | лексикографический порядок]].&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|about=1&lt;br /&gt;
|statement=&amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPC}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
#Очевидно, что &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NP}&amp;lt;/tex&amp;gt; (в качестве [[Классы NP, coNP, Σ₁, Π₁|сертификата]] можно запросить &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;).&lt;br /&gt;
#[[Сведение относительно класса функций. Сведение по Карпу. Трудные и полные задачи | Сведём]] &amp;lt;tex&amp;gt;\mathrm{SAT}&amp;lt;/tex&amp;gt; к &amp;lt;tex&amp;gt;\mathrm{LSAT}&amp;lt;/tex&amp;gt;. Для этого рассмотрим отображение &amp;lt;tex&amp;gt;\varphi \mapsto \langle \varphi, 1^{|\varphi|}\rangle&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;|\varphi|&amp;lt;/tex&amp;gt; — количество различных переменных в формуле &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt;. Ясно, что данное преобразование можно сделать за полиномиальное время. Теперь докажем, что сведение верное. &lt;br /&gt;
#*Если &amp;lt;tex&amp;gt;\varphi \in \mathrm{SAT}&amp;lt;/tex&amp;gt;, то формула &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt; удовлетворима, а значит &amp;lt;tex&amp;gt;\exists x: x \leqslant_{lex} 1^{|\varphi|}, \varphi(x)=1&amp;lt;/tex&amp;gt;. Такой &amp;lt;tex&amp;gt; x &amp;lt;/tex&amp;gt; cуществует, потому что формула удовлетворима и любой вектор длины &amp;lt;tex&amp;gt; |\varphi| &amp;lt;/tex&amp;gt; меньше либо равен единичному, значит мы переберем всевозможые вектора. Следовательно, &amp;lt;tex&amp;gt;\langle \varphi, 1^{|\varphi|}\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
#*Если &amp;lt;tex&amp;gt;\langle \varphi, 1^{|\varphi|}\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\exists x: x \leqslant_{lex} 1^{|\varphi|}, \varphi(x)=1&amp;lt;/tex&amp;gt;. Значит формула &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt; удовлетворима, и &amp;lt;tex&amp;gt;\varphi \in \mathrm{SAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
:Таким образом, &amp;lt;tex&amp;gt;\mathrm{SAT} \leqslant \mathrm{LSAT}&amp;lt;/tex&amp;gt;. Но [[Теорема Кука | по теореме Кука ]]&amp;lt;tex&amp;gt;\mathrm{SAT} \in \mathrm{NPC}&amp;lt;/tex&amp;gt;, а значит для любого &amp;lt;tex&amp;gt;L \in \mathrm{NP} &amp;lt;/tex&amp;gt; выполнено &amp;lt;tex&amp;gt; L \leqslant \mathrm{SAT}&amp;lt;/tex&amp;gt;. Тогда в силу транзитивности &amp;lt;tex&amp;gt;\forall L \in \mathrm{NP} \; L \leqslant \mathrm{LSAT}&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPH}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Итого, мы доказали, что &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPH}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NP}&amp;lt;/tex&amp;gt;. Тогда по определению &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPC}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=&amp;lt;tex&amp;gt;\langle\varphi,y\rangle \in \mathrm{LSAT}, y&amp;lt;_{lex}z&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;\langle\varphi,z\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&amp;lt;tex&amp;gt;\langle\varphi,y\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;\exists x: x\leqslant_{lex}y, \varphi(x) = 1&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;y&amp;lt;_{lex}z&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\exists x: x&amp;lt;_{lex}z, \varphi(x) = 1&amp;lt;/tex&amp;gt;, следовательно &amp;lt;tex&amp;gt;\langle\varphi,z\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Редкие языки==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|id = Sparse&lt;br /&gt;
|definition=&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{SPARSE}=\{L \mid \exists&amp;lt;/tex&amp;gt; полином &amp;lt;tex&amp;gt; p: \forall n \, |L \cap \Sigma^n| \leqslant p(n)\}&amp;lt;/tex&amp;gt; {{---}} множество '''редких''' (англ. ''sparse'') языков.&lt;br /&gt;
}}&lt;br /&gt;
То есть множество языков таких, что множество слов длины &amp;lt;tex&amp;gt; n &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; n &amp;lt;/tex&amp;gt; всего &amp;lt;tex&amp;gt; 2^{n} &amp;lt;/tex&amp;gt;, и если язык содержит только полином от этого числа, то при большом &amp;lt;tex&amp;gt; n &amp;lt;/tex&amp;gt; эта часть стремится к нулю.&lt;br /&gt;
&lt;br /&gt;
'''Пример:''' Согласно [https://en.wikipedia.org/wiki/Church%E2%80%93Turing_thesis тезису Чёрча - Тьюринга], существует биекция между машинами Тьюринга и программами. Зафиксировав язык, можно занумеровать программы, а следовательно и машины Тьюринга. &amp;lt;tex&amp;gt; \{1^{n} \mid n&amp;lt;/tex&amp;gt;-я [[Машина Тьюринга | машина Тьюринга]] останавливается в допускающем состоянии &amp;lt;tex&amp;gt; \} \in \mathrm{SPARSE}&amp;lt;/tex&amp;gt;. Более того, любой унарный язык принадлежит &amp;lt;tex&amp;gt;\mathrm{SPARSE} &amp;lt;/tex&amp;gt; (просто принять &amp;lt;tex&amp;gt; p(n) = 1 &amp;lt;/tex&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==Теорема==&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|author=Махэни&lt;br /&gt;
|statement=&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{NPC} \cap \mathrm{SPARSE} \ne \varnothing \Rightarrow \mathrm{P}=\mathrm{NP}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=Пусть &amp;lt;tex&amp;gt;S \in \mathrm{NPC} \cap \mathrm{SPARSE}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;S\in \mathrm{NPC}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPC}&amp;lt;/tex&amp;gt;, то существует полиномиальная функция сведения &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; такая, что &amp;lt;tex&amp;gt;\langle \varphi, y \rangle \in \mathrm{LSAT} \Leftrightarrow f(\langle \varphi, y \rangle) \in S&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как функция &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; работает полиномиальное время, и &amp;lt;tex&amp;gt;|\varphi|\geqslant|y|&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;|y|&amp;lt;/tex&amp;gt; — длина вектора &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;), то &amp;lt;tex&amp;gt;f(\langle\varphi,y\rangle) \leqslant q(|\phi|)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; — полином.&lt;br /&gt;
&amp;lt;tex&amp;gt;S\in \mathrm{SPARSE}&amp;lt;/tex&amp;gt;, следовательно &amp;lt;tex&amp;gt;\forall n \; |S \cap \Sigma^n|\leqslant p(n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; — некоторый полином. &lt;br /&gt;
&lt;br /&gt;
Тогда &amp;lt;tex&amp;gt;|\{x\in S \mid |x| \leqslant q(|\varphi|)\}| \leqslant \displaystyle\sum\limits_{i=1}^{q(|\varphi|)} p(i) = r(|\phi|)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; — также полином.&lt;br /&gt;
&lt;br /&gt;
Опишем алгоритм для нахождения лексикографически минимальной строки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, удовлетворяющей формуле &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;n=|\varphi|, r=r(|\varphi|)&amp;lt;/tex&amp;gt;. Изначально область поиска для &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; — все строки длины &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. Опишем одну итерацию поиска.&lt;br /&gt;
&lt;br /&gt;
Разобьём текущее множество строк на &amp;lt;tex&amp;gt;r+1&amp;lt;/tex&amp;gt; подотрезок примерно равной длины. Обозначим концы полученных подотрезков &amp;lt;tex&amp;gt;w_0,...,w_{r+1}&amp;lt;/tex&amp;gt;. Пусть теперь &amp;lt;tex&amp;gt;z_i=f(\langle\varphi,w_i\rangle)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Из леммы (2) мы знаем, что, начиная с некоторого &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, все пары &amp;lt;tex&amp;gt;\langle\varphi, w_l\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;. Тогда по сведению &amp;lt;tex&amp;gt;z_j \in S&amp;lt;/tex&amp;gt; для всех &amp;lt;tex&amp;gt;j\geqslant l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим два случая:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tex&amp;gt;\exists i \ne j : z_i=z_j&amp;lt;/tex&amp;gt;. Строки &amp;lt;tex&amp;gt;z_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;z_j&amp;lt;/tex&amp;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;x\notin (w_i, w_j]&amp;lt;/tex&amp;gt;. Значит мы можем исключить этот полуинтервал из рассматриваемого множества. Таким образом, мы удаляем не менее &amp;lt;tex&amp;gt;\dfrac 1{r+1}&amp;lt;/tex&amp;gt; часть множества подстановок.&lt;br /&gt;
# &amp;lt;tex&amp;gt;z_i \ne z_j \, \forall i \ne j&amp;lt;/tex&amp;gt;. Как было показано выше, если &amp;lt;tex&amp;gt;x \in [w_0, w_1]&amp;lt;/tex&amp;gt;, то все &amp;lt;tex&amp;gt;z_i&amp;lt;/tex&amp;gt;, начиная с &amp;lt;tex&amp;gt;z_1&amp;lt;/tex&amp;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;r+1&amp;lt;/tex&amp;gt; строку длины не более, чем &amp;lt;tex&amp;gt;q(|\varphi|)&amp;lt;/tex&amp;gt;, что противоречит условию &amp;lt;tex&amp;gt;|\{x\in S \mid |x| \leqslant q(|\varphi|)\}| \leqslant r(|\varphi|)&amp;lt;/tex&amp;gt;. Следовательно, &amp;lt;tex&amp;gt;x\notin[w_0,w_1]&amp;lt;/tex&amp;gt;, то есть его можно убрать из рассмотрения.&lt;br /&gt;
&lt;br /&gt;
В обоих случаях мы сузили область поиска как минимум на &amp;lt;tex&amp;gt;\dfrac 1{r+1}&amp;lt;/tex&amp;gt; её размера. &lt;br /&gt;
&lt;br /&gt;
Будем повторять эту процедуру до тех пор, пока не останется не более &amp;lt;tex&amp;gt;r+1&amp;lt;/tex&amp;gt; строки, которые мы можем проверить за полиномиальное время. Если какая-то из них удовлетворила формуле &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;x=min(w_i), w_i&amp;lt;/tex&amp;gt; удовлетворяет &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt;. Иначе, &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; не существует.&lt;br /&gt;
&lt;br /&gt;
Оценим время работы нашего алгоритма. После &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; итераций у нас останется не более &amp;lt;tex&amp;gt;2^n\left(1-\dfrac1{r+1}\right)^k&amp;lt;/tex&amp;gt; строк. Оценим &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;2^n\left(1-\dfrac1{r+1}\right)^k \simeq 1&amp;lt;/tex&amp;gt;. Отсюда &amp;lt;tex&amp;gt;k=O(rn)&amp;lt;/tex&amp;gt; (это можно получить, выразив &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; через &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; и воспользовавшись [[Формула Тейлора для произвольной функции | формулой Тейлора]] для логарифма). &lt;br /&gt;
&lt;br /&gt;
Таким образом, мы можем разрешить язык &amp;lt;tex&amp;gt;\mathrm{LSAT}&amp;lt;/tex&amp;gt; за полиномиальное время, найдя лексикографически минимальную строку, удовлетворяющую формуле, и сравнив её с нашим аргументом. Так как &amp;lt;tex&amp;gt;\mathrm{LSAT}\in \mathrm{NPC}&amp;lt;/tex&amp;gt;, то мы можем решить любую задачу из &amp;lt;tex&amp;gt;\mathrm{NP}&amp;lt;/tex&amp;gt; за полиномиальное время, а значит &amp;lt;tex&amp;gt;\mathrm{P}=\mathrm{NP}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Класс P]]&lt;br /&gt;
*[[Классы NP и Σ₁]]&lt;br /&gt;
*[[Сведение относительно класса функций. Сведение по Карпу. Трудные и полные задачи]]&lt;br /&gt;
*[[Теорема Бермана — Форчуна]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [http://blog.computationalcomplexity.org/2011/09/mahaneys-theorem.html Блог Computational Complexity]&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Sparse_language Wikipedia — Sparse language]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория сложности]]&lt;br /&gt;
[[Категория: Детерминированные и недетерминированные вычисления, сложность по времени и по памяти]]&lt;br /&gt;
[[Категория: Классы P и NP, NP-полнота]]&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%B5%D0%BC%D0%BC%D0%B0_%D0%BE_%D0%BF%D0%B0%D1%80%D0%BE%D1%81%D0%BE%D1%87%D0%B5%D1%82%D0%B0%D0%BD%D0%B8%D0%B8_%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%B5_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD&amp;diff=53019</id>
		<title>Лемма о паросочетании в графе замен</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%B5%D0%BC%D0%BC%D0%B0_%D0%BE_%D0%BF%D0%B0%D1%80%D0%BE%D1%81%D0%BE%D1%87%D0%B5%D1%82%D0%B0%D0%BD%D0%B8%D0%B8_%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%B5_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD&amp;diff=53019"/>
				<updated>2016-04-04T06:52:45Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Лемма&lt;br /&gt;
|about=&lt;br /&gt;
о паросочетании в графе замен&lt;br /&gt;
|statement= Пусть &amp;lt;tex&amp;gt;M = \langle X,I \rangle &amp;lt;/tex&amp;gt; &amp;amp;mdash;  матроид. Множества &amp;lt;tex&amp;gt;A, B \in I&amp;lt;/tex&amp;gt;, причем &amp;lt;tex&amp;gt;|A| = |B|&amp;lt;/tex&amp;gt;. Тогда двудольный граф &amp;lt;tex&amp;gt;G_M(A) = \{ (x, y) | x \in A, y \notin A, A \setminus x \cup y \in I \}&amp;lt;/tex&amp;gt; содержит полное паросочетание на &amp;lt;tex&amp;gt;A \bigtriangleup B&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof= &lt;br /&gt;
&lt;br /&gt;
Индукция по &amp;lt;tex&amp;gt;|A \bigtriangleup B|&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
* База &lt;br /&gt;
*: В случае, когда &amp;lt;tex&amp;gt;A \bigtriangleup B = \emptyset &amp;lt;/tex&amp;gt;, есть пустое паросочетание. &lt;br /&gt;
* Переход&lt;br /&gt;
*: Рассмотрим матроид &amp;lt;tex&amp;gt;M_1 = \langle X, \{ K | K \in I, |K| \leq |A| \} \rangle&amp;lt;/tex&amp;gt;. Множества &amp;lt;tex&amp;gt;A, B \in I&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;|A| = |B|&amp;lt;/tex&amp;gt;, а значит они являются базами для матроида &amp;lt;tex&amp;gt;M_1&amp;lt;/tex&amp;gt;. Тогда по [[Теорема о базах|теореме о базах]] &amp;lt;tex&amp;gt;\forall x \in A \setminus B: \exists y \in B \setminus A : A \setminus x \cup y \in I&amp;lt;/tex&amp;gt;, поэтому &amp;lt;tex&amp;gt;(x, y) \in G_M(A)&amp;lt;/tex&amp;gt;. Множества &amp;lt;tex&amp;gt;A \setminus x &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;B \setminus y&amp;lt;/tex&amp;gt; являются независимыми как подмножества независимых и их &amp;lt;tex&amp;gt;\bigtriangleup&amp;lt;/tex&amp;gt; имеет меньшую мощность, чем &amp;lt;tex&amp;gt;|A \bigtriangleup B|&amp;lt;/tex&amp;gt;. Тогда по предположению индукции на их &amp;lt;tex&amp;gt;\bigtriangleup&amp;lt;/tex&amp;gt; есть полное паросочетание, которое вместе с &amp;lt;tex&amp;gt;(x, y)&amp;lt;/tex&amp;gt; составляет полное паросочетание на &amp;lt;tex&amp;gt;A \bigtriangleup B&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;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%B5%D0%BC%D0%BC%D0%B0_%D0%BE_%D0%BF%D0%B0%D1%80%D0%BE%D1%81%D0%BE%D1%87%D0%B5%D1%82%D0%B0%D0%BD%D0%B8%D0%B8_%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%B5_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD&amp;diff=53018</id>
		<title>Лемма о паросочетании в графе замен</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%B5%D0%BC%D0%BC%D0%B0_%D0%BE_%D0%BF%D0%B0%D1%80%D0%BE%D1%81%D0%BE%D1%87%D0%B5%D1%82%D0%B0%D0%BD%D0%B8%D0%B8_%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%B5_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD&amp;diff=53018"/>
				<updated>2016-04-04T06:22:57Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Лемма&lt;br /&gt;
|about=&lt;br /&gt;
о паросочетании в графе замен&lt;br /&gt;
|statement= Пусть &amp;lt;tex&amp;gt;M = \langle X,I \rangle &amp;lt;/tex&amp;gt; &amp;amp;mdash;  матроид. Множества &amp;lt;tex&amp;gt;A, B \in I&amp;lt;/tex&amp;gt;, причем &amp;lt;tex&amp;gt;|A| = |B|&amp;lt;/tex&amp;gt;. Тогда двудольный граф &amp;lt;tex&amp;gt;G_M(A) = \{ (x, y) | x \in A, y \notin A, A \setminus x \cup y \in I \}&amp;lt;/tex&amp;gt; содержит полное паросочетание на &amp;lt;tex&amp;gt;A \bigtriangleup B&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof= Индукция по &amp;lt;tex&amp;gt;|A \bigtriangleup B|&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt; 1)База индукции очевидна. В случае, когда &amp;lt;tex&amp;gt;A \bigtriangleup B = \emptyset &amp;lt;/tex&amp;gt;, есть пустое паросочетание. &amp;lt;br&amp;gt; 2)Покажем, что справедлив и индукционный переход. Рассмотрим матроид &amp;lt;tex&amp;gt;M_1 = \langle X, \{ K | K \in I, |K| \leq |A| \} \rangle&amp;lt;/tex&amp;gt;. Множества &amp;lt;tex&amp;gt;A, B \in I&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;|A| = |B|&amp;lt;/tex&amp;gt;, а значит они являются базами для матроида &amp;lt;tex&amp;gt;M_1&amp;lt;/tex&amp;gt;. Тогда по [[Теорема о базах|теореме о базах]] &amp;lt;tex&amp;gt;\forall x \in A \setminus B: \exists y \in B \setminus A : A \setminus x \cup y \in I&amp;lt;/tex&amp;gt;, поэтому &amp;lt;tex&amp;gt;(x, y) \in G_M(A)&amp;lt;/tex&amp;gt;. Множества &amp;lt;tex&amp;gt;A \setminus x &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;B \setminus y&amp;lt;/tex&amp;gt; являются независимыми как подмножества независимых и их &amp;lt;tex&amp;gt;\bigtriangleup&amp;lt;/tex&amp;gt; имеет меньшую мощность, чем &amp;lt;tex&amp;gt;|A \bigtriangleup B|&amp;lt;/tex&amp;gt;. Тогда по предположению индукции на их &amp;lt;tex&amp;gt;\bigtriangleup&amp;lt;/tex&amp;gt; есть полное паросочетание, которое вместе с &amp;lt;tex&amp;gt;(x, y)&amp;lt;/tex&amp;gt; составляет полное паросочетание на &amp;lt;tex&amp;gt;A \bigtriangleup B&amp;lt;/tex&amp;gt;, а значит индукционный переход справедлив.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Категория:Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория:Матроиды]]&lt;br /&gt;
[[Категория:Пересечение матроидов]]&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%B5%D0%BC%D0%BC%D0%B0_%D0%BE_%D0%BF%D0%B0%D1%80%D0%BE%D1%81%D0%BE%D1%87%D0%B5%D1%82%D0%B0%D0%BD%D0%B8%D0%B8_%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%B5_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD&amp;diff=53017</id>
		<title>Лемма о паросочетании в графе замен</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9B%D0%B5%D0%BC%D0%BC%D0%B0_%D0%BE_%D0%BF%D0%B0%D1%80%D0%BE%D1%81%D0%BE%D1%87%D0%B5%D1%82%D0%B0%D0%BD%D0%B8%D0%B8_%D0%B2_%D0%B3%D1%80%D0%B0%D1%84%D0%B5_%D0%B7%D0%B0%D0%BC%D0%B5%D0%BD&amp;diff=53017"/>
				<updated>2016-04-04T06:20:21Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Лемма&lt;br /&gt;
|about=&lt;br /&gt;
о паросочетании в графе замен&lt;br /&gt;
|statement= Пусть &amp;lt;tex&amp;gt;M = \langle X,I \rangle &amp;lt;/tex&amp;gt; &amp;amp;mdash;  матроид. Множества &amp;lt;tex&amp;gt;A, B \in I&amp;lt;/tex&amp;gt;, причем &amp;lt;tex&amp;gt;|A| = |B|&amp;lt;/tex&amp;gt;. Тогда двудольный граф &amp;lt;tex&amp;gt;G_M(A) = \{ (x, y) | x \in A, y \notin A, A \setminus x \cup y \in I \}&amp;lt;/tex&amp;gt; содержит полное паросочетание на &amp;lt;tex&amp;gt;A \bigtriangleup B&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof= Индукция по &amp;lt;tex&amp;gt;|A \oplus B|&amp;lt;/tex&amp;gt;.&amp;lt;br&amp;gt; 1)База индукции очевидна. В случае, когда &amp;lt;tex&amp;gt;A \oplus B = \emptyset &amp;lt;/tex&amp;gt;, есть пустое паросочетание. &amp;lt;br&amp;gt; 2)Покажем, что справедлив и индукционный переход. Рассмотрим матроид &amp;lt;tex&amp;gt;M_1 = \langle X, \{ K | K \in I, |K| \leq |A| \} \rangle&amp;lt;/tex&amp;gt;. Множества &amp;lt;tex&amp;gt;A, B \in I&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;|A| = |B|&amp;lt;/tex&amp;gt;, а значит они являются базами для матроида &amp;lt;tex&amp;gt;M_1&amp;lt;/tex&amp;gt;. Тогда по [[Теорема о базах|теореме о базах]] &amp;lt;tex&amp;gt;\forall x \in A \setminus B: \exists y \in B \setminus A : A \setminus x \cup y \in I&amp;lt;/tex&amp;gt;, поэтому &amp;lt;tex&amp;gt;(x, y) \in G_M(A)&amp;lt;/tex&amp;gt;. Множества &amp;lt;tex&amp;gt;A \setminus x &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;B \setminus y&amp;lt;/tex&amp;gt; являются независимыми как подмножества независимых и их &amp;lt;tex&amp;gt;\oplus&amp;lt;/tex&amp;gt; имеет меньшую мощность, чем &amp;lt;tex&amp;gt;|A \oplus B|&amp;lt;/tex&amp;gt;. Тогда по предположению индукции на их &amp;lt;tex&amp;gt;\oplus&amp;lt;/tex&amp;gt; есть полное паросочетание, которое вместе с &amp;lt;tex&amp;gt;(x, y)&amp;lt;/tex&amp;gt; составляет полное паросочетание на &amp;lt;tex&amp;gt;A \oplus B&amp;lt;/tex&amp;gt;, а значит индукционный переход справедлив.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Категория:Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория:Матроиды]]&lt;br /&gt;
[[Категория:Пересечение матроидов]]&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D0%B5%D0%BE%D1%80%D0%B5%D0%BC%D0%B0_%D0%9C%D0%B0%D1%85%D1%8D%D0%BD%D0%B8&amp;diff=53007</id>
		<title>Теорема Махэни</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D0%B5%D0%BE%D1%80%D0%B5%D0%BC%D0%B0_%D0%9C%D0%B0%D1%85%D1%8D%D0%BD%D0%B8&amp;diff=53007"/>
				<updated>2016-04-01T21:26:16Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Теорема Махэни, доказанная Стефаном Махэни в 1982 году, утверждает, что если хотя бы один [[#Sparse|редкий язык]] {{---}} &amp;lt;tex&amp;gt; \mathrm{NP} &amp;lt;/tex&amp;gt;-полный, то &amp;lt;tex&amp;gt; \mathrm{P} = \mathrm{NP} &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Подготовка к доказательству==&lt;br /&gt;
&lt;br /&gt;
Введём вспомогательный язык &amp;lt;tex&amp;gt;\mathrm{LSAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{LSAT} = \{\langle \varphi, y \rangle \mid \exists x: x \leqslant_{lex} y, \varphi(x) = 1\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt; \varphi &amp;lt;/tex&amp;gt; {{---}} булева формула из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; переменных, &amp;lt;tex&amp;gt;x, y \in \{0,1\}^{n} &amp;lt;/tex&amp;gt; и отношение &amp;lt;tex&amp;gt; \leqslant_{lex} &amp;lt;/tex&amp;gt; задает [[Лексикографический порядок | лексикографический порядок]].&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|about=1&lt;br /&gt;
|statement=&amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPC}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
#Очевидно, что &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NP}&amp;lt;/tex&amp;gt; (в качестве сертификата можно запросить &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;).&lt;br /&gt;
#[[Сведение относительно класса функций. Сведение по Карпу. Трудные и полные задачи | Сведём]] &amp;lt;tex&amp;gt;\mathrm{SAT}&amp;lt;/tex&amp;gt; к &amp;lt;tex&amp;gt;\mathrm{LSAT}&amp;lt;/tex&amp;gt;. Для этого рассмотрим отображение &amp;lt;tex&amp;gt;\varphi \mapsto \langle \varphi, 1^{|\varphi|}\rangle&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;|\varphi|&amp;lt;/tex&amp;gt; — количество различных переменных в формуле &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt;. Ясно, что данное преобразование можно сделать за полиномиальное время. Теперь докажем, что сведение верное. &lt;br /&gt;
#*Если &amp;lt;tex&amp;gt;\varphi \in \mathrm{SAT}&amp;lt;/tex&amp;gt;, то формула &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt; удовлетворима, а значит &amp;lt;tex&amp;gt;\exists x: x \leqslant_{lex} 1^{|\varphi|}, \varphi(x)=1&amp;lt;/tex&amp;gt;. Следовательно, &amp;lt;tex&amp;gt;\langle \varphi, 1^{|\varphi|}\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
#*Если &amp;lt;tex&amp;gt;\langle \varphi, 1^{|\varphi|}\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\exists x: x \leqslant_{lex} 1^{|\varphi|}, \varphi(x)=1&amp;lt;/tex&amp;gt;. Значит формула &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt; удовлетворима, и &amp;lt;tex&amp;gt;\varphi \in \mathrm{SAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
:Таким образом, &amp;lt;tex&amp;gt;\mathrm{SAT} \leqslant \mathrm{LSAT}&amp;lt;/tex&amp;gt;. Но [[Теорема Кука | по теореме Кука ]]&amp;lt;tex&amp;gt;\mathrm{SAT} \in \mathrm{NPC}&amp;lt;/tex&amp;gt;, а значит для любого &amp;lt;tex&amp;gt;L \in \mathrm{NP} &amp;lt;/tex&amp;gt; выполнено &amp;lt;tex&amp;gt; L \leqslant \mathrm{SAT}&amp;lt;/tex&amp;gt;. Тогда в силу транзитивности &amp;lt;tex&amp;gt;\forall L \in \mathrm{NP} \; L \leqslant \mathrm{LSAT}&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPH}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Итого, мы доказали, что &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPH}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NP}&amp;lt;/tex&amp;gt;. Тогда по определению &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPC}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=&amp;lt;tex&amp;gt;\langle\varphi,y\rangle \in \mathrm{LSAT}, y&amp;lt;_{lex}z&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;\langle\varphi,z\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&amp;lt;tex&amp;gt;\langle\varphi,y\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;\exists x: x\leqslant_{lex}y, \varphi(x) = 1&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;y&amp;lt;_{lex}z&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\exists x: x&amp;lt;_{lex}z, \varphi(x) = 1&amp;lt;/tex&amp;gt;, следовательно &amp;lt;tex&amp;gt;\langle\varphi,z\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Редкие языки==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|id = Sparse&lt;br /&gt;
|definition=&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{SPARSE}=\{L \mid \exists&amp;lt;/tex&amp;gt; полином &amp;lt;tex&amp;gt; p: \forall n \, |L \cap \Sigma^n| \leqslant p(n)\}&amp;lt;/tex&amp;gt; {{---}} множество '''редких''' (англ. ''sparse'') языков.&lt;br /&gt;
}}&lt;br /&gt;
То есть множество языков таких, что множество слов длины &amp;lt;tex&amp;gt; n &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; n &amp;lt;/tex&amp;gt; всего &amp;lt;tex&amp;gt; 2^{n} &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; \{1^{n} \mid n&amp;lt;/tex&amp;gt;-я [[Машина Тьюринга | машина Тьюринга]] останавливается на &amp;lt;tex&amp;gt; Y \} \in \mathrm{SPARSE}&amp;lt;/tex&amp;gt;. Более того, любой унарный язык принадлежит &amp;lt;tex&amp;gt;\mathrm{SPARSE} &amp;lt;/tex&amp;gt; (просто принять &amp;lt;tex&amp;gt; p(n) = 1 &amp;lt;/tex&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==Теорема==&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|author=Махэни&lt;br /&gt;
|statement=&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{NPC} \cap \mathrm{SPARSE} \ne \varnothing \Rightarrow \mathrm{P}=\mathrm{NP}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=Пусть &amp;lt;tex&amp;gt;S \in \mathrm{NPC} \cap \mathrm{SPARSE}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;S\in \mathrm{NPC}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPC}&amp;lt;/tex&amp;gt;, то существует полиномиальная функция сведения &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; такая, что &amp;lt;tex&amp;gt;\langle \varphi, y \rangle \in \mathrm{LSAT} \Leftrightarrow f(\langle \varphi, y \rangle) \in S&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как функция &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; работает полиномиальное время, и &amp;lt;tex&amp;gt;|\varphi|\geqslant|y|&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;|y|&amp;lt;/tex&amp;gt; — длина вектора &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;), то &amp;lt;tex&amp;gt;f(\langle\varphi,y\rangle) \leqslant q(|\phi|)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; — полином.&lt;br /&gt;
&amp;lt;tex&amp;gt;S\in \mathrm{SPARSE}&amp;lt;/tex&amp;gt;, следовательно &amp;lt;tex&amp;gt;\forall n \; |S \cap \Sigma^n|\leqslant p(n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; — некоторый полином. &lt;br /&gt;
&lt;br /&gt;
Тогда &amp;lt;tex&amp;gt;|\{x\in S \mid |x| \leqslant q(|\varphi|)\}| \leqslant \displaystyle\sum\limits_{i=1}^{q(|\varphi|)} p(i) = r(|\phi|)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; — также полином.&lt;br /&gt;
&lt;br /&gt;
Опишем алгоритм для нахождения лексикографически минимальной строки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, удовлетворяющей формуле &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;n=|\varphi|, r=r(|\varphi|)&amp;lt;/tex&amp;gt;. Изначально область поиска для &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; — все строки длины &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. Опишем одну итерацию поиска.&lt;br /&gt;
&lt;br /&gt;
Разобьём текущее множество строк на &amp;lt;tex&amp;gt;r+1&amp;lt;/tex&amp;gt; подотрезок примерно равной длины. Обозначим концы полученных подотрезков &amp;lt;tex&amp;gt;w_0,...,w_{r+1}&amp;lt;/tex&amp;gt;. Пусть теперь &amp;lt;tex&amp;gt;z_i=f(\langle\varphi,w_i\rangle)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Из леммы (2) мы знаем, что, начиная с некоторого &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, все пары &amp;lt;tex&amp;gt;\langle\varphi, w_l\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;. Тогда по сведению &amp;lt;tex&amp;gt;z_j \in S&amp;lt;/tex&amp;gt; для всех &amp;lt;tex&amp;gt;j\geqslant l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим два случая:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tex&amp;gt;\exists i \ne j : z_i=z_j&amp;lt;/tex&amp;gt;. Строки &amp;lt;tex&amp;gt;z_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;z_j&amp;lt;/tex&amp;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;x\notin (w_i, w_j]&amp;lt;/tex&amp;gt;. Значит мы можем исключить этот полуинтервал из рассматриваемого множества. Таким образом, мы удаляем не менее &amp;lt;tex&amp;gt;\dfrac 1{r+1}&amp;lt;/tex&amp;gt; часть множества подстановок.&lt;br /&gt;
# &amp;lt;tex&amp;gt;z_i \ne z_j \, \forall i \ne j&amp;lt;/tex&amp;gt;. Как было показано выше, если &amp;lt;tex&amp;gt;x \in [w_0, w_1]&amp;lt;/tex&amp;gt;, то все &amp;lt;tex&amp;gt;z_i&amp;lt;/tex&amp;gt;, начиная с &amp;lt;tex&amp;gt;z_1&amp;lt;/tex&amp;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;r+1&amp;lt;/tex&amp;gt; строку длины не более, чем &amp;lt;tex&amp;gt;q(|\varphi|)&amp;lt;/tex&amp;gt;, что противоречит условию &amp;lt;tex&amp;gt;|\{x\in S \mid |x| \leqslant q(|\varphi|)\}| \leqslant r(|\varphi|)&amp;lt;/tex&amp;gt;. Следовательно, &amp;lt;tex&amp;gt;x\notin[w_0,w_1]&amp;lt;/tex&amp;gt;, то есть его можно убрать из рассмотрения.&lt;br /&gt;
&lt;br /&gt;
В обоих случаях мы сузили область поиска как минимум на &amp;lt;tex&amp;gt;\dfrac 1{r+1}&amp;lt;/tex&amp;gt; её размера. &lt;br /&gt;
&lt;br /&gt;
Будем повторять эту процедуру до тех пор, пока не останется не более &amp;lt;tex&amp;gt;r+1&amp;lt;/tex&amp;gt; строки, которые мы можем проверить за полиномиальное время. Если какая-то из них удовлетворила формуле &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;x=min(w_i), w_i&amp;lt;/tex&amp;gt; удовлетворяет &amp;lt;tex&amp;gt;\varphi&amp;lt;/tex&amp;gt;. Иначе, &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; не существует.&lt;br /&gt;
&lt;br /&gt;
Оценим время работы нашего алгоритма. После &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; итераций у нас останется не более &amp;lt;tex&amp;gt;2^n\left(1-\dfrac1{r+1}\right)^k&amp;lt;/tex&amp;gt; строк. Оценим &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;2^n\left(1-\dfrac1{r+1}\right)^k \simeq 1&amp;lt;/tex&amp;gt;. Отсюда &amp;lt;tex&amp;gt;k=O(rn)&amp;lt;/tex&amp;gt; (это можно получить, выразив &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; через &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; и воспользовавшись [[Формула Тейлора для произвольной функции | формулой Тейлора]] для логарифма). &lt;br /&gt;
&lt;br /&gt;
Таким образом, мы можем разрешить язык &amp;lt;tex&amp;gt;\mathrm{LSAT}&amp;lt;/tex&amp;gt; за полиномиальное время, найдя лексикографически минимальную строку, удовлетворяющую формуле, и сравнив её с нашим аргументом. Так как &amp;lt;tex&amp;gt;\mathrm{LSAT}\in \mathrm{NPC}&amp;lt;/tex&amp;gt;, то мы можем решить любую задачу из &amp;lt;tex&amp;gt;\mathrm{NP}&amp;lt;/tex&amp;gt; за полиномиальное время, а значит &amp;lt;tex&amp;gt;\mathrm{P}=\mathrm{NP}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Класс P]]&lt;br /&gt;
*[[Классы NP и Σ₁]]&lt;br /&gt;
*[[Сведение относительно класса функций. Сведение по Карпу. Трудные и полные задачи]]&lt;br /&gt;
*[[Теорема Бермана — Форчуна]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [http://blog.computationalcomplexity.org/2011/09/mahaneys-theorem.html Блог Computational Complexity]&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Sparse_language Wikipedia — Sparse language]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория сложности]]&lt;br /&gt;
[[Категория: Детерминированные и недетерминированные вычисления, сложность по времени и по памяти]]&lt;br /&gt;
[[Категория: Классы P и NP, NP-полнота]]&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D0%B5%D0%BE%D1%80%D0%B5%D0%BC%D0%B0_%D0%9C%D0%B0%D1%85%D1%8D%D0%BD%D0%B8&amp;diff=52905</id>
		<title>Теорема Махэни</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D0%B5%D0%BE%D1%80%D0%B5%D0%BC%D0%B0_%D0%9C%D0%B0%D1%85%D1%8D%D0%BD%D0%B8&amp;diff=52905"/>
				<updated>2016-03-27T12:15:54Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Введём вспомогательный язык &amp;lt;tex&amp;gt;\mathrm{LSAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{LSAT} = \{\langle \phi, y \rangle \mid \exists x: x \leqslant_{lex} y, \phi(x) = 1\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt; \phi &amp;lt;/tex&amp;gt; {{---}} булева формула из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; переменных, &amp;lt;tex&amp;gt;x, y \in \{0,1\}^{n} &amp;lt;/tex&amp;gt; и отношение &amp;lt;tex&amp;gt; \leqslant_{lex} &amp;lt;/tex&amp;gt; задает [[Лексикографический порядок | лексикографический порядок]].&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|about=1&lt;br /&gt;
|statement=&amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPC}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&lt;br /&gt;
#Очевидно, что &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NP}&amp;lt;/tex&amp;gt; (в качестве сертификата можно запросить &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;).&lt;br /&gt;
#[[Сведение относительно класса функций. Сведение по Карпу. Трудные и полные задачи | Сведём]] &amp;lt;tex&amp;gt;\mathrm{SAT}&amp;lt;/tex&amp;gt; к &amp;lt;tex&amp;gt;\mathrm{LSAT}&amp;lt;/tex&amp;gt;. Для этого рассмотрим отображение &amp;lt;tex&amp;gt;\phi \mapsto \langle \phi, 1^{|\phi|}\rangle&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;|\phi|&amp;lt;/tex&amp;gt; — количество различных переменных в формуле &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt;. Ясно, что данное преобразование можно сделать за полиномиальное время. Теперь докажем, что сведение верное. &lt;br /&gt;
#*Если &amp;lt;tex&amp;gt;\phi \in \mathrm{SAT}&amp;lt;/tex&amp;gt;, то формула &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; удовлетворима, а значит &amp;lt;tex&amp;gt;\exists x: x \leqslant_{lex} 1^{|\phi|}, \phi(x)=1&amp;lt;/tex&amp;gt;. Следовательно, &amp;lt;tex&amp;gt;\langle \phi, 1^{|\phi|}\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
#*Если &amp;lt;tex&amp;gt;\langle \phi, 1^{|\phi|}\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\exists x: x \leqslant_{lex} 1^{|\phi|}, \phi(x)=1&amp;lt;/tex&amp;gt;. Значит формула &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; удовлетворима, и &amp;lt;tex&amp;gt;\phi \in \mathrm{SAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
:Таким образом, &amp;lt;tex&amp;gt;\mathrm{SAT} \leqslant \mathrm{LSAT}&amp;lt;/tex&amp;gt;. Но [[Теорема Кука | по теореме Кука ]]&amp;lt;tex&amp;gt;\mathrm{SAT} \in \mathrm{NPC}&amp;lt;/tex&amp;gt;, а значит &amp;lt;tex&amp;gt;\forall L \in \mathrm{NP} \; L \leqslant \mathrm{SAT}&amp;lt;/tex&amp;gt;. Тогда в силу транзитивности &amp;lt;tex&amp;gt;\forall L \in \mathrm{NP} \; L \leqslant \mathrm{LSAT}&amp;lt;/tex&amp;gt;, то есть &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPH}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Итого мы доказали, что &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPH}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NP}&amp;lt;/tex&amp;gt;. Тогда по определению &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPC}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=&amp;lt;tex&amp;gt;\langle\phi,y\rangle \in \mathrm{LSAT}, y&amp;lt;_{lex}z&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;\langle\phi,z\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=&amp;lt;tex&amp;gt;\langle\phi,y\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;\exists x: x\leqslant_{lex}y, \phi(x) = 1&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;y&amp;lt;_{lex}z&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;\exists x: x&amp;lt;_{lex}z, \phi(x) = 1&amp;lt;/tex&amp;gt;, следовательно &amp;lt;tex&amp;gt;\langle\phi,z\rangle \in \mathrm{LSAT}&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;\mathrm{SPARSE}=\{L \mid \exists&amp;lt;/tex&amp;gt; полином &amp;lt;tex&amp;gt; p: \forall n \, |L \cap \Sigma^n| \leqslant p(n)\}&amp;lt;/tex&amp;gt; {{---}} множество редких (англ. ''sparse'') языков.&lt;br /&gt;
}}&lt;br /&gt;
То есть множество языков таких, что множество слов длины &amp;lt;tex&amp;gt; n &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; \{1^{n} \mid n&amp;lt;/tex&amp;gt;-я [[Машина Тьюринга | машина Тьюринга]] останавливается на &amp;lt;tex&amp;gt; Y \} \in \mathrm{SPARSE}&amp;lt;/tex&amp;gt;. Более того, любой [https://en.wikipedia.org/wiki/Unary_language унарный язык] принадлежит &amp;lt;tex&amp;gt;\mathrm{SPARSE} &amp;lt;/tex&amp;gt; (просто принять &amp;lt;tex&amp;gt; p(n) = 1 &amp;lt;/tex&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|author=Махэни&lt;br /&gt;
|statement=&lt;br /&gt;
&amp;lt;tex&amp;gt;\mathrm{NPC} \cap \mathrm{SPARSE} \ne \varnothing \Rightarrow \mathrm{P}=\mathrm{NP}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
|proof=Пусть &amp;lt;tex&amp;gt;S \in \mathrm{NPC} \cap \mathrm{SPARSE}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как &amp;lt;tex&amp;gt;S\in \mathrm{NPC}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\mathrm{LSAT} \in \mathrm{NPC}&amp;lt;/tex&amp;gt;, то существует полиномиальная функция сведения &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; такая, что &amp;lt;tex&amp;gt;\langle \phi, y \rangle \in \mathrm{LSAT} \Leftrightarrow f(\langle \phi, y \rangle) \in S&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как функция &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; работает полиномиальное время, и &amp;lt;tex&amp;gt;|\phi|\geqslant|y|&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;|y|&amp;lt;/tex&amp;gt; — длина вектора &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;), то &amp;lt;tex&amp;gt;f(\langle\phi,y\rangle) \leqslant q(|\phi|)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt; — полином.&lt;br /&gt;
&amp;lt;tex&amp;gt;S\in \mathrm{SPARSE}&amp;lt;/tex&amp;gt;, следовательно &amp;lt;tex&amp;gt;\forall n \; |S \cap \Sigma^n|\leqslant p(n)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; — некоторый полином. &lt;br /&gt;
&lt;br /&gt;
Тогда &amp;lt;tex&amp;gt;|\{x\in S \mid |x| \leqslant q(|\phi|)\}| \leqslant \displaystyle\sum\limits_{i=1}^{q(|\phi|)} p(i) = r(|\phi|)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; — также полином.&lt;br /&gt;
&lt;br /&gt;
Опишем алгоритм для нахождения лексикографически минимальной строки &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, удовлетворяющей формуле &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;n=|\phi|, r=r(|\phi|)&amp;lt;/tex&amp;gt;. Изначально область поиска для &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; — все строки длины &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. Опишем одну итерацию поиска.&lt;br /&gt;
&lt;br /&gt;
Разобьём текущее множество строк на &amp;lt;tex&amp;gt;r+1&amp;lt;/tex&amp;gt; подотрезок примерно равной длины. Обозначим концы полученных подотрезков &amp;lt;tex&amp;gt;w_0,...,w_{r+1}&amp;lt;/tex&amp;gt;. Пусть теперь &amp;lt;tex&amp;gt;z_i=f(\langle\phi,w_i\rangle)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Из леммы (2) мы знаем, что, начиная с некоторого &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, все пары &amp;lt;tex&amp;gt;\langle\phi, w_l\rangle \in \mathrm{LSAT}&amp;lt;/tex&amp;gt;. Тогда по сведению &amp;lt;tex&amp;gt;z_j \in S&amp;lt;/tex&amp;gt; для всех &amp;lt;tex&amp;gt;j\geqslant l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим два случая:&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;tex&amp;gt;\exists i \ne j : z_i=z_j&amp;lt;/tex&amp;gt;. Строки &amp;lt;tex&amp;gt;z_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;z_j&amp;lt;/tex&amp;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;x\notin (w_i, w_j]&amp;lt;/tex&amp;gt;. Значит мы можем исключить этот полуинтервал из рассматриваемого множества. Таким образом, мы удаляем не менее &amp;lt;tex&amp;gt;\dfrac 1{r+1}&amp;lt;/tex&amp;gt; часть множества подстановок.&lt;br /&gt;
# &amp;lt;tex&amp;gt;z_i \ne z_j \, \forall i \ne j&amp;lt;/tex&amp;gt;. Как было показано выше, если &amp;lt;tex&amp;gt;x \in [w_0, w_1]&amp;lt;/tex&amp;gt;, то все &amp;lt;tex&amp;gt;z_i&amp;lt;/tex&amp;gt;, начиная с &amp;lt;tex&amp;gt;z_1&amp;lt;/tex&amp;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;r+1&amp;lt;/tex&amp;gt; строку длины не более, чем &amp;lt;tex&amp;gt;q(|\phi|)&amp;lt;/tex&amp;gt;, что противоречит условию &amp;lt;tex&amp;gt;|\{x\in S \mid |x| \leqslant q(|\phi|)\}| \leqslant r(|\phi|)&amp;lt;/tex&amp;gt;. Следовательно, &amp;lt;tex&amp;gt;x\notin[w_0,w_1]&amp;lt;/tex&amp;gt;, то есть его можно убрать из рассмотрения.&lt;br /&gt;
&lt;br /&gt;
В обоих случаях мы сузили область поиска как минимум на &amp;lt;tex&amp;gt;\dfrac 1{r+1}&amp;lt;/tex&amp;gt; её размера. &lt;br /&gt;
&lt;br /&gt;
Будем повторять эту процедуру до тех пор, пока не останется не более &amp;lt;tex&amp;gt;r+1&amp;lt;/tex&amp;gt; строки, которые мы можем проверить за полиномиальное время. Если какая-то из них удовлетворила формуле &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt;, то &amp;lt;tex&amp;gt;x=min(w_i), w_i&amp;lt;/tex&amp;gt; удовлетворяет &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt;. Иначе, &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; не существует.&lt;br /&gt;
&lt;br /&gt;
Оценим время работы нашего алгоритма. После &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; итераций у нас останется не более &amp;lt;tex&amp;gt;2^n\left(1-\dfrac1{r+1}\right)^k&amp;lt;/tex&amp;gt; строк. Оценим &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;2^n\left(1-\dfrac1{r+1}\right)^k \simeq 1&amp;lt;/tex&amp;gt;. Отсюда &amp;lt;tex&amp;gt;k=O(rn)&amp;lt;/tex&amp;gt; (это можно получить, выразив &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; через &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; и воспользовавшись [http://ru.wikipedia.org/wiki/Ряд_Тейлора#.D0.A0.D1.8F.D0.B4.D1.8B_.D0.9C.D0.B0.D0.BA.D0.BB.D0.BE.D1.80.D0.B5.D0.BD.D0.B0_.D0.BD.D0.B5.D0.BA.D0.BE.D1.82.D0.BE.D1.80.D1.8B.D1.85_.D1.84.D1.83.D0.BD.D0.BA.D1.86.D0.B8.D0.B9 формулой Тейлора] для логарифма). &lt;br /&gt;
&lt;br /&gt;
Таким образом, мы можем разрешить язык &amp;lt;tex&amp;gt;\mathrm{LSAT}&amp;lt;/tex&amp;gt; за полиномиальное время, найдя лексикографически минимальную строку, удовлетворяющую формуле, и сравнив её с нашим аргументом. Так как &amp;lt;tex&amp;gt;\mathrm{LSAT}\in \mathrm{NPC}&amp;lt;/tex&amp;gt;, то мы можем решить любую задачу из &amp;lt;tex&amp;gt;\mathrm{NP}&amp;lt;/tex&amp;gt; за полиномиальное время, а значит &amp;lt;tex&amp;gt;\mathrm{P}=\mathrm{NP}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
*[[Класс P]]&lt;br /&gt;
*[[Классы NP и Σ₁]]&lt;br /&gt;
*[[Сведение относительно класса функций. Сведение по Карпу. Трудные и полные задачи]]&lt;br /&gt;
*[[Теорема Бермана — Форчуна]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* [http://blog.computationalcomplexity.org/2011/09/mahaneys-theorem.html Блог Computational Complexity]&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Sparse_language Wikipedia — Sparse language]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Теория сложности]]&lt;br /&gt;
[[Категория: Детерминированные и недетерминированные вычисления, сложность по времени и по памяти]]&lt;br /&gt;
[[Категория: Классы P и NP, NP-полнота]]&lt;/div&gt;</summary>
		<author><name>188.227.78.59</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%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0&amp;diff=52904</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%A5%D0%B0%D1%84%D1%84%D0%BC%D0%B0%D0%BD%D0%B0&amp;diff=52904"/>
				<updated>2016-03-27T12:14:30Z</updated>
		
		<summary type="html">&lt;p&gt;188.227.78.59: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Алгоритм Хаффмана''' (англ. ''Huffman's algorithm'') — алгоритм [[Задача_об_оптимальном_префиксном_коде_с_сохранением_порядка._Монотонность_точки_разреза | оптимального префиксного кодирования]] алфавита. Был разработан в 1952 году аспирантом Массачусетского технологического института Дэвидом Хаффманом при написании им курсовой работы. Используется во многих программах сжатия данных, например, PKZIP 2, LZH и др.&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=\{a_{1},a_{2}, \ldots ,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; различных символов, &amp;lt;tex&amp;gt;W=\{w_{1},w_{2}, \ldots ,w_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор положительных целых весов. Тогда набор бинарных кодов &amp;lt;tex&amp;gt;C=\{c_{1},c_{2}, \ldots ,c_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;c_{i}&amp;lt;/tex&amp;gt; является кодом для символа &amp;lt;tex&amp;gt;a_{i}&amp;lt;/tex&amp;gt;, такой, что:&lt;br /&gt;
&lt;br /&gt;
:* &amp;lt;tex&amp;gt;c_{i}&amp;lt;/tex&amp;gt; не является префиксом для &amp;lt;tex&amp;gt;c_{j}&amp;lt;/tex&amp;gt;, при &amp;lt;tex&amp;gt;i \ne j&amp;lt;/tex&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
:* cумма &amp;lt;tex&amp;gt;\sum\limits_{i \in [1, n]} w_{i}\cdot |c_{i}|&amp;lt;/tex&amp;gt; минимальна (&amp;lt;tex&amp;gt;|c_{i}|&amp;lt;/tex&amp;gt; — длина кода &amp;lt;tex&amp;gt;c_{i}&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;
# Составим [[Список | список]] кодируемых символов, при этом будем рассматривать один символ как дерево, состоящее из одного элемента c весом, равным частоте появления символа в строке.&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;O(N \log N)&amp;lt;/tex&amp;gt;.Такую асимптотику можно [[Алгоритм_Хаффмана_за_O(n) |улучшить до &amp;lt;tex&amp;gt;O(N)&amp;lt;/tex&amp;gt;]], используя обычные массивы.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
&lt;br /&gt;
[[Файл:Huffman_abracadabra.jpg|400px|thumb|right|Дерево Хаффмана для слова &amp;lt;tex&amp;gt;abracadabra&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Закодируем слово &amp;lt;tex&amp;gt;abracadabra&amp;lt;/tex&amp;gt;. Тогда алфавит будет &amp;lt;tex&amp;gt;A= \{a, b, r, c, d\} &amp;lt;/tex&amp;gt;, а набор весов (частота появления символов алфавита в кодируемом слове) &amp;lt;tex&amp;gt;W=\{5, 2, 2, 1, 1\}&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
В дереве Хаффмана будет &amp;lt;tex&amp;gt;5&amp;lt;/tex&amp;gt; узлов:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел ||  a  ||  b  ||  r  ||  с  ||  d&lt;br /&gt;
|-&lt;br /&gt;
| Вес || 5 || 2 || 2 || 1 || 1&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;d&amp;lt;/tex&amp;gt;. Сформируем из них новый узел &amp;lt;tex&amp;gt;cd&amp;lt;/tex&amp;gt; весом &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; и добавим его к списку узлов:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || a || b || r || cd &lt;br /&gt;
|-&lt;br /&gt;
| Вес || 5 || 2 || 2 || 2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Затем опять объединим в один узел два минимальных по весу узла {{---}} &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;cd&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || a || rcd || b &lt;br /&gt;
|-&lt;br /&gt;
| Вес || 5 || 4 || 2 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Еще раз повторим эту же операцию, но для узлов &amp;lt;tex&amp;gt;rcd&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || brcd || a&lt;br /&gt;
|-&lt;br /&gt;
| Вес || 6 || 5 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
На последнем шаге объединим два узла {{---}} &amp;lt;tex&amp;gt;brcd&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || abrcd&lt;br /&gt;
|-&lt;br /&gt;
| Вес || 11&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Остался один узел, значит, мы пришли к корню дерева Хаффмана (смотри рисунок). Теперь для каждого символа выберем кодовое слово (бинарная последовательность, обозначающая путь по дереву к этому символу от корня):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || a || b || r || с || d&lt;br /&gt;
|-&lt;br /&gt;
| Код || 0 || 11 || 101 || 1000 || 1001&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Таким образом, закодированное слово &amp;lt;tex&amp;gt;abracadabra&amp;lt;/tex&amp;gt; будет выглядеть как &amp;lt;tex&amp;gt;01110101000010010111010&amp;lt;/tex&amp;gt;. Длина закодированного слова {{---}} &amp;lt;tex&amp;gt;23&amp;lt;/tex&amp;gt; бита. Стоит заметить, что если бы мы использовали алгоритм кодирования с одинаковой длиной всех кодовых слов, то закодированное слово заняло бы &amp;lt;tex&amp;gt;33&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;
|id=lemma1&lt;br /&gt;
|about=1&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; — алфавит, каждый символ &amp;lt;tex&amp;gt;c \in C&amp;lt;/tex&amp;gt; которого встречается с частотой &amp;lt;tex&amp;gt;f[c]&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&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;C&amp;lt;/tex&amp;gt; существует оптимальный префиксный код, кодовые слова символов &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; в котором имеют одинаковую максимальную длину и отличаются лишь последним битом. &lt;br /&gt;
|proof=&lt;br /&gt;
Возьмем дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, представляющее произвольный оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. Преобразуем его в дерево, представляющее другой оптимальный префиксный код, в котором символы &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&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;b&amp;lt;/tex&amp;gt; имеют общий родительский узел и находятся на максимальной глубине дерева &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;. Предположим, что &amp;lt;tex&amp;gt;f[a] \leqslant f[b]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[x] \leqslant f[y]&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;f[x]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[y]&amp;lt;/tex&amp;gt; — две наименьшие частоты, а &amp;lt;tex&amp;gt;f[a]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[b]&amp;lt;/tex&amp;gt; — две произвольные частоты, то выполняются отношения &amp;lt;tex&amp;gt;f[x] \leqslant f[a]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[y] \leqslant f[b]&amp;lt;/tex&amp;gt;. Пусть дерево &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; — дерево, полученное из &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; путем перестановки листьев &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;, а дерево &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; — дерево полученное из &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; перестановкой листьев &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;. Разность стоимостей деревьев &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; равна:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;B(T) - B(T') = \sum\limits_{c \in C} f(c)d_T(c) - \sum\limits_{c \in C} f(c)d_{T'}(c) = (f[a] - f[x])(d_T(a) - d_T(x)),&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
что больше либо равно &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;, так как величины &amp;lt;tex&amp;gt;f[a] - f[x]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;d_T(a) - d_T(x)&amp;lt;/tex&amp;gt; неотрицательны. Величина &amp;lt;tex&amp;gt;f[a] - f[x]&amp;lt;/tex&amp;gt; неотрицательна, потому что &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; — лист с минимальной частотой, а величина &amp;lt;tex&amp;gt;d_T(a) - d_T(x)&amp;lt;/tex&amp;gt; является неотрицательной, так как лист &amp;lt;tex&amp;gt;a&amp;lt;/tex&amp;gt; находится на максимальной глубине в дереве &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;. Точно так же перестановка листьев &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;b&amp;lt;/tex&amp;gt; не будет приводить к увеличению стоимости. Таким образом, разность &amp;lt;tex&amp;gt;B(T') - B(T'')&amp;lt;/tex&amp;gt; тоже будет неотрицательной.&lt;br /&gt;
&lt;br /&gt;
Таким образом, выполняется неравенство &amp;lt;tex&amp;gt;B(T'') \leqslant B(T)&amp;lt;/tex&amp;gt;. С другой стороны, &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; — оптимальное дерево, поэтому должно выполняться неравенство &amp;lt;tex&amp;gt;B(T) \leqslant B(T'')&amp;lt;/tex&amp;gt;. Отсюда следует, что &amp;lt;tex&amp;gt;B(T) = B(T'')&amp;lt;/tex&amp;gt;. Значит, &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; — дерево, представляющее оптимальный префиксный код, в котором символы &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; имеют одинаковую максимальную длину, что и доказывает лемму.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|id=lemma2&lt;br /&gt;
|about=2&lt;br /&gt;
|statement=Пусть дан алфавит &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, в котором для каждого символа &amp;lt;tex&amp;gt;c \in C&amp;lt;/tex&amp;gt; определены частоты &amp;lt;tex&amp;gt;f[c]&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; — два символа из алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; с минимальными частотами. Пусть &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt; — алфавит, полученный из алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; путем удаления символов &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; и добавления нового символа &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt;, так что &amp;lt;tex&amp;gt;C' = C \backslash \{ x, y \} \cup {z}&amp;lt;/tex&amp;gt;. По определению частоты &amp;lt;tex&amp;gt;f&amp;lt;/tex&amp;gt; в алфавите &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt; совпадают с частотами в алфавите &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;, за исключением частоты &amp;lt;tex&amp;gt;f[z] = f[x] + f[y]&amp;lt;/tex&amp;gt;. Пусть &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; — произвольное дерево, представляющее оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt; Тогда дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, полученное из дерева &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; путем замены листа &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; внутренним узлом с дочерними элементами &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;, представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. &lt;br /&gt;
|proof=&lt;br /&gt;
Сначала покажем, что стоимость &amp;lt;tex&amp;gt;B(T)&amp;lt;/tex&amp;gt; дерева &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; может быть выражена через стоимость &amp;lt;tex&amp;gt;B(T')&amp;lt;/tex&amp;gt; дерева &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt;. Для каждого символа &amp;lt;tex&amp;gt;c \in C \backslash \{x, y \}&amp;lt;/tex&amp;gt; верно &amp;lt;tex&amp;gt;d_T(C) = d_{T'}&amp;lt;/tex&amp;gt;, значит, &amp;lt;tex&amp;gt;f[c]d_T(c) = f[c]d_{T'}(c)&amp;lt;/tex&amp;gt;. Так как &amp;lt;tex&amp;gt;d_T(x) = d_T(y) = d_{T'} (z) + 1&amp;lt;/tex&amp;gt;, то&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f[x]d_T(x) + f[y]d_T(y) = (f[x] + f[y])(d_{T'}(z) + 1) = f[z]d_{T'}(z) + (f[x] + f[y])&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
из чего следует, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B(T) = B(T') + f[x] + f[y] &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
или&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B(T') = B(T) - f[x] - f[y] &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Докажем лемму от противного. Предположим, что дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; не представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;. Тогда существует дерево &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; такое, что &amp;lt;tex&amp;gt;B(T'') &amp;lt; B(T)&amp;lt;/tex&amp;gt;. Согласно лемме (1), элементы &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; можно считать дочерними элементами одного узла. Пусть дерево &amp;lt;tex&amp;gt;T'''&amp;lt;/tex&amp;gt; получено из дерева &amp;lt;tex&amp;gt;T''&amp;lt;/tex&amp;gt; заменой элементов &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; листом &amp;lt;tex&amp;gt;z&amp;lt;/tex&amp;gt; с частотой &amp;lt;tex&amp;gt;f[z] = f[x] + f[y]&amp;lt;/tex&amp;gt;. Тогда&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;B(T''') = B(T'') - f[x] - f[y] &amp;lt; B(T) - f[x] - f[y] = B(T')&amp;lt;/tex&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
что противоречит предположению о том, что дерево &amp;lt;tex&amp;gt;T'&amp;lt;/tex&amp;gt; представляет оптимальный префиксный код для алфавита &amp;lt;tex&amp;gt;C'&amp;lt;/tex&amp;gt;. Значит, наше предположение о том, что дерево &amp;lt;tex&amp;gt;T&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;
|id=th1&lt;br /&gt;
|statement=&lt;br /&gt;
Алгоритм Хаффмана дает оптимальный префиксный код. &lt;br /&gt;
|proof=&lt;br /&gt;
Справедливость теоремы непосредственно следует из лемм (1) и (2)&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-е изд. — М.: «Вильямс», 2007. — с. 459. — ISBN 5-8489-0857-4&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Huffman_coding Wikipedia — Huffman coding]&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/%C4%E2%EE%E8%F7%ED%EE%E5_%E4%E5%F0%E5%E2%EE Википедия — Бинарное дерево]&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/Префиксный_код Википедия — Префиксный код]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
&lt;br /&gt;
[[Категория:Алгоритмы сжатия]]&lt;/div&gt;</summary>
		<author><name>188.227.78.59</name></author>	</entry>

	</feed>