Skip to content

albshady/compression

Repository files navigation

Отчет по лабораторной работе №1

Описание алгоритмов

Данные алгоритмы написаны на языке Python 3.7, для запуска можно использовать стандартный интерпретатор CPython, но для достижения большей производительности настоятельно рекомендуется использовать PyPy, имеющий встроенный JIT-компилятор.

К примеру, тестовый файл pic, объемом 501Кб CPython сжимает за 25 минут, в то время как PyPy выполняет эту операцию всего за 10 секунд.

Алгоритм компрессии

Алгоритм компрессии состоит из двух последовательных алгоритмов начального преобразования, по результату работы которых получается много одинаковых символов. После этого над преобразованным текстом применяется кодирование Хаффмана, эффективность которого повышается из-за обилия одинаковых символов, чьи коды будут наиболее короткими.

Burrows-Wheeler transformation

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

Было бы нецелесообразным генерировать все циклические сдвиги из-за больших затрат по памяти (n^2) и по времени (n^2), поэтому был написан компаратор сдвигов, который сравнивает два циклических сдвига, используя индексы, и проходит по самому блоку не создавая сдвиги.

Move to Front transformation

После преобразования Барроуза-Уиллера блок содержит много подряд идущих одинаковых символов. Алгоритм перемещения к началу подразумевает наличие исходного упорядоченного алфавита. Далее читается символ из блока, возвращается его индекс в алфавите, а символ переставляется в начало алфавита. Таким образом, все подряд идущие одинаковые символы превращаются в 0, за исключением первого в серии, что сильно повышает количество нулей в блоке.

Huffman coding

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

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

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

Алгоритм декомпрессии

Соответсвенно, в алгоритме декомпрессии будут декодированы символы из файла при помощи алгоритма Хаффмана, полученный символ будет являться индексом в алфавите из трансформации перемещия к началу, следовательно, найдется исходный символ, после чего полученный таким образом блок будет преобразован в исходный текст алгоритмом обратного преобразования Барроуза-Уиллера.

Huffman decoding

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

Reverse Move to Front transformation

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

Reverse Burrows-Wheeler transformation

У преобразования Барроуза-Уиллера есть свойство, что одинаковые символы из последней колонки идут в таком же порядке, как и в первой колонке. Доказательство этого простое: предположим у нас есть последняя колонка ccbacaa. Поскольку строки - отсортированные циклические сдвиги, то первая колонка была бы aaabccc. При этом если мы пронумеруем одинаковые символы из первой колонки - a1a2a3b1c1c2c3, то символ a1 окажется перед символами a2 и a3, поскольку строка, состоящая из следующих за ним символов будет в результате сортировки выше, чем строки, состоящие из следующих за другими символами a. Следовательно, одинаковые символы в последней колонке стоят в порядке, в котором были отсортированы строки из символов, состоящих до последнего. А поскольку представлены циклические сдвиги, то строка из символов до символа в последней колонке - это та же строка, что и строка из символов после символа в первой колонке. Значит, одинаковые символы в последней колонке идут в таком же порядке, как и в первой колонке: c1c2b1a1c3a2a3.

Блок, пришедший на вход обратному преобразованию Барроуза-Уиллера - последняя колонка матрицы сдвигов. Поскольку известно, что последний символ исходного блока это символ конца блока, начав с него и используя переход от последнего символа к первому, получится восстановить исходный блок в правильной последовательности.

Результаты

file name H(X) H(X | X) H(X | XX) значение средних затрат на символ (в битах) размер сжатого файла (в байтах) размер исходного файла (в байтах)
bib 5.20065 3.36413 2.30750 2.395017 33309 111261
book1 4.52714 3.58451 2.81407 2.781270 267270 768771
book2 4.79262 3.74520 2.73566 2.450096 187082 610856
geo 5.64637 4.26419 3.45769 5.428438 69484 102400
news 5.18962 4.09188 2.92274 2.834342 133607 377109
obj1 5.94815 3.46364 1.40042 4.354167 11704 21504
obj2 6.26035 3.87036 2.26541 2.873549 88654 246814
paper1 4.98290 3.64606 2.33176 2.757059 18321 53161
paper2 4.60138 3.52222 2.51353 2.747089 28226 82199
pic 1.21018 0.82365 0.70519 1.582102 101495 513216
progc 5.19893 3.60338 2.13400 2.785489 13792 39611
progl 4.77004 3.21158 2.04353 2.103565 18839 71646
progp 4.86871 3.18733 1.75509 2.093360 12921 49379
trans 5.53275 3.35478 1.93048 1.919761 22484 93695

Releases

No releases published

Packages

No packages published

Languages