7
правок
Изменения
Отмена правки 81085, сделанной Капелюшок Георгий Александрович ([[User talk:Капелюшок Георгий Ал…
{{Определение
|definition=
'''Арифметическое кодирование''' (англ. ''Arithmetic coding'') {{---}} алгоритм сжатия информации без потерь, который при кодировании ставит в соответствие тексту вещественное число из отрезка <tex>[0; 1)</tex>.
Данный метод, как и [[Алгоритм Хаффмана|алгоритм Хаффмана]], является [[Энтропия случайного источника|энтропийным]], т.е. то есть длина кода конкретного символа зависит от частоты встречаемости этого символа в тексте. Арифметическое кодирование показывает более высокие результаты сжатия, чем алгоритм Хаффмана, для данных с неравномерными распределениями вероятностей кодируемых символов. Кроме того, при арифметическом кодировании каждый символ кодируется нецелым числом бит, что эффективнее кода Хаффмана (теоретически, символу <tex>a</tex> с вероятностью появления <tex>p(a)</tex> допустимо ставить в соответствие код длины <tex>-\log_2 p(a)</tex>, следовательно, при кодировании алгоритмом Хаффмана это достигается только с вероятностями, равными обратным степеням двойки).}}
== Принцип действия ==
При арифметическом кодировании каждый символ кодируется нецелым числом бит, что эффективнее кода Хаффмана (теоретически, символу <tex>a</tex> с вероятностью появления <tex>p(a)</tex> допустимо ставить в соответствие код длины <tex>-\log_2 p(a)</tex>, следовательно, при кодировании алгоритмом Хаффмана это достигается только с вероятностями, равными обратным степеням двойки).
=== Кодирование ===
На вход алгоритму передаются текст для кодирования и список частот встречаемости символов.
# Поставим каждому символу текста в соответствие отрезок, длина которого равна частоте его появления.
# Считаем символ из входного потока и рассмотрим отрезок, соответствующий этому символу. Разделим этот отрезок на части, пропорциональные частотам встречаемости символов.
# Повторим пункт <tex>(3) </tex> до конца входного потока.
# Выберем любое число из получившегося отрезка, которое и будет результатом арифметического кодирования.
*<math>\mathtt{left}\,</math>, <math>\mathtt{right}\,</math> {{---}} границы отрезка, содержащего возможный результат арифметического кодирования.
'''struct''' Segment:
'''double''' left
right = newRight
'''return''' (left + right) / 2
'''Замечание:''' для оптимизации размера кода можно выбрать из полученного на последнем шаге диапазона <tex>[left; right]</tex> число, содержащее наименьшее количество знаков в двоичной записи.
# Выберем на отрезке <tex>[0; 1)</tex>, разделенном на части, длины которых равны вероятностям появления символов в тексте, подотрезок, содержащий входное вещественное число. Символ, соответствующий этому подотрезку, дописываем в ответ.
# Нормируем подотрезок и вещественное число.
# Повторим пункты <tex>1</tex>{{---}}<tex>2 </tex> до тех пор, пока не получим ответ.
=== Псевдокод ===
** <math>\mathtt{character}\,</math> {{---}} значение символа.
'''struct''' Segment:
'''double''' left
'''for''' i = 0 '''to''' n - 1
'''for''' j = 0 '''to''' m - 1
'''if''' code <tex>\small{~\geqslant~}</tex>= segment[j].left '''and''' code < segment[j].right
s += segment[j].character
code = (code – segment[j].left) / (segment[j].right – segment[j].left)
'''break'''
'''return''' s
'''Замечание:''' кодировщику и декодировщику должно быть известно, когда завершать работу. Для этого можно передавать в качестве аргумента длину текста или символ конца файла, после которого процесс должен быть остановлен.
Размер сообщения <tex>L</tex> можно найти по формуле:
Число бит в закодированном тексте:
}}