Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
3_chast_Proektirovanie_IS_TIPiS.docx
Скачиваний:
20
Добавлен:
21.08.2019
Размер:
940.3 Кб
Скачать

8. Оптимальное кодирование. Алгоритм Хаффмана.

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

Метод Хаффмана: буквы алфавита сообщений вписываются в столбец в порядке убывания вероятностей. Две последние буквы объе­диняются в одну вспомогательную букву, которой приписывается сум­марная вероятность. Вероятности букв, не участвовавших в объедине­нии, и полученная суммарная вероятность снова располагаются в порядке убывания вероятностей в дополнительном столбце, а две последние буквы объединяются.

Кодирование методом Хаффмана.

В методе Хаффмана кодо­вые слова формируются, начиная с последнего символа.

Шаг 1. Переменной-счетчику t присваиваем значение 1: t := 1. Рассмат­риваем вспомогательную последовательность символов At, полагая на пер­вом шаге a1 = А.

Шаг 2. Из последовательности At выбираем М символов ai1i2, ..... aim , которым соответствуют наименьшие вероятности появления

Шаг 3. Для выбранных символов формируются очередные (считая от конца) элементы кодовых слов: в кодовое слово, соответствующее символу ai, (i= 1, 2, . . . , М), добавляется символ кодового алфавита bi.

Шаг 4 Символы ai1, ai2, . . .., aim объединяются в один вспомогательный

м символ at с вероятностью р(аt) =  p(ai)

Шаг 5. Из последовательности символов исходного алфавита At исклю­чаем символы ai1, ai2, . . .., aim , вместо них добавляем аt . Полученную после­довательность обозначим At+1.

Шаг 6. Если At+1 состоит из одного элемента, то алгоритм заканчивает работу. Иначе t := t + 1 и переходим к шагу 2.

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

Алгоритм Хаффмена

Метод Хаффмана: буквы алфавита сообщений вписываются в столбец в порядке убывания вероятностей. Две последние буквы объединяются в одну вспомогательную букву, которой приписывается суммарная вероятность. Вероятности букв, не участвовавших в объединении, и полученная суммарная вероятность снова располагаются в порядке убывания вероятностей в дополнительном столбце, а две последние буквы объединяются.

Код Хаффмена

Вход: n – количество букв, P: array [1..n] of real – массив вероятностей букв, упорядоченный по убыванию.

Выход: C: array [1..n,1..L] of 0..1 – массив элементарных кодов, l: array [1..n] of 1..L – массив длин элементарных кодов схемы оптимального префиксного кодирования.

If n=2 then

C[1,1]:=0; l[1]:=1; (первый элемент)

C[2,1]:=1: l[2]:=1; (второй элемент)

else

q:=P[n-1]+ P[n]; (сумма двух последних вероятностей)

j:=Up(n,q); (поиск места и вставка суммы)

haff(P,n-1); (рекурс вызов)

Dawn(n,j); (достраивание кодов)

End;

Функция Up находит в массиве Р место, в котором должно находиться число q и вставляет это число, сдвигая вниз остальные элементы.

Вход: n – длинна обрабатываемой части массива, P, q – вставляемая сумма.

Выход: измеренный массив P.

For i from n-1 downto 2 do

If P[i-1] <=q then

P[i]:=P[i-1]; (сдвиг элемента массива)

Else

j:=i-1; (определение места вставляемого элемента)

exit for i (все сделано цикл не нужно продолжать)

end;

end;

p[j]:=q (запись восстанавливаемого элемента)

return j

Процедура Dawn строит оптимальный код для n букв на основе построенного оптимального кода для n-1 буквы. Для этого код буквы с номером j временно исключается из массива С путем сдвига вверх кодов букв с номерами, большими j, а затем в конец обрабатываемой части массива С добавляется пара кодов, полученных из кода буквы с номером j удлинением на 0 и 1, соответственно. Здесь C[i,*] означает вырезку из массива, т.е. i-ю строку массива С.

Вход: n – длинна обрабатываемой части массива, P, j – номер «разделяемой» буквы.

Выход: оптимальные коды в первых n элементах массивов C и l.

c:=C[j,*]; (запоминание кода буквы j)

l:=l[j]; (и длинны этого кода)

for i from j to n-2 do

C[i,*]:=C[i+1,*]; (сдвиг кода)

l[i]:=l[i+1]; (и его длинны)

end;

C[n-1,*]:=c; C[n,*]:=c; (копирование кода буквы j)

C[n-1,l+1]:=0; C[n,l+1]:=1; (наращивание кодов)

l[n-1]:=l+1; l[n]:=l+1; (и увеличение длин)