Канонический алгоритм Хаффмана Частоты дерево Хаффмана коды Хаффмана Исходный текст: 3 B 3 A 2 C 2 D 2 E 2 F 1 ABCDEFADEBBC 5 2 12 2 2 2 4 7 3 B 3 00 A 2 01 C 2 100 D 2 101 E 2 110 F 1 111 1 Зашифрованный текст: 0100 1001 0111 0111 0110 1110 0000 100 Проблемы канонического алгоритма Хаффмана 1. Для построения оптимального кода Хаффмана нужно 2 прохода по данным: a) Подсчёт частот встречаемости символов (для построения дерева Хаффмана). b) Собственно кодирование текста. 2. Для раскодирования текста надо передавать структуру дерева Хаффмана (либо частоты). 3. Нет учёта локальных изменений в статистике распределения частот (пример – EXE-файлы). Адаптивный алгоритм Хаффмана Идея Статистику символов надо набирать по мере чтения текста. Можно не передавать частоты/дерево вместе с закодированным сообщением, его можно восстановить прямо из текста! Код будет адаптироваться под текущее распределение частот символов. Дерево Хаффмана придётся перестраивать. Адаптивный алгоритм Хаффмана Схема работы Кодирование Раскодирование Initialize_Tree; Initialize_Tree; while not End_of_Text do begin while not End_of_Text do begin Пояснения Создать начальное состояния дерева Хаффмана А покуда не конец… Read_Char; Decode_Char; …Раскодировать Encode_Char; Write_Char; Закодировать… Update_Tree; end; Update_Tree; end; Обновить статистику для последнего символа Адаптивный алгоритм Хаффмана Инициализация дерева Простейший вариант: Всем символам присвоить одинаковое начальное количество =1 (0 – плохо, т.к. не даёт различия для суммы неудобно строить дерево, потребуется отдельный алгоритм для построения дерева с нулевыми весами элементов). Недостатки 1. Плохо кодирует короткие сообщения. 2. В алфавите есть сразу все символы, даже те, которых нет в сообщении! Адаптивный алгоритм Хаффмана Инициализация дерева "Боевые" алгоритмы: Изначально в алфавите есть только два специальных символа – ESCAPE и EOF. • EOF (End-Of-File) – признак окончания текста. • ESCAPE (выход за алфавит) – признак, что новый символ ещё отсутствует в алфавите, его надо добавить (в алфавит) и обновить дерево Хаффмана. Адаптивный алгоритм Хаффмана Алгоритм Исходный текст: ABCDEFADEBBC Пусть уже прочитаны первые символы, например, ABCDEF. Для них дерево Хаффмана выглядит так: A 1 1 B 1 1 C 1 1 D 1 1 E 1 1 F 1 1 2 4 2 6 2 Адаптивный алгоритм Хаффмана Алгоритм Исходный текст: ABCDEFADEBBC Сохраним дерево в массиве записей. A B Type TRec = record ischar: boolean; // =FALSE for inner nodes chr: char; // symbol of the text count: integer; // counter of symbols in text child, // reference to children parent: integer; // reference to parent node end; Var Q: array [1..256*2-1] of TRec; C D E F 11 11 11 11 11 11 2 4 2 2 6 Адаптивный алгоритм Хаффмана Алгоритм Исходный текст: ABCDEFADEBBC Записи упорядочены по возрастанию A частот (количества символов). В массиве дерево Хаффмана выглядит так: 1 1 1 1 1 1 1 B 1 C 1 D 1 E 1 F 1 2 4 2 6 2 A B C D E F (AB) (CD) (EF) (A..D) (A..F) 1 1 1 1 1 1 2 2 2 4 6 Адаптивный алгоритм Хаффмана Добавление буквы A- перестановка Исходный текст: ABCDEFADEBBC A B C D E F (AB) (CD) (EF) (A..D) (A..F) 1 1 1 1 1 1 2 2 2 4 6 A B C D E F (AB) (CD) (EF) (A..D) (A..F) 1+1=2 1 1 1 1 1 2 2 2 4 6 F B C D E A (AB) (CD) (EF) (A..D) (A..F) 1 1 1 1 1 2 2 2 2 4 6 A Адаптивный алгоритм Хаффмана Добавление буквы A (продолж.) Исходный текст: ABCDEFADEBBC F B C D E A (AB) (CD) (EF) (A..D) (A..F) 1 1 1 1 1 2 2 2 2+1=3 4 6 F B C D E A (AB) (CD) (EF) (A..D) (A..F) 1 1 1 1 1 2 2 2 3 4 6+1=7 F B C D E A (AB) (CD) (EF) (A..D) (A..F) 1 1 1 1 1 2 2 2 3 4 7 Адаптивный алгоритм Хаффмана Добавление буквы D- перестановка Исходный текст: ABCDEFADEBBC D F B C D E A (AB) (CD) (EF) (A..D) (A..F) 1 1 1 1+1=2 1 2 2 2 3 4 7 F B C E D A (AB) (CD) (EF) (A..D) (A..F) 1 1 1 1 2 2 2 2 3+1=4 4 7+1=8 F B C E D A (AB) (CD) (EF) (A..D) (A..F) 1 1 1 1 2 2 2 2 4 4 8 Адаптивный алгоритм Хаффмана Добавление буквы E Исходный текст: ABCDEFADEBBC E F B C E D A (AB) (CD) (EF) (A..D) (A..F) 1 1 1 1+1=2 2 2 2 2+1=3 4 F B C E D A (AB) (CD) (EF) (A..D) (A..F) 1 1 1 2 2 2 2 3 4 5 9 4+1=5 8+1=9 Адаптивный алгоритм Хаффмана Перестановка листа Исходный текст: ABCDEFADEBBC B F B C E D A (AB) (CD) (EF) (A..D) (A..F) 1 1+1=2 1 2 2 2 2 3 4 5 9 F C B E D A (AB) (CD) (EF) (A..D) (A..F) 1 1 2 2 2 2 2 3+1=4 4 5+1=6 9+1=10 F C B E D A (AB) (CD) (EF) (A..D) (A..F) 1 1 2 2 2 2 2 4 4 6 10 Адаптивный алгоритм Хаффмана Перестановка внутреннего узла Исходный текст: ABCDEFADEBBC B F C B E D A (AB) (CD) (EF) (A..D) (A..F) 1 1 2+1=3 2 2 2 2 4 4 6 10 F C (AB) E D A B (CD) (EF) (A..D) (A..F) 1 1 2 2 2 2 3 4 4 6+1=7 10+1=11 F C (AB) E D A B (CD) (EF) (A..D) (A..F) 1 1 2 2 2 2 3 4 4 7 11 Адаптивный алгоритм Хаффмана Перестановка и продолжение C Исходный текст: ABCDEFADEBBC F 1 C (AB) 1+1=2 2+1=3 E D A B (CD) (EF) (A..D) (A..F) 2 2 2 3 4 4 7 11 F C A E D (AB) B (CD) (EF) (A..D) (A..F) 1 2 2 2 2 3 3 4 4+1=5 7 11+1=12 F C A E D (AB) B (CD) (EF) (A..D) (A..F) 1 2 2 2 2 3 3 4 4+1=5 7 11+1=12 Адаптивный алгоритм Хаффмана Проверка Исходный текст: ABCDEFADEBBC [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] F C A E D (AB) B (CD) (EF) (A..D) (A..F) 1 2 2 2 2 3 3 4 5 7 12 F 1 C 2 A 2 E 2 D 2 B 3 [1] 1 [2] 2 [3] 2 [4] 2 [5] 2 [7] 3 [6] 3 [8] 4 [9] 5 [10] 7 [11] 12