N(ai) –число двоичных разрядов в кодовой комбинации, соответствующей символуai.

Таким образом, мы получим для табл.1 Iср=2,84, а для табл.2 Iср=2,80. Построенный код весьма близок к наилучшему эффективному коду по Шеннону, но не является оптимальным. Должен существовать некоторый алгоритм позволяющий выполнить большее сжатие сообщения.

От недостатка рассмотренного алгоритма свободна методика Д. Хаффмена. Она гарантирует однозначное построение кода с наименьшим для данного распределения вероятностей средним числом двоичных разрядов на символ.

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

Шаг 1. Символы алфавита, составляющего сообщение, выписываются в основной столбец в порядке убывания вероятностей. Два последних символа объединяются в один вспомогательный, которому приписывается суммарная вероятность.

Шаг 2. Вероятности символов, не участвовавших в объединении, и полученная суммарная вероятность снова располагаются в порядке убывания вероятностей в дополнительном столбце, а две последних объединяются. Процесс продолжается до тех пор, пока не получим единственный вспомогательный символ с вероятностью, равной единице.

Эти два шага алгоритма иллюстрирует табл.3 для уже рассмотренного случая кодирования восьми символов.

Шаг 3.Строится кодовое дерево и, в соответствии с ним, формируются кодовые слова, соответствующие кодируемым символам.

Поясним принципы выполнения последнего шага алгоритма. Для составления кодовой комбинации, соответствующей данному сообщению, необходимо проследить путь перехода сообщений по строкам и столбцам таблицы. Для наглядности строится кодовое дерево (рис.1). Из точки, соответствующей вероятности 1, направляются две ветви. Ветви с большей вероятностью присваивается символ 1, а с меньшей – символ 0. Такое последовательное ветвление продолжаем до тех пор, пока не дойдем до каждого символа.

Таким образом, символам источника сопоставляются концевые вершины дерева. Кодовые слова, соответствующие символам, определяются путями из начального узла дерева к концевым. Каждому ответвлению влево соответствует символ 1 в результирующем коде, а вправо – символ 0.

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

 
 

 

 


 

 

Рис.1. Кодовое дерево


 

Теперь, двигаясь по кодовому дереву сверху вниз, можно записать для каждой буквы соответствующую ей кодовую комбинацию:

a1 a2 a3 a4 a5 a6 a7 a8

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

Пусть передаваемое сообщение a1, a5, a3, a7, a8. В результате кодирования по алгоритму Хаффмана получим следующую кодовую последовательность:

011001111010110100.

При приеме неизвестно, каким образом эту последовательность надо разбить на кодовые слова и, соответственно, получить последовательность переданных символов.

Просматриваем принятую последовательность слева направо, учитывая, что наибольшая длина кодового слова равна 5. Из первых пяти принятых элементов следует, что комбинация 01100 не встречается ни в одном кодовом слове. Единственным правильным решением будет, что первым был передан символ a1. Аналогично, продолжая просмотр с третьего слева элемента, определяем второй символ - a5. Аналогично декодируем все сообщение - .a1, a5, a3, a7, a8.

Таким образом, в передаваемой последовательности нет необходимости указывать разделители между отдельными кодовыми словами.