<?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=109.172.13.207&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=109.172.13.207&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/109.172.13.207"/>
		<updated>2026-07-06T20:34:30Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<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=18397</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=18397"/>
				<updated>2012-02-27T13:23:30Z</updated>
		
		<summary type="html">&lt;p&gt;109.172.13.207: Переделано доказательство первой леммы&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''''Алгоритм Хаффмана''''' — алгоритм оптимального префиксного кодирования алфавита. Это один из классических алгоритмов, известных с 60-х годов. Использует только частоту появления одинаковых байт в изображении. Сопоставляет символам входного потока, которые встречаются большее число раз, цепочку бит меньшей длины. И, напротив, встречающимся редко — цепочку большей длины.&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},...,a_{n}\}&amp;lt;/tex&amp;gt; — алфавит из n различных символов, &amp;lt;tex&amp;gt;W=\{w_{1},w_{2},...,w_{n}\}&amp;lt;/tex&amp;gt; — соответствующий ему набор положительных целых весов. Тогда набор бинарных кодов &amp;lt;tex&amp;gt;C=\{c_{1},c_{2},...,c_{n}\}&amp;lt;/tex&amp;gt;, такой, что:&lt;br /&gt;
&lt;br /&gt;
1. &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;
2. Сумма &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;
1. Составим список кодируемых символов, при этом будем рассматривать один символ как дерево, состоящее из одного элемента, весом, равным частоте появления символа в тексте.&lt;br /&gt;
&lt;br /&gt;
2. Из списка выберем два узла с наименьшим весом.&lt;br /&gt;
&lt;br /&gt;
3. Сформируем новый узел с весом, равным сумме весов выбранных узлов, и присоединим к нему два выбранных узла в качестве дочерних.&lt;br /&gt;
&lt;br /&gt;
4. Добавим к списку только что сформированный узел.&lt;br /&gt;
&lt;br /&gt;
5. Если в списке больше одного узла, то повторить пункты со второго по пятый.&lt;br /&gt;
&lt;br /&gt;
== Пример ==&lt;br /&gt;
&lt;br /&gt;
[[Файл:Mississippi.png|400px|thumb|right|Дерево Хаффмана для слова ''&amp;quot;Миссисипи&amp;quot;'']]&lt;br /&gt;
&lt;br /&gt;
Для примера возьмём слово ''&amp;quot;Миссисипи&amp;quot;''. Тогда алфавит будет &amp;lt;tex&amp;gt;A= \{&amp;lt;/tex&amp;gt; ''и, м, п, с'' &amp;lt;tex&amp;gt;\} &amp;lt;/tex&amp;gt;, а набор весов &amp;lt;tex&amp;gt;W=\{4, 1, 1, 3\}&amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || и || м || п || с&lt;br /&gt;
|-&lt;br /&gt;
| Вес || 4 || 1 || 1 || 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
По алгоритму возьмем два символа с наименьшей частотой - это ''м'' и ''п''. Сформируем из них новый узел ''мп'' весом 2 и добавим его к списку узлов:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || и || мп || с &lt;br /&gt;
|-&lt;br /&gt;
| Вес || 4 || 2 || 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Затем объединим в один узел узлы ''мп'' и ''c'':&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Узел || и || мпс &lt;br /&gt;
|-&lt;br /&gt;
| Вес || 4 || 5 &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
И, наконец, объединяем два узла ''и'' и ''мпс''. Итак, мы получили дерево Хаффмана и соответствующую ему таблицу кодов:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || и || м || п || с&lt;br /&gt;
|-&lt;br /&gt;
| Код || 0 || 100 || 101 || 11&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Таким образом, закодированное слово ''&amp;quot;миссисипи&amp;quot;'' будет выглядеть как ''&amp;quot;1000111101101010&amp;quot;''. Длина закодированного слова - 16 бит. Стоит заметить, что если бы мы использовали для кодирования каждого символа из четырёх по 2 бита, длина закодированного слова составила бы 18 бит.&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] \le f[b]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[x] \le 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] \le f[a]&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f[y] \le 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'') \le 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) \le 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=Сначала покажем, что стоимость &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 \le C \backslash \{x,y\}&amp;lt;/tex&amp;gt; выполняется соотношение &amp;lt;tex&amp;gt;d_T(C) = d_{T'}(c)&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;, получаем соотношение&amp;lt;br&amp;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;
&amp;lt;br&amp;gt;&lt;br /&gt;
из которого следует равенство &amp;lt;br&amp;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;. Тогда можно записать:&amp;lt;br&amp;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;,&amp;lt;br&amp;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;
* Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн Алгоритмы: построение и анализ — 2-е изд. — М.: «Вильямс», 2007. — с. 459. — ISBN 5-8489-0857-4&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы сжатия ]]&lt;/div&gt;</summary>
		<author><name>109.172.13.207</name></author>	</entry>

	</feed>