Алгоритм Хаффмана — различия между версиями
(Переделано доказательство первой леммы) |
(Переделано доказательство второй леммы) |
||
Строка 92: | Строка 92: | ||
|about=2 | |about=2 | ||
|statement=Пусть дан алфавит <tex>C</tex>, в котором для каждого символа <tex>c \in C</tex> определены частоты <tex>f[c]</tex>. Пусть <tex>x</tex> и <tex>y</tex> — два символа из алфавита <tex>C</tex> с минимальными частотами. Пусть <tex>C'</tex> — алфавит, полученный из алфавита <tex>C</tex> путем удаления символов <tex>x</tex> и <tex>y</tex> и добавления нового символа <tex>z</tex>, так что <tex>C' = C \backslash \{ x, y \} \cup {z}</tex>. По определению частоты <tex>f</tex> в алфавите <tex>C'</tex> совпадают с частотами в алфавите <tex>C</tex>, за исключением частоты <tex>f[z] = f[x] + f[y]</tex>. Пусть <tex>T'</tex> — произвольное дерево, представляющее оптимальный префиксный код для алфавита <tex>C'</tex> Тогда дерево <tex>T</tex>, полученное из дерева <tex>T'</tex> путем замены листа <tex>z</tex> внутренним узлом с дочерними элементами <tex>x</tex> и <tex>y</tex>, представляет оптимальный префиксный код для алфавита <tex>C</tex>. | |statement=Пусть дан алфавит <tex>C</tex>, в котором для каждого символа <tex>c \in C</tex> определены частоты <tex>f[c]</tex>. Пусть <tex>x</tex> и <tex>y</tex> — два символа из алфавита <tex>C</tex> с минимальными частотами. Пусть <tex>C'</tex> — алфавит, полученный из алфавита <tex>C</tex> путем удаления символов <tex>x</tex> и <tex>y</tex> и добавления нового символа <tex>z</tex>, так что <tex>C' = C \backslash \{ x, y \} \cup {z}</tex>. По определению частоты <tex>f</tex> в алфавите <tex>C'</tex> совпадают с частотами в алфавите <tex>C</tex>, за исключением частоты <tex>f[z] = f[x] + f[y]</tex>. Пусть <tex>T'</tex> — произвольное дерево, представляющее оптимальный префиксный код для алфавита <tex>C'</tex> Тогда дерево <tex>T</tex>, полученное из дерева <tex>T'</tex> путем замены листа <tex>z</tex> внутренним узлом с дочерними элементами <tex>x</tex> и <tex>y</tex>, представляет оптимальный префиксный код для алфавита <tex>C</tex>. | ||
− | |proof=Сначала покажем, что стоимость <tex>B(T)</tex> дерева <tex>T</tex> | + | |proof= |
− | <tex>f[x]d_T(x) + f[y] | + | Сначала покажем, что стоимость <tex>B(T)</tex> дерева <tex>T</tex> может быть выражена через стоимость <tex>B(T')</tex> дерева <tex>T'</tex>. Для каждого символа <tex>c \in C \backslash \{x, y \}</tex> верно <tex>d_T(C) = d_{T'}</tex>, значит, <tex>f[c]d_T(c) = f[c]d_{T'}(c)</tex>. Так как <tex>d_T(x) = d_T(y) = d_{T'} (z) + 1</tex>, то |
− | + | ||
− | из | + | <tex>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])</tex> |
+ | |||
+ | из чего следует, что | ||
+ | |||
<tex> B(T) = B(T') + f[x] + f[y] </tex> | <tex> B(T) = B(T') + f[x] + f[y] </tex> | ||
или | или | ||
− | <tex> B(T') = B(T) - f[x] - f[y] </tex>. | + | <tex> B(T') = B(T) - f[x] - f[y] </tex> |
+ | |||
+ | Докажем лемму от противного. Предположим, что дерево <tex>T</tex> не представляет оптимальный префиксный код для алфавита <tex>C</tex>. Тогда существует дерево <tex>T''</tex> такое, что <tex>B(T'') < B(T)</tex>. Согласно лемме (1), элементы <tex>x</tex> и <tex>y</tex> можно считать дочерними элементами одного узла. Пусть дерево <tex>T'''</tex> получено из дерева <tex>T''</tex> заменой элементов <tex>x</tex> и <tex>y</tex> листом <tex>z</tex> с частотой <tex>f[z] = f[x] + f[y]</tex>. Тогда | ||
+ | |||
+ | <tex>B(T''') = B(T'') - f[x] - f[y] < B(T) - f[x] - f[y] = B(T')</tex>, | ||
− | + | что противоречит предположению о том, что дерево <tex>T'</tex> представляет оптимальный префиксный код для алфавита <tex>C'</tex>. Значит, наше предположение о том, что дерево <tex>T</tex> не представляет оптимальный префиксный код для алфавита <tex>C</tex>, неверно, что и доказывает лемму. | |
− | |||
− | что противоречит предположению о том, что дерево <tex>T'</tex> представляет оптимальный префиксный код для алфавита <tex>C'</tex>. | ||
}} | }} | ||
Версия 20:02, 28 февраля 2012
Алгоритм Хаффмана — алгоритм оптимального префиксного кодирования алфавита. Это один из классических алгоритмов, известных с 60-х годов. Использует только частоту появления одинаковых байт в изображении. Сопоставляет символам входного потока, которые встречаются большее число раз, цепочку бит меньшей длины. И, напротив, встречающимся редко — цепочку большей длины.
Определение
Определение: |
Пусть 1. не является префиксом для , при2. Сумма называется кодом Хаффмана. минимальна. ( — длина кода ) | — алфавит из n различных символов, — соответствующий ему набор положительных целых весов. Тогда набор бинарных кодов , такой, что:
Алгоритм
Построение кода Хаффмана сводится к построению соответствующего бинарного дерева по следующему алгоритму:
1. Составим список кодируемых символов, при этом будем рассматривать один символ как дерево, состоящее из одного элемента, весом, равным частоте появления символа в тексте.
2. Из списка выберем два узла с наименьшим весом.
3. Сформируем новый узел с весом, равным сумме весов выбранных узлов, и присоединим к нему два выбранных узла в качестве дочерних.
4. Добавим к списку только что сформированный узел.
5. Если в списке больше одного узла, то повторить пункты со второго по пятый.
Пример
Для примера возьмём слово "Миссисипи". Тогда алфавит будет
и, м, п, с , а набор весов :Узел | и | м | п | с |
---|---|---|---|---|
Вес | 4 | 1 | 1 | 3 |
По алгоритму возьмем два символа с наименьшей частотой - это м и п. Сформируем из них новый узел мп весом 2 и добавим его к списку узлов:
Узел | и | мп | с |
---|---|---|---|
Вес | 4 | 2 | 3 |
Затем объединим в один узел узлы мп и c:
Узел | и | мпс |
---|---|---|
Вес | 4 | 5 |
И, наконец, объединяем два узла и и мпс. Итак, мы получили дерево Хаффмана и соответствующую ему таблицу кодов:
Символ | и | м | п | с |
---|---|---|---|---|
Код | 0 | 100 | 101 | 11 |
Таким образом, закодированное слово "миссисипи" будет выглядеть как "1000111101101010". Длина закодированного слова - 16 бит. Стоит заметить, что если бы мы использовали для кодирования каждого символа из четырёх по 2 бита, длина закодированного слова составила бы 18 бит.
Корректность алгоритма Хаффмана
Чтобы доказать корректность алгоритма Хаффмана, покажем, что в задаче о построении оптимального префиксного кода проявляются свойства жадного выбора и оптимальной подструктуры. В сформулированной ниже лемме показано соблюдение свойства жадного выбора.
Лемма (1): |
Пусть — алфавит, каждый символ которого встречается с частотой . Пусть и — два символа алфавита с самыми низкими частотами.
Тогда для алфавита существует оптимальный префиксный код, кодовые слова символов и в котором имеют одинаковую максимальную длину и отличаются лишь последним битом. |
Доказательство: |
Возьмем дерево , представляющее произвольный оптимальный префиксный код для алфавита . Преобразуем его в дерево, представляющее другой оптимальный префиксный код, в котором символы и - листья с общим родительским узлом, находящиеся на максимальной глубине.Пусть символы и имеют общий родительский узел и находятся на максимальной глубине дерева . Предположим, что и . Так как и - две наименьшие частоты, а и - две произвольные частоты, то выполняются отношения и . Пусть дерево - дерево, полученное из путем перестановки листьев и , а дерево - дерево полученное из перестановкой листьев и . Разность стоимостей деревьев и равна:
что больше либо равно Таким образом, выполняется неравенство , так как величины и неотрицательны. Величина неотрицательна, потому что - лист с минимальной частотой, а величина является неотрицательной, так как лист находится на максимальной глубине в дереве . Точно так же перестановка листьев и не будет приводить к увеличению стоимости. Таким образом, разность тоже будет неотрицательной. . С другой стороны, - оптимальное дерево, поэтому должно выполняться неравенство . Отсюда следует, что . Значит, - дерево, представляющее оптимальный префиксный код, в котором символы и имеют одинаковую максимальную длину, что и доказывает лемму. |
Лемма (2): |
Пусть дан алфавит , в котором для каждого символа определены частоты . Пусть и — два символа из алфавита с минимальными частотами. Пусть — алфавит, полученный из алфавита путем удаления символов и и добавления нового символа , так что . По определению частоты в алфавите совпадают с частотами в алфавите , за исключением частоты . Пусть — произвольное дерево, представляющее оптимальный префиксный код для алфавита Тогда дерево , полученное из дерева путем замены листа внутренним узлом с дочерними элементами и , представляет оптимальный префиксный код для алфавита . |
Доказательство: |
Сначала покажем, что стоимость дерева может быть выражена через стоимость дерева . Для каждого символа верно , значит, . Так как , то
из чего следует, что
или
Докажем лемму от противного. Предположим, что дерево не представляет оптимальный префиксный код для алфавита . Тогда существует дерево такое, что . Согласно лемме (1), элементы и можно считать дочерними элементами одного узла. Пусть дерево получено из дерева заменой элементов и листом с частотой . Тогдачто противоречит предположению о том, что дерево , представляет оптимальный префиксный код для алфавита . Значит, наше предположение о том, что дерево не представляет оптимальный префиксный код для алфавита , неверно, что и доказывает лемму. |
Теорема: |
Алгоритм Хаффмана дает оптимальный префиксный код. |
Доказательство: |
Справедливость теоремы непосредственно следует из лемм (1) и (2) |
Литература
- Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн Алгоритмы: построение и анализ — 2-е изд. — М.: «Вильямс», 2007. — с. 459. — ISBN 5-8489-0857-4