Файл: Технологии программирования (Возникновение теории кодирования).pdf

ВУЗ: Не указан

Категория: Курсовая работа

Дисциплина: Не указана

Добавлен: 25.04.2023

Просмотров: 549

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

2. Основные методы кодирования данных

2.1 Кодирование целых чисел

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

Каждому целому числу из определенного диапазона ставится в соответствие свое кодовое слово. Поэтому эту группу методов также называют представлением целых чисел (representation of integers).

Основная идея кодирования целых чисел: отдельно кодировать порядок значения элемента («экспоненту» ) и отдельно – значащие цифры значения («мантиссу» i).

Значащие цифры мантиссы начинаются со старшей ненулевой цифры, порядок числа определяется позицией старшей ненулевой цифры в двоичной записи числа.

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

Пример:

Двоичное число 000001101
Порядок равен 4, мантисса – 1101

Рассмотрим две группы методов кодирования целых чисел. Условно их можно обозначить так:

  • Fixed + Variable (фиксированная длина порядка + переменная длина мантиссы)
  • Variable + Variable (переменная длина порядка + переменная длина мантиссы)

В кодах класса Fixed + Variable под запись значения порядка числа отводится фиксированное количество бит, а значение порядка числа определяет, сколько бит потребуется под запись мантиссы.

Для кодирования целого числа необходимо произвести с числом две операции:

  • определение порядка числа
  • выделение бит мантиссы

Можно также хранить в памяти заранее построенную таблицу кодовых слов и по ней получать код числа.

2.1.1 Код класса Fixed + Variable

Пусть R = 15 – количество бит исходного числа.

Отведем E = 4 бита под порядок, т.к. R ≤ 24.

При записи мантиссы можно сэкономить 1 бит: не писать первую единицу, т.к. это всегда будет только единица.

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

Таблица 1

Коды чисел класса Fixed + Variable


Число

Двоичное представление

Кодовое слово

Длина кодового слова

0

1

000000000000000

000000000000001

0000

0001

4

2

3

000000000000010

000000000000011

0010 0

0010 1

5

4

5

6

7

000000000000100

000000000000101

000000000000110

000000000000111

0011 00

0011 01

0011 10

0011 11

6

8

9

10

15

000000000001000

000000000001001

000000000001010

000000000001111

0100 000

0100 001

0100 010

0100 111

7

16

17

000000000010000

000000000010001

0101 0000

0101 0001

8

2.1.2 Код класса Variable + Variable

В качестве кода числа берется двоичная последовательность, построенная следующим образом: несколько нулей (количество нулей равно значению порядка числа), затем мантисса переменной длины.

Таблица 2

Коды чисел класса Variable + Variable

Число

Двоичное представление

Кодовое слово

Длина кодового слова

0

1

00000000000

00000000001

00

01

1

2

2

3

00000000010

00000000011

00 10

00 11

4

4

5

6

7

00000000100

00000000101

00000000110

00000000111

000 100

000 101

000 110

000 111

6

8

9

10

00000001000

00000001001

00000001010

0100 000

0100 001

0100 010

8


Если в рассмотренном выше коде исключить кодовое слово для нуля, то можно уменьшить длины кодовых слов на 1 бит, убрав первый нуль во всех кодовых словах. Таким образом строится гамма-код Элиаса (γ-код Элиаса).

Таблица 3

γ-код Элиаса

Число

Кодовое слово

Длина кодового слова

1

1

1

2

3

0 10

0 11

3

4

5

6

7

00 100

00 101

00 110

00 111

5

8

9

10

000 1000

000 1001

00 1010

7

Другим примером кода класса Variable + Variable является омега-код Элиаса (ω-код Элиаса).

В нем первое значение (кодовое слово для единицы) задается отдельно. Другие кодовые слова состоят из последовательности групп длиной L1 L2 …Lm , начинающихся с единицы.

Конец всей последовательности задается нулевым битом.

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

Значение битов последней группы является итоговым значением всей последовательности групп, т.е. первые m-1 групп служат лишь для указания длины последней группы, которая содержит собственно мантиссу числа.

Таблица 4

ω-код Элиаса

Число

Кодовое слово

Длина кодового слова

1

2

3

0

10 0

11 0

1

3

3

4

5

6

7

10 100 0

10 101 0

10 110 0

10 111 0

6

6

6

6

8

9

..

15

11 1000 0

11 1001 0

..

11 1111 0

7

7

..

7

16

17

..

31

10 100 10000 0

10 100 10001 0

..

10 100 11111 0

11

11

..

11

32

10 101 100000 0

12


В омега-коде Элиаса (P. Elias):

При кодировании формируется сначала последняя группа, затем предпоследняя и т.д., пока процесс не будет завершен.

При декодировании, наоборот, сначала считывается первая группа, по значению ее битов определяется длина следующей группы, или итоговое значение числа, если следующая группа – 0.

  • Рассмотренные типы кодов могут быть эффективны в следующих случаях:
  • Вероятности чисел убывают с ростом значений элементов и их распределение близко к такому: P(x) ≥ P(x+1), при любом x, т.е. маленькие числа встречаются чаще, чем большие.
  • Диапазон значений входных элементов не ограничен или неизвестен.
    Например, при кодировании 32-битовых чисел реально большинство чисел маленькие, но могут быть и большие.
  • При использовании в составе других схем кодирования, например, кодировании длин серий.

2.2 Кодирование длин серий

Метод кодирования длин серий (RLE), предложенный П. Элиасом (P.Elias), при построении использует коды целых чисел. Входной поток для кодирования рассматривается как последовательность из нулей и единиц.

Идея кодирования заключается в том, чтобы кодировать последовательности одинаковых элементов (например, нулей) как целые числа, указывающие количество элементов в этой последовательности.

Последовательность одинаковых элементов называется серией, количество элементов в ней – длиной серии.

2.2.1 Пример кодирования длин серий

Входную последовательность (31 бит) можно разбить на серии, а затем закодировать их длины.

000000 1 00000 1 0000000 1 1 00000000 1

Длины серий нулей: 6 5 7 0 8

Используем, например, γ-код Элиаса.

Поскольку в γ-коде Элиаса нет кодового слова для нуля,то будем кодировать длину серии +1: 65708 ⇒ 76819

7 6 8 1 9 ⇒ 00111 00110 0001000 1 0001001

Длина полученной кодовой последовательности 25 бит.

Метод длин серий актуален для кодирования данных, в которых есть длинные последовательности одинаковых бит. В нашем примере, если P(0)>>P(1).

2.3 Код Хафмана

Код Хаффмана (англ. Huffman's algorithm) — алгоритм оптимального префиксного кодирования алфавита. Разработан в 1952 году аспирантом Массачусетского технологического института Дэвидом Хаффманом при написании им курсовой работы. [7]


Кодирование Хаффмана широко применяется при сжатии данных, в том числе при сжатии фото- и видеоизображений (JPEG, MPEG), в популярных архиваторах (PKZIP, LZH и др.), в протоколах передачи данных HTTP (Deflate), MNP5 и MNP7 и других. [3]

В 2013 году была предложена модификация алгоритма Хаффмана, позволяющая кодировать символы дробным количеством бит — ANS. На базе данной модификации реализованы алгоритмы сжатия Zstandard (Zstd, Facebook, 2015—2016) и LZFSE[fr] (Apple, OS X 10.11, iOS 9, 2016).

2.3.1 Определение

Пусть A={a1,a2,…,an} — алфавит из n различных символов, W={w1,w2,…,wn} — соответствующий ему набор положительных целых весов. Тогда набор бинарных кодов C={c1,c2,…,cn}, где ci является кодом для символа ai, такой, что:

ci не является префиксом для cj, при i≠j,

cумма ∑i∈[1,n]wi⋅|ci| минимальна (|ci| — длина кода ci),

называется кодом Хаффмана.[7]

2.3.2 Алгоритм построения бинарного кода Хаффмана

Построение кода Хаффмана сводится к построению соответствующего бинарного дерева по следующему алгоритму:

  1. Составим список кодируемых символов, при этом будем рассматривать один символ как дерево, состоящее из одного элемента c весом, равным частоте появления символа в строке.
  2. Из списка выберем два узла с наименьшим весом.
  3. Сформируем новый узел с весом, равным сумме весов выбранных узлов, и присоединим к нему два выбранных узла в качестве детей.
  4. Добавим к списку только что сформированный узел вместо двух объединенных узлов.
  5. Если в списке больше одного узла, то повторим пункты со второго по пятый.

2.3.3 Время работы

Если сортировать элементы после каждого суммирования или использовать приоритетную очередь, то алгоритм будет работать за время O(N log N).Такую асимптотику можно улучшить до O(N), используя обычные массивы.

2.3.4 Пример выполнения алгоритма

Закодируем слово abracadabra. Тогда алфавит будет A={a,b,r,c,d} а набор весов (частота появления символов алфавита в кодируемом слове) W={5,2,2,1,1}. Графическое представление можно посмотреть в приложении на рисунке 4.