Веду на сто
Учебная статья

Двоичные коды и условие Фано

Как читать двоичное сообщение без разделителей, почему код одной буквы не должен быть началом другого и от чего зависит длина сообщения.

В двоичном сообщении видна одна цепочка нулей и единиц. Границы между буквами в ней обычно не отмечены. Код должен позволять восстановить эти границы и получить единственное исходное сообщение. Условие Фано даёт простой способ организовать такой код.

Символ, кодовое слово и сообщение

Алфавит — набор допустимых символов: например, букв А, Б, В, Г. Каждому символу назначается непустая цепочка нулей и единиц — кодовое слово. Один ноль или одна единица занимает один бит. Длина кодового слова равна числу его битов.

В равномерном коде все слова имеют одинаковую длину. В неравномерном длины различаются. Например, можно использовать такой учебный набор:

БукваКодовое словоДлина
А\mathtt{0}1
Б\mathtt{10}2
В\mathtt{110}3
Г\mathtt{111}3

Код сообщения получается приписыванием кодов букв друг к другу. Для АБАГ это выглядит так:

\underbrace{\mathtt{0}}_{\text{А}}\ \underbrace{\mathtt{10}}_{\text{Б}}\ \underbrace{\mathtt{0}}_{\text{А}}\ \underbrace{\mathtt{111}}_{\text{Г}}\;\longrightarrow\;\mathtt{0100111}.

Пробелы и подписи слева показывают границы только в объяснении. Справа записана передаваемая последовательность из семи битов.

Почему условие Фано помогает читать код

Префикс — начало кодового слова. Код удовлетворяет условию Фано, если никакое кодовое слово не является началом другого. Разные буквы при этом не могут иметь одинаковые коды.

В учебном наборе выше после первого нуля уже понятна буква А: ни одно другое кодовое слово с нуля не начинается. После единицы чтение продолжается. Если следующая цифра — ноль, получилось слово \mathtt{10}, то есть Б. Если следующая цифра — единица, нужен ещё один бит, чтобы отличить В от Г.

Так сообщение читается слева направо: найденное кодовое слово завершается, затем начинается поиск следующего. В момент завершения не требуется угадывать, является ли оно только началом более длинного слова: условие Фано исключает эту ситуацию.

Как это показывает двоичное дерево

В начале пути ещё нет битов. Каждая ветвь добавляет 0 или 1. Путь до буквы задаёт её кодовое слово, а число пройденных ветвей — его длину. Ниже показан тот же учебный набор.

Дерево кода: А — 0, Б — 10, В — 110, Г — 111. Все буквы находятся в концах ветвей; после буквы путь не продолжается.

Узлы с буквами — листья. Если поместить букву во внутренний узел, код этой буквы станет началом кодов ниже него. Поэтому готовый код закрывает все свои продолжения. И наоборот: начало уже готового кода нельзя объявить отдельным кодовым словом.

Свободное начало можно оставить для одной буквы или разделить на два продолжения. Например, из \mathtt{10} получаются \mathtt{100} и \mathtt{101}. Теперь вместо одного слова длины 2 есть два слова длины 3. Само \mathtt{10} одновременно с ними использовать нельзя.

Длина набора кодов и длина сообщения

Сумма длин кодовых слов считает каждый код один раз. Для учебного набора это 1+2+3+3=9. Но сообщение АБАГ занимает 7 бит: код А встречается дважды, коды Б и Г — по одному разу, а код В не встречается.

Если буква встречается n раз, а её код имеет длину \ell, она добавляет в сообщение n\ell битов. Общая длина получается сложением этих вкладов:

L=\sum_i n_i\ell_i.

Здесь i обозначает букву алфавита, n_i — число её повторений в сообщении, \ell_i — длину её кода. Для АБАГ:

L=2\cdot1+1\cdot2+0\cdot3+1\cdot3=7.

При подборе кодов более частой букве выгоднее назначить более короткое из доступных слов. Например, если две буквы встречаются 3 и 1 раз, длины 2 и 4 дадут 3\cdot2+1\cdot4=10 битов. Обратное назначение даст 3\cdot4+1\cdot2=14. При таком обмене меняются только подписи двух свободно назначаемых слов; заданные условием коды переставлять нельзя.

Буква с нулевым числом повторений не увеличивает длину данного сообщения. Но если она входит в алфавит, для неё всё равно требуется допустимое кодовое слово. Оно занимает место в дереве и может повлиять на выбор остальных кодов.

Нарушение Фано и неоднозначность — разные утверждения

Условие Фано гарантирует однозначное декодирование, но не является единственным способом его обеспечить. Например, два кода А — \mathtt{0} и Б — \mathtt{01} нарушают условие Фано. Однако сообщение из этих кодов можно однозначно разбирать с конца: последняя единица означает код Б целиком, \mathtt{01}; последний ноль означает код А, \mathtt{0}. После удаления последнего кода разбор продолжается тем же способом.

Другой набор — \mathtt{0},\ \mathtt{01},\ \mathtt{10} — уже даёт неоднозначность: цепочка \mathtt{010} разбивается и как \mathtt{0}\mid\mathtt{10}, и как \mathtt{01}\mid\mathtt{0}. Значит, одного нарушения Фано недостаточно для вывода о неоднозначности. В задании с явным требованием Фано проверяется именно это требование.

Применение в заданиях

Как найти кратчайшее кодовое слово и при этом оставить место для остальных букв? Почему минимум суммы длин кодов может отличаться от минимума длины сообщения?

Эти вопросы разобраны на конкретных примерах в статье «Задание №4. Выбор кодов и длина сообщения».

Связанные материалыЗадание №4. Короткий конспект