Сайт о телевидении

Сайт о телевидении

» » Кодирование информации методом шеннона. Коды шеннона - фано

Кодирование информации методом шеннона. Коды шеннона - фано

При ответе на данный вопрос необходимо привести пример построения префиксного кода Шеннона-Фано для заданного начального алфавита и известных частот использования символов этого алфавита с помощью таблицы и графа.

В 1948-1949 гг. Клод Шеннон (Claude Elwood Shannon ) и Роберт Фано (Robert Mario Fano ) независимо друг от друга предложили префиксный код, названный в последствие в их честь. Алгоритм Шеннона - Фано использует избыточность сообщения, заключённую в неоднородном распределении частот символов его первичного алфавита, то есть заменяет коды более частых символов короткими двоичными последовательностями, а коды более редких символов - более длинными двоичными последовательностями.

Рассмотрим этот префиксный код на примере. Пусть имеется первичный алфавит, состоящий из шести символов: {A; B; C; D; E; F}, также известны вероятности появления этих символов в сообщении соответственно {0,15; 0,2; 0,1; 0,3; 0,2; 0,05}. Расположим эти символы в таблице в порядке убывания их вероятностей.

Кодирование осуществляется следующим образом. Все знаки делятся на две группы с сохранением порядка следования (по убыванию вероятностей появления), так чтобы суммы вероятностей в каждой группе были приблизительно равны. В нашем примере в первую группу попадают символы D и B, все остальные буквы попадают во вторую группу. Поставим ноль в первый знак кодов для всех символов из первой группы, а первый знак кодов символов второй группы установим равным единице.

Продолжим деление каждой группы. В первой группе два элемента, и деление на подгруппы здесь однозначно: в первой подгруппе будет символ D, а во второй - символ B. Во второй группе теоретически возможны три способа деления на подгруппы: {E} и {A, C, F}, {E, A} и {C, F}, {E, A, C} и {F}. Но в первом случае абсолютная разность суммарных вероятностей будет |0,2 - (0,15 + 0,1 + 0,05)| = 0,1. Во втором и третьем варианте деления аналогичные величины будут 0,2 и 0,4 соответственно. Согласно алгоритму необходимо выбрать тот способ деления, при котором суммы вероятностей в каждой подгруппе были примерно одинаковыми, а, следовательно, вычисленная разность минимальна. Соответственно наилучшим способом деления будет следующий вариант: {E} в первой подгруппе и {A, C, F} во второй. Далее по имеющемуся алгоритму распределим нули и единицы в соответствующие знаки кода каждой подгруппы.



Осуществляем деление на подгруппы по той же схеме до тех пор, пока не получим группы, состоящие из одного элемента. Процедура деления изображена в таблице (символ Х означает, что данный знак кода отсутствует):

Первичный алфавит Вероятности появления Знаки кода символа Код символа Длина кода
I II III IV
D 0,3 Х Х
B 0,2 Х Х
E 0,2 Х Х
A 0,15 Х
C 0,1
F 0,05

Данный код может быть построен и с помощью графа. Распределим символы алфавита в порядке убывания вероятностей - это будут концевые вершины (листья) будущего двоичного дерева (нижние индексы соответствуют вероятностям появления символов):

D 0,3 B 0,2 E 0,2 A 0,15 C 0,1 F 0,05

Согласно алгоритму построения кода Шеннона-Фано разобьем эти символы на две группы с приблизительно равными суммарными вероятностями появления и соединим первые символы каждой группы с корнем дерева:

D 0,3 B 0,2 E 0,2 A 0,15 C 0,1 F 0,05

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

D 0,3 B 0,2 E 0,2 A 0,15 C 0,1 F 0,05
D 0,3 B 0,2 E 0,2 A 0,15 C 0,1 F 0,05

Окончательно имеем следующий граф:

D 0,3 B 0,2 E 0,2 A 0,15 C 0,1 F 0,05

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

D 0,3
B 0,2 E 0,2 A 0,15
C 0,1
F 0,05

Для получения кода символа достаточно пройти по дугам полученного дерева от корня к соответствующей вершине и записать номера дуг, по которым осуществляется движение. Например, для символа A, двигаясь от корня дерева, проходим дуги с номерами 1, 1 и 0, следовательно код символа A - 110. Аналогично могут быть получены коды других символов.

Полученный код удовлетворяет условию Фано, следовательно он является префиксным. Средняя длина этого кода равна (см. формулу на стр.13):

К(Шеннона-Фано, А, Binary) = 0,3*2+0,2*2+0.2*2+0,15*3 +0,1*4+0.05*4 = 2,45 символа.

Теперь по известной нам формуле найдем избыточность кода Шеннона –Фано:

Q(Шеннона-Фано, A, Binary) = 2,45/2,41 – 1 = 0,01659751.

То есть избыточность кода Шеннона-Фано для нашего шестибуквенного алфавита составляет всего около 1,7 %. Для русского алфавита этот избыточность кодирования кодом Шеннона-Фано составила бы примерно 1,47%.

Префиксный код Хаффмана.

При ответе на данный вопрос необходимо привести пример построения префиксного кода Хаффмана для заданного начального алфавита и известных частот использования символов этого алфавита с помощью таблицы и графа.

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

Алгоритм кодирования методом Хаффмана состоит из двух этапов. На первом этапе исходный алфавит на каждом шаге сокращается на один символ и на следующем шаге рассматривается новый, сокращенный первичный алфавит. Число таких шагов будет на две единицы меньше первоначального числа символов. На втором этапе происходит пошаговое формирование кода символов, при этом заполнение кода осуществляется с символов последнего сокращенного первичного алфавита.

Рассмотрим алгоритм построения кода Хаффмана на примере. Пусть имеется первичный алфавит, состоящий из шести символов: {A; B; C; D; E; F}, также известны вероятности появления этих символов в сообщении соответственно {0,15; 0,2; 0,1; 0,3; 0,2; 0,05}. Расположим эти символы в таблице в порядке убывания их вероятностей.

На первом шаге алгоритма два символа исходного алфавита с наименьшими вероятностями объединяются в один новый символ. Вероятность нового символа есть сумма вероятностей тех символов, которые его образовали. Таким образом, получаем новый алфавит, который содержит на один символ меньше чем предыдущий. На следующем шаге алгоритма описанная процедура применяется к новому алфавиту. И так до тех пор, пока в очередном алфавите не остается только двух символов.

A 0 Код А 0 A 1 Код А 1 А 2 Код А 2 А 3 Код А 3 А 4 Код А 4
a 0 1 =D P = 0,3 a 1 1 P = 0,3 a 2 1 P = 0,3 a 3 1 P = 0,4 a 4 1 P = 0,6
a 0 2 =B P = 0,2 a 1 2 P = 0,2 a 2 2 P = 0,3 a 3 2 P = 0,3 a 4 2 P = 0,4
a 0 3 =E P = 0,2 a 1 3 P = 0,2 a 2 3 P = 0,2 a 3 3 P = 0,3
a 0 4 =A P = 0,15 a 1 4 P = 0,15 a 2 4 P = 0,2
a 0 5 =C P = 0,1 a 1 5 P = 0,15
a 0 6 =F P = 0,05

Теперь начинается второй этап алгоритма кодирования по Хаффману. Для формирования кода мы нумеруем символы всех промежуточных алфавитов, начиная с последнего. В нашем примере – с А 4 .

В А 4 всего два символа. Они получают соответственно номера 0 и 1. В алфавите А 3 уже три символа. Причем, один из символов алфавита А 4 , назовем этот символ «предок», был получен объединением двух символов алфавита А 3 , назовем первый из этих символов «дочкой», а второй «сыном». Коды этих двух символов формируются следующим образом. К номеру «предка» приписываются справа 0, чтобы получить номер «дочки», и 1 – чтобы получить номер «сына». Следующая итерация алгоритма по той же схеме формирует коды символов алфавита А 2 . В нем два первых символа будут иметь те же коды, что были у них в А 1 , а два последних символа изменят свой код, удлинив его на 1 символ («0» и «1» соответственно). Процесс останавливается при достижении первичного алфавита A 0 – коды для знаков первичного алфавита получены.

A 0 Код А 0 A 1 Код А 1 А 2 Код А 2 А 3 Код А 3 А 4 Код А 4
a 0 1 =D P = 0,3 a 1 1 P = 0,3 a 2 1 P = 0,3 a 3 1 P = 0,4 a 4 1 P = 0,6
a 0 2 =B P = 0,2 a 1 2 P = 0,2 a 2 2 P = 0,3 01 a 3 2 P = 0,3 a 4 2 P = 0,4
a 0 3 =E P = 0,2 a 1 3 P = 0,2 a 2 3 P = 0,2 a 3 3 P = 0,3
a 0 4 =A P = 0,15 a 1 4 P = 0,15 a 2 4 P = 0,2
a 0 5 =C P = 0,1 a 1 5 P = 0,15
a 0 6 =F P = 0,05

Данный алгоритм построения можно осуществить и с помощью графа. Расположим символы первичного алфавита в порядке убывания вероятностей их появления. Эти символы будут листьями будущего кодового дерева. Будем считать, что уровень этих концевых узлов равен N.

В получившемся промежуточном алфавите вновь выбираем два символа с наименьшей частотой использования. Это символ А с вероятностью 0,15 и новый символ, получившийся в результате объединения символов C и F на предыдущем этапе и имеющий ту же вероятность использования. Соединяем эти символы дугами, исходящими из одного узла N-2 уровня:

Посчитаем среднюю длину кодового слова для кода Хаффмана и нашего первичного алфавита А.

К(Хаффман, А, Binary) = = 0,3*2 + 0,2*2 + 0.2*2 + 0,15*3 + 0,1*4 + 0.05*4 = 2,45 символа

Среднее количество информации на один символ первичного алфавита равно:

I A = - (0,3* log 2 0,3 + 0,2* log 2 0,2 + 0,2* log 2 0,2 + 0,15* log 2 0,15 + + 0,1* log 2 0,1 + 0,05* log 2 0,05) = 2,41 бит.

Относительная избыточность кода Хаффмана в нашем случае:

Q(Хаффмана, A, Binary) = 2,45/2,41 – 1 = 0,01659751.

Таким образом, для нашего примера код Шеннона-Фано и код Хаффмана обладают одинаковой избыточностью. Однако, в тех случаях когда вероятности символов первичного алфавита сильно разнятся, ситуация меняется. Код Хаффмана обладает существенно меньшей избыточностью. Например, для русского языка избыточность кодирования кодом Хаффмана оказывается равной примерно 0,0090.

Кодирование Шеннона-Фано является одним из самых первых алгоритмов сжатия, который впервые сформулировали американские учёные Шеннон (Shannon) и Фано (Fano). Данный метод сжатия имеет большое сходство с кодированием Хаффмана , которое появилось на несколько лет позже. Главная идея этого метода - заменить часто встречающиеся символы более короткими кодами, а редко встречающиеся последовательности более длинными кодами. Таким образом, алгоритм основывается на кодах переменной длины. Для того, чобы декомпрессор впоследствии смог раскодировать сжатую последовательность, коды Шеннона-Фано должны обладать уникальностью, то есть, не смотря на их переменную длину, каждый код уникально определяет один закодированый символ и не является префиксом любого другого кода.
Рассмотрим алгоритм вычисления кодов Шеннона-Фано (для наглядности возьмём в качестве примера последовательность "aa bbb cccc ddddd"). Для вычисления кодов, необходимо создать таблицу уникальных символов сообщения c(i) и их вероятностей p(c(i)) , и отсортировать её в порядке невозрастания вероятности символов.
c(i) p(c(i))
d 5 / 17
c 4 / 17
space 3 / 17
b 3 / 17
a 2 / 17

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

Длина кода s(i) в полученной таблице равна int(-lg p(c(i))) , если сиволы удалость разделить на группы с одинаковой частотой, в противном случае, длина кода равна int(-lg p(c(i))) + 1 .

длиной в 39 бит. Учитывая, что оргинал имел длину равную 136 бит, получаем коэффициент сжатия ~28% - не так уж и плохо.
Глядя на полученную последовательность, возникает вопрос: "А как же теперь это расжать?". Мы не можем, как в случае кодирования, заменять каждые 8 бит входного потока, кодом переменной длины. При расжатии нам необходимо всё сделать наоборот - заменить код переменной длины символом длиной 8 бит. В данном случае, лучше всего будет использовать бинарное дерево, листьями которого будут являтся символы (аналог дерева Хаффмана).
Кодирование Шеннона-Фано является достаточно старым методом сжатия, и на сегодняшний день оно не представляет особого практического интереса (разве что как упражнение по курсу структур данных). В большинстве случаев, длина сжатой последовательности, по данному методу, равна длине сжатой последовательности с использованием кодирования Хаффмана. Но на некоторых последовательностях всё же формируются не оптимальные коды Шеннона-Фано, поэтому сжатие методом Хаффмана принято считать более эффективным. Для примера, рассмотрим последовательность с таким содержанием символов: "a" - 14, "b" - 7, "c" - 5, "d" - 5, "e" - 4. Метод Хаффмана сжимает её до 77 бит, а вот Шеннона-Фано до 79 бит.

символ код Хаффмана код Шеннона-Фано
a 0 00
b 111 01
c 101 10
d 110 110
e 100 111
Кстати, в одном источнике (не буду указывать каком), эту последовательность сжали методом Шеннона-Фано до 84 бит, а методом Хаффмана до тех же 77. Такие отличаи в степени сжатия возникают из-за нестрогого определения способа деления символов на группы.
Как же мы делили на группы? Достаточно просто:

Из-за такой неопределённости у некоторых людей возникают даже такие мысли: "... программа иногда назначает некоторым символам..." и так далее - рассуждения о длине кодов. Если вы не пишете AI, то такое понятие, как "программа иногда" что-то делает, звучит смешно. Правильно реализованный алгоритм - работает строго опеределённо.

Для определенности будем рассматривать кодирование в двоичном алфавите (m = 2). Буквы (или любые сообщения, подлежащие кодированию) исходного алфавита записывают в порядке убывающей вероятности. Упорядоченное таким образом множество букв разбивают на две части так, чтобы суммарные вероятности этих подмножеств были примерно равны. Всем знакам (буквам) верхней половины в качестве первого символа присваивают кодовый элемент 1, а всем нижним - 0. Затем каждое подмножество снова разбивается на два подмножества с соблюдением того же условия равенства вероятностей и с тем же условием присваивания кодовых элементов в качестве второго символа. Такое разбиение продолжается до тех пор, пока в подмножестве не окажется только по одной букве кодируемого алфавита. При каждом разбиении буквам верхнего подмножества присваивается кодовый элемент 1, а буквам нижнего подмножества - 0.

Пример. Провести эффективное кодирование ансамбля из восьми знаков:

(знак) x i

Вероят-ность p i

Кодовые последовательности

Длина l i

р i l i

i log р i

Номер разбиения

2,7 и
.

Как видно, l ср = H , следовательно, полученный код является оптимальным.

Заметим, что при равномерном (не учитывающем статистических характеристик) кодировании с использованием m =2 знаков количество элементов в кодовой последовательности будет l  log m n = log 2 8 = 3, т.е. для представления каждого знака использованного алфавита потребуется три двоичных символа.

При кодировании по методике Шеннона - Фано некоторая избыточность в последовательностях символов, как правило, остается (l ср > H ).

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

Пример. Рассмотрим процедуру эффективного кодирования сообщений, образованных с помощью алфавита, состоящего всего из двух знаков x 1 и x 2 с вероятностями появления соответственно

p (х 1) = 0,9; p (x 2) = 0,1.

Так как вероятности не равны, то последовательность из таких букв будет обладать избыточностью. Однако, при побуквенном кодировании мы никакого эффекта не получим. Действительно, на передачу каждой буквы требуется символ либо 1, либо 0, в то время как энтропия равна
, т.е. оказывается
.

При кодировании блоков, содержащих по две буквы, получим коды:

Вероятности

комбинации

номер разбиения

Так как знаки статистически не связаны, вероятности блоков определяют как произведение вероятностей составляющих знаков. Среднее число символов на блок
а на букву 1,29/2 = 0,645, т.е. приблизилось к Н = 0,47, и таким образом удалось повысить эффективность кодирования.

Кодирование блоков, содержащих по три знака, дает еще больший эффект:

Вероятность

кодовые комбинации

номер разбиения

Среднее число символов на блок равно 1,59, а на знак - 0,53, что всего на 12% больше энтропии.

Оптимальным кодом можно определить тот, в котором каждый двоичный символ будет передавать максимальную информацию. В силу формул Хартли и Шеннона максимум энтропии достигается при равновероятных событиях, следовательно, двоичный код будет оптимальным, если в закодированном сообщении символы 0 и 1 будут встречаться одинаково часто.

Рассмотрим в качестве примера оптимальное двоичное кодирование букв русского алфавита вместе с символом пробела «-». Полагаем, что известны вероятности появления в сообщении символов русского алфавита, например, приведенные в таблице 3.

Таблица 3.Частота букв русского языка (предположение)

К. Шеннон и Р. Фано независимо предложили в 1948-1949 гг. способ построения кода, основанный на выполнении условия равной вероятности символов 0 и 1 в закодированном сообщении.

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

Для символов первой группы значение первого разряда кода присваивается равным «0», для символов второй группы – равными «1».

Далее каждая группа разделяется на две подгруппы, так чтобы суммы вероятностей знаков в каждой подгруппе были равны. Для символов первой подгруппы каждой группы значение второго разряда кода присваивается равным «0», для символов второй подгруппы каждой группы – «1». Такой процесс разбиения символов на группы и кодирования продолжается до тех пор, пока в подгруппах не остается по одному символу.

Пример кодирования символов русского алфавита приведен в табл. 4

Таблица 4. Пример кодирования букв русского алфавита с помощью кода Шеннна-Фано.

Анализ приведенных в таблице кодов приводит к выводу, что часто встречающиеся символы кодируются более короткими двоичными последовательностями, а редко встречающиеся - более длинными. Значит, в среднем для кодирования сообщения определенной длины потребуется меньшее число двоичных символов 0 и 1, чем при любом другом способе кодирования.

Вместе с тем процедура построения кода Шеннона-Фано удовлетворяет критерию различимости Фано. Код является префиксным и не требует специального символа, отделяющего буквы друг от друга для однозначного него декодирование двоичного сообщения.

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

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

Заключение

Мы рассмотрели задачу кодирования, которая включает в себя:

1.Обеспечение экономичности передачи информации посредством устранения избыточности.

2. Обеспечение надежности (помехоустойчивости) передачи информации

3.Согласование скорости передачи информации с пропускной способностью канала

Задача кодирования является одним из главных понятий информатики, так как кодирование предшествует передаче и хранению информации, и, соответственно, является основой их успешного осуществления.

При передаче сообщений по каналам связи могут возникать помехи, способные привести к искажению принимаемых знаков. Эта проблема решается с помощью помехоустойчивого кодирования. Помехоустойчивое кодирование передаваемой информации позволяет в приемной части системы обнаруживать и исправлять ошибки. Коды, применяемые при помехоустойчивом кодировании, называются корректирующими кодами. Впервые, исследование эффективного кодирования произвел Клод Шеннон. Для теории связи важнейшее значение имеют две теоремы, доказанные Шенноном.

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

Если рассмотреть примеры кодирования, на основе первой теоремы Шеннона, то можно прийти к выводам, что это кодирования является достаточно эффективным, так как получаемый код практически не имеет избыточности, но, к сожалению, в реальных линиях связи множество помех, и такой результат недостижим. Поэтому код Шеннона не является таким же эффективным как, например код Хафмена. Но, несмотря на это нужно отметить, что Клод Шеннон был одним из основателей теории кодирования и его работы внесли огромный вклад в развитие информатики.

Список литературы:

1. Журнал "Радио", номер 9, 1999г.

наук, г. Москва

2. Кловский Д.Д. Теория передачи сигналов. -М.: Связь, 1984.

3. Кудряшов Б.Д. Теория информации. Учебник для вузов Изд-во ПИТЕР,

4. Рябко Б.Я Фионов А.Н. Эффективный метод адаптивного

арифметического кодирования для источников с большими алфавитами

// Проблемы передачи информации 1999 Т.35, Вып С.95 - 108.

5. Семенюк В.В. Экономное кодирование дискретной информации СПб.:

СПбГИТМО (ТУ), 2001

6. Дмитриев В.И. Прикладная теория информации. М.: Высшая школа,

7. Нефедов В.Н Осипова В.А. Курс дискретной математики. М.: МАИ,

8. Колесник В.Д Полтырев Г.Ш. Курс теории информации. М.: Наука,

Алгоритм построения сжимающего кода Шеннона – Фано заключается в следующем.

1. Все символов дискретного источника располагаются в порядке убывания вероятностей их появления (табл. 4.2).

Таблица 4.2. Построение кода Шеннона-Фано

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

3. Верхняя группа кодируется символом «1», а нижняя – «0».

4. Каждая группа делится на две подгруппы с близкими суммарными вероятностями; верхняя подгруппа кодируется символом «1», а нижняя – «0».

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

6. Записывается код для каждого символа источника; считывание кода осуществляется слева направо.

При использовании простейшего равномерного кода для кодирования шести элементов алфавита источника потребуется по три двоичных символа на каждую букву сообщения. Если же используется код Шеннона – Фано, то среднее число символов на одну букву