Алгоритм Ше́ннона — Фанó — один из первых алгоритмов сжатия, который впервые сформулировали американские учёные Клод Шеннон и Роберт Фано.
- Символы первичного алфавита m1 выписывают по убыванию вероятностей.
- Символы полученного алфавита делят на две части, суммарные вероятности символов которых максимально близки друг другу.
- В префиксном коде для первой части алфавита присваивается двоичная цифра «0», второй части — «1».
- Полученные части рекурсивно делятся, и их частям назначаются соответствующие двоичные цифры в префиксном коде.
Когда размер подалфавита становится равен нулю или единице, то дальнейшего удлинения префиксного кода для соответствующих ему символов первичного алфавита не происходит, таким образом, алгоритм присваивает различным символам префиксные коды разной длины.
O(n logn)
При построении кода Шеннона — Фано разбиение множества элементов может быть произведено, вообще говоря, несколькими способами. Выбор разбиения на уровне n может ухудшить варианты разбиения на следующем уровне (n + 1) и привести к неоптимальности кода в целом. Другими словами, оптимальное поведение на каждом шаге пути ещё не гарантирует оптимальности всей совокупности действий. Поэтому код Шеннона — Фано не является оптимальным в общем смысле, хотя и дает оптимальные результаты при некоторых распределениях вероятностей. Для одного и того же распределения вероятностей можно построить, вообще говоря, несколько кодов Шеннона — Фано, и все они могут дать различные результаты.
Создать файл data.txt, в который передать 1 строкой символы, 2 строкой их вероятности, 3 строкой сообщение
Пример
a b c d e
0.2 0.1 0.3 0.2 0.2
abbdeecacbdddee
Команда для запуска
python fano.py
Преобразование Барроуза — Уилера (Burrows-Wheeler transform, BWT, также исторически называется блочно-сортирующим сжатием, хотя сжатием и не является) — это алгоритм, используемый в техниках сжатия данных для преобразования исходных данных.
- Составляется таблица всех циклических сдвигов входной строки.
- Производится лексикографическая (в алфавитном порядке) сортировка строк таблицы.
- В качестве выходной строки выбирается последний столбец таблицы преобразования и номер строки, совпадающей с исходной.
Декодирование:
Выпишем в столбик нашу преобразованную последовательность символов. Запишем её как последний столбик предыдущей матрицы (при прямом преобразовании Барроуза — Уилера), при этом все предыдущие столбцы оставляем пустыми. Далее построчно отсортируем матрицу, затем в предыдущий столбец запишем преобразованную последовательность. Опять построчно отсортируем матрицу. Продолжая таким образом, можно восстановить полный список всех циклических сдвигов строки, которую нам надо найти. Выстроив полный отсортированный список сдвигов, выберем строку с номером, который нам был изначально дан.
O(N^2*logN)
Передать в функцию bw_restore первым аргументов - индекс, вторым аргументов - закодированное сообщение
Пример
bw_restore(24, 'styssesvmrgath ceiis eee r')
Команда для запуска
python bwt.py
Алгори́тм Ле́мпеля — Зи́ва — Уэлча (Lempel-Ziv-Welch, LZW) — это универсальный алгоритм сжатия данных без потерь, созданный Авраамом Лемпелем (англ. Abraham Lempel), Яаковом Зивом (англ. Jacob Ziv) и Терри Велчем (англ. Terry Welch).
- Все возможные символы заносятся в словарь. Во входную фразу X заносится первый символ сообщения.
- Считать очередной символ Y из сообщения.
- Если Y — это символ конца сообщения, то выдать код для X, иначе: Если фраза XY уже имеется в словаре, то присвоить входной фразе значение XY и перейти к Шагу 2 , Иначе выдать код для входной фразы X, добавить XY в словарь и присвоить входной фразе значение Y. Перейти к Шагу 2. Конец.
Декодирование
Декодер LZW сначала считывает индекс (целое число), ищет этот индекс в словаре и выводит подстроку, связанную с этим индексом. Первый символ этой подстроки конкатенируется с текущей рабочей строкой. Эта новая конкатенация добавляется в словарь (подобно тому, как подстроки были добавлены во время сжатия). Затем декодированная строка становится текущей рабочей строкой (текущий индекс, т.е. подстрока, запоминается), и процесс повторяется.
O(n), так как каждый байт читается только один раз, а сложность операции для каждого символа константна.
Передать в функцию decode первым аргументов - путь до закодированного файла, вторым аргументов - количество бит
Пример
decode("data2_encoded.txt", 8)
Команда для запуска
python lzw.py