Вы находитесь на странице: 1из 11

3. Словарные алгоритмы сжатия данных.

Методы Лемпела-Зива
3.1. Общая идея и классификация
словарных методов

Рассмотренные выше статистические методы


сжатия (Шеннона-Фано, Хаффмана, арифметическое
кодирование) используют статистическую модель дан-
ных, например, в виде распределения вероятностей
символов источника либо некоторых групп (блоков)
этих символов . Качество сжатия зависит от того, не-
сколько точной была эта модель.
Словарные методы не используют статистическую
модель. Основную идею словарного кодирования пояс-
ним на следующем простом примере. Допустим, что в
распоряжении кодера имеется хранящийся в памяти
некоторый индексированный (пронумерованный) список
из 30 тысяч слов. Если передача некоторого текстового
файла осуществляется с использованием стандартного
8 – битного кода ASCII–8 (т.е. без применения процедур
сжатия), то количество бит, используемых для пред-
ставления одного слова со средней длиной в 7 букв,
будет равно 8*7=56 бит. В то же время, если это слово
содержится в указанном индексированном списке, то
вместо прямой передачи слова в ASCII – кодировке
можно ограничиться передачей метки с указанием на
местоположение этого слова в словаре. Если пронуме-
ровать все слова в словаре числами от 0 до 30 000 , то
для указания номера любого слова достаточно
n  log2 30000  15 бит , т.е. получается более чем
трехкратный выигрыш в объеме передаваемых данных.
В тех случаях, когда необходимое слово в словаре от-
сутствует, оно может быть передано без сжатия. В
среднем, тем не менее, будет иметь место выигрыш в
объеме передаваемых данных, т.е. сжатие. При деко-
1
дировании осуществляется обратная замена индекса
на соответствующее ему слово или фразу словаря. Ин-
дексы слов и представляющие их коды должны быть
построены таким образом, чтобы в среднем их пред-
ставление занимало меньше места, чем требует пря-
мое представление замещаемых ими слов. За счет это-
го и происходит сжатие. При этом термины “слово” и
“фраза” понимаются не в общепринятом в теории языка
смысле, а более обобщенно, понимая под ними некото-
рые группы или подпоследовательности символов, ко-
торые как мы полагаем, будут встречаться в обрабаты-
ваемой последовательности.
Используемый словарь может быть статисти-
ческим или динамическим (адаптивным). Статистиче-
ские словари создаются заранее, до процедуры сжатия,
и в течение выполнения этой процедуры не изменяют-
ся. Динамические, или адаптивные словари строятся в
процессе выполнения процедуры сжатия путём добав-
ления в первоначально пустой или малозаполненный
исходный словарь новых слов по мере их поступления
из входного файла и удаления при необходимости ста-
рых слов или редко используемых слов, с тем, чтобы
ограничить рост размеров словаря выше некоторой до-
пустимой величины.
Статистические словари целесообразно исполь-
зовать для сжатия некоторых специализированных тек-
стов с ограниченным набором терминов, порядка не-
скольких сотен слов, что предполагает словари не-
большого размера, ориентированные на этот конкрет-
ный тип файлов. Главным недостатком статистических
словарей является необходимость их передачи деко-
деру совместно со сжатым файлом, что может нивели-
ровать выигрыш сжатия, особенно при передаче фай-
лов небольшого размера.

2
На практике преимущественное распространение
получили алгоритмы сжатия на основе динамических
или адаптивных словарей или более корректно-
адаптивных алгоритмов сжатия на основе словаря. Их
достоинством является более высокая универсаль-
ность по сравнению со сжатием на основе статистиче-
ских словарей, так как динамический словарь строится
по мере обработки входного файла и поэтому он как бы
“на лету” приспосабливается (адаптируется) к особен-
ностям этого файла. Важным является также то, что
процедура формирования словаря осуществляемая в
кодере, однозначно воспроизводится и в декодере в
процессе последовательной обработки сжатого файла.
Это позволяет избежать необходимости передачи сло-
варя совместно со сжатым файлом.
Базой большинства современных методов сло-
варного сжатия являются два алгоритма, которые раз-
работали и опубликовали в 1977 и 1978 гг. И.Зив (I.Ziv)
и А. Лемпел (A.Lempel ) [4,7,9,10]. В соответствии с да-
той публикации, эти алгоритмы принято обозначать
кратко символами LZ77 и LZ78 (иногда LZ1 и LZ2),
соответственно. Каждый из этих алгоритмов является, в
свою очередь, родоначальником целого семейства ме-
тодов, представляющих собой определенные модифи-
кации базовых алгоритмов. Эти модификации принято
обозначать кратко символами типа LZX, LZY и т.п., где
Х или Y и т.д. представляют первые буквы фамилий ав-
торов модификации.
LZ77, LZ78 и их модификации не требуют для
осуществления процедур кодирования и декодирования
наличия какой-то предварительной информации о
параметрах статистической модели источника. Следо-
вательно, они могут использоваться для кодирования
стационарного источника с моделью произвольного ви-
да и в этом смысле их можно отнести к универсальным

3
методам кодирования. При этом доказано [4], что сло-
варные методы LZ являются асимптотически опти-
мальными, т.е. при неограниченном увеличении длины
кодируемого файла средняя скорость кодирования R
(число бит кода, приходящихся на один кодируемый
символ источника) стремится к минимально возможно-
му по теореме Шеннона нижнему пределу, равному эн-
тропии источника H(S) .Следует, правда, отметить, что
скорость этого приближения является достаточно мед-
ленной. В каждом из указанных методов, включая и их
модификации, словарь формируется на основании уже
обработанной части входного потока символов, т.е.
адаптивно. Принципиальным отличием является лишь
способ формирования словаря и входящих в него слов.
Одной из причин популярности алгоритмов LZ являет-
ся их простота при достаточно высокой эффективности
сжатия.
3.2. Алгоритмы семейства LZ77

Алгоритмы LZ77 и его модификации называют также


алгоритмами со скользящим словарем или скользя-
щим окном. Кодер организует в памяти некоторую об-
ласть, называемую скользящим окном размером в M
байт, в которую может помещаться M символов, где
каждый символ входного кодируемого файла может
быть представлен 8 - битовым ASCII кодом.
Окно состоит из двух частей (рис.8.9). Левая часть окна
размером W байт называется буфером поиска. В ней
содержатся последние уже закодированные символы, и
она играет роль текущего словаря, в котором может
размещаться не более W символов (на практике обыч-
но W  2  16 тысяч символов). Правая часть окна,
называемая упреждающим буфером или буфером
предварительного просмотра (lookahead, англ.), со-
держит L  (M  W) очередных символов (на практике
4
обычно L  несколько десятков), которые предстоит за-
кодировать. Таким образом, через сдвиговый регистр
длиной M ячеек выходной поток символов кодируемого
сообщения последовательно сдвигается справа нале-
во.

Буфер поиска (словарь) Упрежд. буфер


b a d c e _ b a d c _ b
1 2 3 4 5 ………. W 1 2 3 …… L

M
Входной поток символов

Рисунок 8.9. Иллюстрация функционирования


алгоритма LZ77

Чисто формально это можно трактовать и как последо-


вательное смещение (скольжение) слева направо M -
ячеечного ( M - символьного) окно последовательности
символов входного сообщения.
Допустим, что на текущий момент скользящее окно уже
заполнено символами, приведенными на рис.8.9. Зада-
чей алгоритма является отыскание в словаре (буфере
поиска) фрагмента текста, совпадающего в возможно
большей степени с содержимым упреждающего буфе-
ра. Одним из вариантов является совпадение буквы a ,
расположенной на 1 - ой позиции упреждающего буфе-
ра, с буквой a на позиции W словаря. Просматривая
словарь дальше, алгоритм обнаружит, что совпадаю-
щей будет подстрока adc , расположенная на позициях
2, 3 и 4 словаря, и подстрока adc на позициях 1, 2 и 3
упреждающего буфера. Кодер выбирает для кодирова-
ния самую длинную из совпадающих подстрок. При
наличии двух одинаковых по длительности совпадаю-
щих подстрок для кодирования в некоторых вариантах
5
реализации выбирается подстрока наиболее удаленная
от упреждающего буфера, а в других – самая близкая (у
каждого из них есть свои достоинства и недостатки).
Результат кодирования выбранной совпадающей под-
строки представляется в виде некоторого триплета ви-
да (p, l, s) , где p  [1, L] - номер позиции начала совпа-
дающей подстроки, l  [1, L] – длина совпадающих под-
строк, которая не может превышать L , S – первая (по-
сле совпадающей подстроки) буква в упреждающем
буфере, нарушающая совпадение. Для ситуации, пока-
занной на рис.8.9, кодом совпадающей подстроки adc
будет триплет (2,3, (_)) , где p  2 (номер позиции нача-
ла совпадающей подстроки), l  3 – длина совпадения
(число совпадающих последовательных символов по-
строки), S  (_) (где под “ (_) здесь понимается

знак пробела в тексте)*. Во многих случаях номер пози-
ции p указывается не по отношению к началу буфера
поиска, а по отношению к началу упреждающего буфе-
ра, т.е. указывается значения ( W  p) .
Если поиск в словаре не обнаружил никакого совпаде-
ния символов, то в качестве кода записывается триплет
(0,0, S), где в роли S выступает буква, находящаяся на
первой позиции упреждающего буфера.
Можно приближенно оценить размер в битах одного ко-
дового триплета. Для представления номера позиции p
достаточно log2 W бит, а длины совпадения ≈ log2 L
бит. Размер поля для представления символа S обыч-
но равен 8 бит (8 битовый код ASCII), а в общем случае
– log2 N , где N – размер алфавита источника.
____________________
*Следует заметить, что могут встречаться и такие ситуации,
когда совпадающая строка начинается в буфере поиска, а
заканчивается в упреждающем буфере.
6
После формирования кода совпадающей подстроки ок-
но сдвигается вправо (точнее, входной файл сдвигает-
ся влево на (1  1) окно) и начинается новый этап поиска
совпадающих подстрок и формирования соответству-
ющего им кода. В итоге, кодированное сообщение
представляет собой последовательность выра-женных
в двоичной форме кодовых триплетов, каждый из кото-
рых представляет собой код соответствующей подстро-
ки текста сообщения.
Эффективность сжатия будет тем выше, чем больше
размер W словаря (буфера поиска), так как повышает-
ся вероятность нахождения более длинных совпадаю-
щих подстрок. Однако при этом возрастают и вычисли-
тельные затраты на поиск.
Декодер метода LZ 77 гораздо проще кодера.
Декодер непосредственно из принимаемых последова-
тельно кодовых триплетов строит словарь, идентичный
словарю кодера. Для этого по принятой метке (p, l ) он
находит совпадения в своем буфере поиска, записыва-
ет совпадающие символы и символ из третьего поля S
в буфер и выдает их получателю.

Пример 8.11. Произвести кодирование и декодирова-


ние методом LZ 77 текста сообщения ” LZ 77LZ 77. ” с
общей длиной в 9 символов, полагая, что размер сло-
варя W  2 , а размер упреждающего буфера L  4 .

Решение:
а) Процедура кодирования
1. Начнем рассмотрение с того момента, когда упре-
ждающий буфер полностью заполнен первыми симво-
лами сообщения LZ 77 , а словарь (буфер поиска) еще
пуст и поэтому совпадающих подстрок нет. На выходе
кодера вырабатывается кодовый триплет (0,0, L) , где L
7
– некодированный символ на первой позиции упрежда-
ющего буфера (табл.8.9). После этого производится
сдвиг влево на одну позицию содержимого всего окна и
ввод справа в упреждающий буфер следующего сим-
вола сообщения L .
2. На следующем шаге словарь содержит единствен-
ный символ L , а на первой позиции упреждающего бу-
фера – символ Z . Совпадающих подстрок снова нет, и
кодер вырабатывает на выходе код (0,0, Z) , после чего
содержимое обоих буферов сдвигается влево на одну
позицию вводом справа нового символа сообщения Z
(таб.8.9).
3. В словаре содержатся символы LZ , а на первой по-
зиции упреждающего буфера символ 7 . Совпадения
нет и на выходе кодера появляется код (0,0,7) , после
чего осуществляется ввод справа следующего символа
текста 7 и сдвиг на 1 позицию влево всего содержимого
окна.
4. Словарь содержит символы LZ 7 на последних трех
своих позициях, а на первой позиции упреждающего
буфера – символ 7 , совпадающий с символом 7 на по-
следней позиции словаря. Это единственное совпаде-
ние подстрок. На выходе кодера вырабатывается код
(1,1, L) , где первый элемент триплета “ 1 ” означает, что
начало совпадающей подстроки в словаре находится
на одну позицию раньше начала упреждающего буфе-
ра; второй элемент ” 1 “ указывает, что длина совпада-
ющей подстроки – символ в упреждающем буфере.
Производится сдвиг влево содержимого окна на 2 пози-
ции.
По аналогичному алгоритму выполняются и последую-
щие шаги кодирования. Их результаты приведены в
табл. 8.10.

8
Таблица 8.10. Результаты кодирования и
декодирования в примере 8.11

Буфер поиска (сло- Упрежд. Вход Выход


Номер варь) буфер кодера декодера
шага
1 2 3 4 5 6 7 8 1 2 3 4 p l S
1 - - - - - - - - L Z 7 7 0 0 L L

2 - - - - - - - L Z 7 7 L 0 0 Z Z

3 - - - - - - L Z 7 7 L Z 0 0 7 7

4 - - - - - L Z 7 7 L Z 7 1 1 L 7L

5 - - - L Z 7 7 L Z 7 7 . 4 3 . Z77

Итог Z 7 7 L Z 7 7 . - - - - - - LZ77LZ77.

Таким образом, закодированный текст представляется


последовательностью триплетов:
(0,0, L) (0,0, Z) (0,0,7) (1,1, L) (4,3,) ,
где знаки проставлены лишь для удобства чтения. До-
пустим, что символы исходного текста представлены
8 - битным кодом ASCII, т.е. для представления данного
сообщения из 9 символов потребуется 9  8  72 бита, а
для кодированного текста
( log2 W  log2 L  8)  ( log2 8  log2 4  8  13 бит
для одного кодового триплета и 13  5  65 бит для всех
5 триплетов. Коэффициент сжатия:
K C  65  0.9 (90%).
72

б) Декодирование
1. При получении первого кодового триплета (0,0, L)
декодер выдает символ L , записывая его в выходной
буфер и одновременно в свой словарь на позиции 8
(табл.8.9).
9
2. При получении второго триплета (0,0, Z) декодер
записывает символ Z в выходной буфер и также в сло-
варь, в котором уже хранится и символ L на позициях,
соответствующих состоянию словаря кодера на шаге 3
(табл.8.9).
3. В результате обработки третьего триплета (0,0,7)
декодер записывает символ 7 в выходной буфер и в
словарь, состояние которого теперь идентично состоя-
нию словаря кодера на шаге 4 (табл.8.9).
4. При получении триплета (1,1, L) декодер извлека-
ет из своего словаря символ 7 , соответствующий сов-
падающей подстроке, находящийся на первой по отно-
шению к концу словаря позиции (поз.8 в таб.8.9), до-
бавляя к нему символ L в выходной буфер и рабочий
словарь дуплет символов 7L . Состояние словаря
декодера примет вид, аналогичный состоянию словаря
кодера на шаге 5 (табл. 8.9).
5. После приема триплета (4,3,) декодер возвраща-
ется в словаре на 4 шага назад, извлекает из него сов-
падающую подстроку длительностью в 3 символа Z77
и, добавляя к ней символ “  ”, записывает в выходной
буфер 4 – х-символьную последовательность Z77 . По-
скольку других кодовых триплетов на декодер не посту-
пает, то на этом процесс декодирования завершается,
а в его выходном буфере можно прочесть результиру-
ющий текст сообщения LZ 77LZ 77 , который соответ-
ствует исходному сообщению.
Помимо базового алгоритма LZ 77 используются
и разработанные другими авторами его модификации, в
которых сделаны попытки устранения некоторых недо-
статков LZ 77 . Одной из таких популярных модифика-
ций является алгоритм LZSS , который в 1982 г. разра-
ботали Сторер (Storer) и Жимански (Szumanski). Он
улучшает алгоритм LZ 77 по трем направлениям:

10
1) упреждающий буфер использует циклическую оче-
редь;
2) буфер поиска хранится в виде дерева двоичного
поиска, что уменьшает время поиска совпадающих
подстрок;
3) предложен более экономный способ построения
кодов, что позволяет добиться некоторого уменьшения
в среднем длины кодированного сообщения, т.е. повы-
сить степень сжатия.
Cуществуют и алгоритмы LZB (Белл (Bell), 1987),
LZH (Брент (Brent), 1987), LZRW 1 (Уилльямс
(Williams), 1991), являющиеся модификациями LZSS ,
LZFG (Фиала, Грин (Fiala, Greene), 1989), LZCB (Блум
(Bloum), 1995), представляющие собой модификации
LZ 77, и др.

11