Арифметическое кодирование — различия между версиями
Borisov (обсуждение | вклад) м |
(→Кодирование) |
||
Строка 16: | Строка 16: | ||
while !eof | while !eof | ||
read(symb) | read(symb) | ||
− | newRight = left + (right - left) * segment[symb].right <span style="color:green"> //segment[symb] — подотрезок отрезка [0; 1), соответствующий символу symb </span> | + | newRight = left + (right - left) * segment[symb].right <span style="color:green"> //segment[symb] — подотрезок отрезка [0; 1), |
+ | //соответствующий символу symb </span> | ||
newLeft = left + (right - left) * segment[symb].left | newLeft = left + (right - left) * segment[symb].left | ||
left = newLeft | left = newLeft |
Версия 14:08, 8 января 2014
Содержание
Определение
Арифметическое кодирование (Arithmetic coding) — алгоритм сжатия информации без потерь, который при кодировании ставит в соответствие тексту вещественное число из отрезка алгоритм Хаффмана) является энтропийным т.е. длина кода конкретного символа зависит от частоты встречаемости этого символа в тексте. Арифметическое кодирование показывает более высокие результаты сжатия, чем алгоритм Хаффмана, для данных с неравномерными распределениями вероятностей кодируемых символов. Кроме того, при арифметическом кодировании каждый символ кодируется нецелым числом бит, что эффективнее кода Хаффмана (теоретически символу с вероятностью появления допустимо ставить в соответствие код длины , следовательно при кодировании Хаффманом это достигается только с вероятностями, равными обратным степеням двойки).
. Данный метод (как иПринцип действия
Кодирование
Алгоритму передаются текст для кодирования и список частот встречаемости символов.
- Рассмотрим отрезок на координатной прямой.
- Поставим каждому символу текста в соответствие отрезок, длина которого равна частоте его появления.
- Считаем символ из входного потока и рассмотрим отрезок, соответствующий этому символу. Этот отрезок разделим на части, пропорциональные частотам встречаемости символов.
- Повторим пункт (3) до конца входного потока.
- Выберем любое число из получившегося отрезка. Это и будет результат арифметического кодирования.
left = 0
right = 1
while !eof
read(symb)
newRight = left + (right - left) * segment[symb].right //segment[symb] — подотрезок отрезка [0; 1),
//соответствующий символу symb
newLeft = left + (right - left) * segment[symb].left
left = newLeft
right = newRight
ans = (left + right) / 2
Декодирование
Алгоритм по вещественному числу восстанавливает исходный текст.
- Выберем на отрезке , разделенном на части, длины которых равны вероятностям появления символов в тексте, подотрезок, содержащий входное вещественное число. Символ, соответствующий этому подотрезку, дописываем в ответ.
- Нормируем подотрезок и вещественное число.
- Повторим п. (1-2) до тех пор, пока не получим ответ (до конца файла).
do for i = 1 to n if code >= segment[i].left && code < segment[i].right write(segment[i].character) code = (code – segment[i].left) / (segment[i].right – segment[i].left) break while (segment[i].character != eof)
Замечание
Ккодировщику и декодировщику должно быть известно, когда завершать работу. Для этого можно передавать в качестве аргумента длину текста или символ конца файла, после которого процесс должен быть остановлен.
Для оптимизации размера кода необходимо выбрать из окончательного диапазона число, содержащее наименьшее количество знаков в двоичной записи.
Пример работы
Рассмотрим в качестве примера строку
Кодирование
Символ | Частота появления |
---|---|
| |
| |
|
Считанный символ | Левая граница отрезка | Правая граница отрезка |
---|---|---|
| ||
| ||
| ||
| ||
| ||
| ||
| ||
|
Код:
Декодирование
Код:
Декодируемый символ | Код |
---|---|
| |
| |
| |
| |
| |
| |
|
Замечание
При декодировании текста можно не только нормализовывать рабочий отрезок и текущий код, но и уменьшать рабочий отрезок (аналогично кодированию), не изменяя значение кода.
Декодирование (второй способ)
Код:
Декодируемый символ | Границы отрезка | |||
---|---|---|---|---|
| ||||
| ||||
| ||||
| ||||
| ||||
| ||||
|
Оценка длины кодового слова
Теорема: |
При арифметическом кодировании длина кодового слова не превышает энтропии исходного текста. |
Доказательство: |
Размер сообщения Число бит в закодированном тексте: ( - длина текста; - размер алфавита; - частота встречаемости символа; - вероятность вхождения символа) |