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

Для того, щоб зберігати й передавати дані, часто корисно (а іноді навіть необхідно) зменшити розмір цих даних. Метод, що використовується для цього, називається стисненням даних (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:

 

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

 

Рисунок 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

 



/footer.php"; ?>