Проблема стиснення інформації

Для того, щоб зберігати й передавати дані, часто корисно (а іноді навіть необхідно) зменшити розмір цих даних. Метод, що використовується для цього, називається стисненням даних (data compression). Одним із загальних методів стиснення даних є частотно-залежне кодування (frequency-dependent encoding), у якому довжина коду елемента інформації обернено пропорційна частоті використання цього елемента. Ці коди є прикладами кодів змінної (нерівномірної) довжини (variable-length codes), що означає представлення елементів інформації послідовностями різної довжини, на відміну від таких кодів, як Unicode, у якому всі символи представлені 16-бітовими послідовностями. Майже всі частотно-частотно-залежні коди, що використовуються сьогодні - це коди Хафмана (Huffman codes).

Завдання оптимізації кодування можна сформулювати наступним чином: побудувати таку схему кодування, в якій сумарна довжина кодів при передачі (або сумарне число кодів при зберіганні) даного повідомлення була б найменшою.

3.2 Рівномірне кодування

Рівномірні коди мають однакову довжину для всіх символів початкового алфавіту. Розглянемо цей вид кодування на наступному прикладі: нехай є початковий алфавіт А, що складається з N = 6 знаків а1...а6 з ймовірностями їх появи в кодованому повідомленні 0,3; 0,2; 0,2; 0,15; 0,1; 0,05. Мінімальне значення середньої довжини рівномірного двійкового коду можна визначити за формулою:

Kрівн.к.(A, 2) ³ log2N,

де N - число знаків початкового алфавіту.

У нашому прикладі K(A, 2)рівн.к.min ³ log26 ≈ 2,58 Þ K.(A, 2)рівн.к. = 3. Один з можливих варіантів кодування записаний в таблиці 3.1.

Визначимо відносну надлишковість отриманого рівномірного двійкового коду Q(A,2):

Q(A,2) = ( K(A, 2) × I(B) ) / I(A) – 1, де (3.1)

I(A) – середня кількість інформації на знак початкового алфавіту A:

I(A) = - å pi log2 pi, біт,

де pi = ni/n – ймовірність появи i-го символу початкового алфавіту, ni – кількість повторень i-го символу в кодованому повідомленні, n – довжина кодованого повідомлення.

Для заданого алфавіту А одержимо:

I(A) = - (0,3 × log20,3 + 0,2 × log20,2 + 0,2 × log20,2 +0,15 × log20,15 + 0,1 ´ log20,1+ 0,05 × log20,05) ≈ 2,409 біт.

Нехай I(B) - середня кількість інформації на знак вторинного алфавіту B. З урахуванням того, що для кодування використано двійковий алфавіт:

I(2) = - å pi log2 pi = - (p0log2 p0 + p1log2 p1), біт, (3.2)

де p0 – імовірність появи 0 у коді, p0 = m0/m,

p1 – імовірність появи 1 у коді, p1 = 1 - p0,

m0 – кількість появи 0 у закодованому повідомленні,

m – загальна кількість символів у закодованому повідомленні.

Якщо m0 і m не відомі, тоді p0 можна визначити за формулою:

p0 = å (pi × p(i)0) = å (pi × (k(i)0 / k(i))), (3.3)

де i = 1..N,

pi – імовірність появи i-го символу початкового алфавіту,

p(i)0 – імовірність появи 0 у коді i-го символу початкового алфавіту,

k(i) – довжина коду i-го символу початкового алфавіту,

k(i)0 – кількість цифр 0 у коді i-го символу початкового алфавіту.

Для складеного в таблиці 3.1 рівномірного двійкового коду, маємо:

p0рівн.к. = 0,3 × 3/3 + 0,2 × 2/3 + 0,2 × 2/3 + 0,15 × 1/3 + 0,1 × 2/3 + 0,05 × 1/3 = 0,7.

Тоді, згідно (3.2), I(2) рівн.к. = - (p0рівн.к. × log2 p0рівн.к. + (1 - p0рівн.к.) × log2 (1 - p0рівн.к.)) = = - (0,7 × log20,7 + 0,3 × log20,3) ≈ 0,881 біт.

За формулою (3.1) маємо: Q(A,2)рівн.к. = ( K(A, 2)рівн.к. × I(2)рівн.к. ) / I(A) – 1 =
= 3 × 0,881 / 2,409 – 1 ≈ 0,101.

3.3 Алфавітне кодування в префіксний код Хафмана.

Префіксні коди задовольняють наступній умові (умові Фано): нерівномірний код може бути однозначно декодований, якщо ніякий з кодів не збігається з початком (префіксом) будь-якого іншого довшого коду.

Використання префіксного кодування дозволяє робити повідомлення коротшим, оскільки немає необхідності передавати роздільники знаків. Однак умова Фано не встановлює спосіб формування префіксного коду і, зокрема, найкращий з можливих.

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

Побудову кодів Хафмана розглянемо на тому ж прикладі 3.1. Розташуємо знаки початкового алфавіту в таблиці в порядку зменшення ймовірностей. Створимо новий допоміжний алфавіт А1, об'єднавши два знаки з найменшими ймовірностями (а5 й а6) і замінивши їх одним знаком (наприклад, а(1)); ймовірність нового знаку буде дорівнювати сумі ймовірностей тих знаків попереднього проміжного алфавіту, що в нього увійшли, тобто 0,15. Інші знаки вихідного алфавіту включимо в новий без змін. Загальне число знаків у новому алфавіті, зрозуміло, буде на 1 менше, ніж у вихідному. Аналогічним чином продовжимо створювати нові алфавіти, поки в останньому не залишиться два знаки; очевидно, що кількість таких кроків буде дорівнювати N - 2, де N - число знаків початкового алфавіту (у нашому випадку N = 6, отже, необхідно побудувати 4 допоміжних алфавіти). У проміжних алфавітах щораз будемо перевпорядковувати знаки по зменшенню ймовірностей.

Далі у зворотному напрямку потрібно виконати процедуру кодування. Двом знакам останнього алфавіту присвоїмо коди 0 і 1 (порядок присвоєння не має значення; домовимось, що верхній знак буде мати код 0, а нижній - 1). У нашому прикладі знак a1(4) алфавіту А(4), щомає імовірність 0,6 , отримає код 0, a a2(4) з імовірністю 0,4 - код 1. В алфавіті А(3) знак a1(3)отримає від a2(4) його імовірність 0,4 і код (1); коди знаків a2(3)і a3(3), що виникли від знаку a1(4) з імовірністю 0,6, будуть вже двозначним: їх першою цифрою стане код їх попередника (тобто 0), а друга цифра - як домовлено раніше - у верхнього 0, у нижнього – 1. Таким чином, a2(3) буде мати код 00, а a3(3) - код 01. Повністю процедура кодування представлена на рисунках 3.1, 3.2:

Проблема стиснення інформації - student2.ru

Рисунок 3.1 – Схема побудови проміжних алфавітів префіксного коду Хафмана

Проблема стиснення інформації - student2.ru

Рисунок 3.2 – Схема побудови кодування в префіксний код Хафмана

Із процедури побудови кодів явно видно, що вони задовольняють умові Фано і тому не вимагають спеціального роздільника при передачі і збереженні.

Середня довжина отриманого префіксного коду:

K(А,2)= å (pi × k(i)),

де i = 1..N,

pi – імовірність появи i-го символу початкового алфавіту,

k(i) – довжина коду i-го символу початкового алфавіту.

В нашому випадку:

K(А,2)преф.к. = 0,3 × 2 + 0,2 × 2 + 0,2 × 2 +0,15 × 3 + 0,1 × 4 + 0,05 × 4 = 2,45.

Згідно (3.3) p0преф.к. = å (pi × (k(i)0/ k(i))) = 0,3 × 2/2 + 0,2 × 1/2 + 0,2 × 0/2 + 0,15 × × 2/3 + 0,1 × 2/4 + 0,05 × 1/4 = 0,563.

p1 = 1 - p0 = 1 - 0,563 = 0,437.

Визначимо середню кількість інформації на знак вторинного алфавіту отриманого префіксного коду. За формулою (3.2) маємо:

I(2) преф.к.. = - (p0преф.к. log2 p0преф.к. + (1 - p0преф.к log2 (1 - p0преф.к.) = - (0,563 ×
× log20,563 + 0,437 × log20,437) ≈ 0,988 біт.

Відносні надмірність коду згідно (3.1) дорівнює:

Q(A,2)преф.к. = (K(A,2)преф.к. × I(2)преф.к.) / I(A) – 1 = 2,45 × 0,988 / 2,409 – 1 ≈ 0,005.

Результати обчислень рівномірного двійкового коду й префіксного коду Хафмана відображені в таблиці 3.2. Звідси можна зробити висновок, що префіксний код Хафмана є значно оптимальнішим, ніж мінімальний за довжиною рівномірний двійковий код, тому що 1) містить на 12% більше інформації I(2) завдяки меньшій різниці значення p0 й p1, 2) має на 22% меншу середню довжину коду на один символ початкового алфавіту, а також 3) є в 20 разів менш надлишковим.

Таблиця 3.1 – Результати алфавітного кодування символів із прикладу 3.1 в рівномірний двійковий код і нерівномірний префіксний код Хафмана

Символ початкового алфавіту A Вірогідність появи аi у вхідному повідомленні Рівномірний двійковий код Префіксний код Хафмана
а1 0,3
а2 0,2
а3 0,2
а4 0,15
а5 0,1
а6 0,05

Таблиця 3.2 – Порівняльні результати кодування тексту

Вид кодування I(A) p0 p1 I(2) K(A,2) Q(A,2)
Рівномірний двійковий код 2,409 0,7 0,3 0,881 0,101
Префіксний код Хафмана 2,409 0,563 0,437 0,988 2,45 0,005

Наши рекомендации