Открыть сервис

Канонический код Хаффмана

Канонический код Хаффмана — это разновидность префиксного кода, получаемая на основе алгоритма Хаффмана, в которой кодовые слова одинаковой длины упорядочены в лексикографическом порядке (по возрастанию числового значения). Данный подход позволяет значительно сократить объём служебной информации, необходимой для хранения или передачи таблицы кодирования, что критически важно для систем сжатия данных с ограниченным размером заголовка (например, в форматах JPEG, DEFLATE, MP3).

История

Алгоритм построения оптимального префиксного кода был предложен Дэвидом Хаффманом в 1952 году. Однако оригинальный метод не задавал жёсткого порядка кодовых слов, что приводило к неоднозначности при декодировании, если таблица кодов не передавалась явно. В 1970-х годах для практических задач сжатия (в частности, для архиваторов и кодеков) была разработана концепция канонического кода. Она впервые была формализована в стандарте сжатия данных PKZIP (алгоритм Deflate, 1993 год) и впоследствии закреплена в спецификациях JPEG, MPEG, GZIP и других. Основная цель введения канонической формы — замена полной таблицы кодов компактным представлением, состоящим только из длин кодовых слов.

Определение и свойства

Канонический код Хаффмана удовлетворяет следующим условиям:

  1. Префиксность: ни одно кодовое слово не является началом другого.
  2. Оптимальность: код построен по алгоритму Хаффмана и минимизирует среднюю длину кодового слова для заданного распределения вероятностей символов.
  3. Каноничность: кодовые слова одинаковой длины упорядочены по возрастанию их числового значения, а сами длины кодовых слов не убывают при переходе от одного символа к другому.

Формально, если длины кодовых слов для символов алфавита равны \(l_1, l_2, \dots, l_n\) (где \(l_i\) — длина кода для i-го символа), то канонический код строится следующим образом:

  • Символы сортируются по возрастанию длины кода, а при равной длине — по порядку исходного алфавита (или по частоте).
  • Первое кодовое слово минимальной длины \(l_{\min}\) получает значение \(0^{l_{\min}}\) (строка из \(l_{\min}\) нулей).
  • Каждое следующее кодовое слово той же длины получает значение предыдущего, увеличенное на 1.
  • При переходе к следующей длине \(l' > l\) новое кодовое слово получается путём добавления нулей к двоичной записи числа, равного (предыдущее кодовое слово + 1), сдвинутого влево на \((l' - l)\) бит.

Это гарантирует, что декодирование возможно без явного хранения кодовых слов — достаточно знать только длины кодов для каждого символа.

Алгоритм построения

Построение канонического кода Хаффмана включает два этапа:

  1. Построение дерева Хаффмана: по заданным частотам символов строится бинарное дерево, листья которого соответствуют символам, а пути от корня к листьям — кодовым словам. Длина пути равна длине кода.
  2. Преобразование в каноническую форму: на основе полученных длин кодовых слов строится канонический код. Для этого:
  • Определяется максимальная длина кода \(L_{\max}\).
  • Создаётся массив длин кодовых слов для каждого символа.
  • Символы сортируются по возрастанию длины кода.
  • Применяется описанный выше алгоритм присвоения кодовых слов.

В результате получается таблица, в которой кодовые слова имеют строго определённый порядок, что позволяет восстановить их по единственному параметру — длине кода для каждого символа.

Преимущества перед обычным кодом Хаффмана

Основное преимущество канонического кода — компактное представление таблицы кодирования. Для обычного кода Хаффмана требуется передать каждое кодовое слово (например, в виде пары «символ — кодовая строка»), что может занимать десятки и сотни байт. Для канонического кода достаточно передать список длин кодовых слов для каждого символа (обычно 4–8 бит на символ) или даже более эффективную кодировку — например, коды длин по Хаффману (как в Deflate). Это особенно важно для сжатия коротких сообщений, где размер заголовка может превышать размер сжатых данных.

Дополнительные преимущества:

Применение

Канонический код Хаффмана широко используется в современных алгоритмах сжатия данных:

  • Deflate (форматы ZIP, GZIP, PNG): основной алгоритм сжатия, где канонический код применяется для кодирования литералов, длин повторов и смещений. В спецификации Deflate длины кодовых слов передаются в виде кодов Хаффмана для самих длин.
  • JPEG: в стандарте сжатия изображений используется канонический код Хаффмана для кодирования DC- и AC-коэффициентов после дискретного косинусного преобразования. В заголовке JPEG передаются таблицы длин кодовых слов.
  • MP3 (MPEG-1 Audio Layer 3): для кодирования масштабных коэффициентов и битовой информации применяется канонический код Хаффмана, что позволяет снизить битрейт без потери качества.
  • Brotli: современный алгоритм сжатия, разработанный Google, использует канонический код Хаффмана как часть контекстного моделирования.
  • Zstandard (Zstd): алгоритм сжатия от Facebook (организация Meta признана экстремистской и запрещена в РФ) использует канонический код Хаффмана для энтропийного кодирования наряду с ANS (асимметричными системами счисления).

Пример

Рассмотрим алфавит из 4 символов с частотами: A (50%), B (25%), C (15%), D (10%). Дерево Хаффмана даёт длины кодов: A — 1, B — 2, C — 3, D — 3. Канонический код строится следующим образом:

  • Сортировка по длине: A (1), B (2), C (3), D (3).
  • Первое кодовое слово длины 1: «0».
  • Следующее слово длины 1 отсутствует.
  • Переход к длине 2: предыдущее кодовое слово «0» + 1 = «1», сдвиг влево на (2-1)=1 бит: «10».
  • Длина 3: предыдущее кодовое слово «10» + 1 = «11», сдвиг влево на (3-2)=1 бит: «110».
  • Следующее слово длины 3: «110» + 1 = «111».

Итоговые коды: A — 0, B — 10, C — 110, D — 111. Эти коды удовлетворяют условию префиксности и упорядочены лексикографически.

Критика

Несмотря на широкое распространение, канонический код Хаффмана имеет ограничения:

  • Статичность: код строится на основе фиксированных частот, что неэффективно для данных с сильно меняющейся статистикой. Для адаптивного кодирования используются динамические версии (например, адаптивный Хаффман).
  • Избыточность при малых алфавитах: для алфавита из 2–3 символов канонический код не даёт выигрыша по сравнению с простым бинарным кодированием.
  • Зависимость от точности частот: ошибки в оценке вероятностей приводят к неоптимальному коду, что снижает степень сжатия.

В современных алгоритмах (Zstd, Brotli) канонический код Хаффмана часто комбинируется с более мощными методами энтропийного кодирования, такими как ANS, что позволяет достичь лучшего сжатия на разнородных данных.

Источники

  • Д. Хаффман, «A Method for the Construction of Minimum-Redundancy Codes», Proceedings of the IRE, 1952.
  • RFC 1951 (Deflate Compressed Data Format Specification), 1996.
  • ITU-T T.81 (JPEG Standard), 1992.
  • ISO/IEC 11172-3 (MPEG-1 Audio Layer 3), 1993.
  • J. Ziv, A. Lempel, «A Universal Algorithm for Sequential Data Compression», IEEE Transactions on Information Theory, 1977.
  • С. В. Абрамов, «Сжатие данных: теория и практика», 2015.

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →