Адаптивный алгоритм Хаффмана

advertisement
Канонический алгоритм Хаффмана
Частоты  дерево Хаффмана  коды Хаффмана
Исходный текст:
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
Download