Каким свойством должны обладать данные для того чтобы сообщение можно было сжать

Каким свойством должны обладать данные для того чтобы сообщение можно было сжать thumbnail

Мы каждый день пользуемся различными архиваторами: zip, rar, ace окружают нас повсюду.
Графические и звуковые файлы тоже содержат сжатые данные. Если же нам нужно использовать
сжатие в своей проге, то мы используем различные dll’ки, многие из которых платные.
Шареварность – это не единственное свойство программных компонентов, мешающих их нормальному
использованию. Если, например, сжимать waw или bmp-файл архиватором, то
он будет значительно уступать специальному методу для конкретного типа данных, т.е.
метод должен учитывать особенности конкретного типа данных. Поэтому полезно уметь реализовывать сжатие самостоятельно.
В этой статье я расскажу, как вообще сжимать информацию и рассмотрю один из методов сжатия.

Классификация методов сжатия

Прежде всего, все методы сжатия делятся на
сжатие с потерями и сжатие без потерь. Задачу сжатия с потерями можно сформулировать так: требуется отобразить множество возможных
сообщений на множество, содержащее меньшее количество элементов, так, чтобы исходные сообщения
и их отображения были в определенном смысле близки (например, неразличимы на глаз), т.е.
малозначительная информация просто отбрасывается. После этого дополнительно применяется сжатие
без потерь. Сжатие без потерь – это однозначное кодирование, такое что закодированные сообщения
в среднем занимают меньше места. Именно такому сжатию посвящена эта статья.
Далее под словом “сжатие” мы будем подразумевать сжатие без потерь.

Теория

Прежде всего, ни один метод сжатия не может сжать любые данные, поскольку кодирование
должно быть однозначным. Задача состоит в том, чтобы построить правило кодирования, по которому
наиболее часто встречающимся сообщениям соответствовали бы сообщения меньшей длины. Поэтому любой метод сжатия должен быть основан на каких-либо предположениях о
вероятностной структуре сжимаемых данных. Например, для текста на определенном языке известны
частоты букв. Наиболее часто используемое предположение заключается в том, что с большей
вероятностью в сообщении будут встречаться одинаковые цепочки символов. Например, в тексте этой
статьи чаще всего встречается слово “сжатие”. Если же ничего не знать о вероятностной структуре
сжимаемых данных и считать все сообщения одной длины равновероятными, то мы вообще ничего не
сожмем.

Методы сжатия делятся на статистические и словарные. Словарные методы заключаются в том,
чтобы в случае встречи подстроки, которая уже была найдена раньше, кодировать ссылку, которая
занимает меньше места, чем сама подстрока. Классическим словарным методом является метод
Лемпела-Зива (LZ). Все используемые на сегодняшний день словарные методы являются лишь
модификациями LZ.

Статистическое кодирование заключается в том, чтобы кодировать каждый символ, но
использовать коды переменной длины. Примером таких методов служит метод Хаффмана
(Huffman). Обычно словарные и статистические методы комбинируются, поскольку у каждого свои
преимущества.

Отметим один момент, который почему-то неочевиден для некоторых “теоретиков”.
Правило кодирования определяется вероятностной структурой данных, а значит, декомпрессор
должен до начала раскодирования уже знать её. Если же мы получаем её из статистики конкретного
сообщения (так оно сжимается лучше), то её придется передать явно или неявно вместе со сжатым
сообщением, и еще неизвестно, будет ли общий размер меньше.

Доказано, что наименьший возможный средний размер сжатого сообщения равен энтропии
ансамбля возможных сообщений, округленной с избытком. Энтропия вычисляется по формуле:

H = -Sum(p[i] * log(p[i]))

где Sum – сумма по i, p[i] – вероятность i-го сообщения, log – логарифм по основанию 2.
Энтропия сложного сообщения равна сумме энтропий входящих в него простых сообщений.

Если кодировать каждый символ отдельно, то длина кода каждого сообщения должна быть
равна -log(p). Т.е., например, если вероятность символа 0.3, то его код должен иметь длину
1.73 бита, в то время, как реальные длины целые. Можно улучшить результаты, если не сводить
задачу к кодированию отдельных символов.

Арифметическое кодирование

Этот метод в корне отличается от всех рассмотренных ранее методов. Его главное
преимущество в том, что достигается теоретический предел сжатия. Рассмотрим этот метод подробно. Всё сообщение целиком представляется одним числом по следующему правилу. Число должно
находиться в интервале от 0 до 1. Этот интервал делится на части, пропорциональные вероятностям
значений первого символа. Выбирается часть, соответствующая символу и делится на части по
вероятностям значений второго символа и т.д. 

новая_нижняя_граница = нижняя_граница + ширина * S[i]
новая_ширина = ширина * p[i]

где p[i] – вероятность i-го символа, S[i] – сумма вероятностей символов с номерами
меньше i.

После обработки всего сообщения по этому алгоритму остается только записать любое
число из получившегося интервала. Количество битов, необходимое для записи этого числа,
примерно равно минус логарифму ширины интервала. Ширина интервала равна произведению
вероятностей символов, т.е. вероятности всего сообщения. Т.о., длина кода равна
-log(p), т.е. теоретическому пределу. На практике мы будем работать с переменными ограниченной длины,
и точность вычислений будет ограничена, а значит, сжатие будет все-таки немного хуже.

Читайте также:  Каким свойством обладает нервная ткань

Реализация

Проект, прикрепленный к этой статье, компилируется на Visual Studio .NET.
Это реализация арифметического кодирования, сжимающая файлы, рассматривая байты как символы.
Содержимое файла рассматривается как марковский процесс 1-го порядка, т. е. распределение
вероятностей символов зависит от предыдущего символа. Класс CMarkovProcessDef обрабатывает
данные, сохраненные в ресурсе в специальном формате. Эти данные сгенерированы по результатам
обработки большого количества текстов, т. е. текстовые файлы, скорее всего, будут сжиматься
хорошо, а если попытаться сжать какой-нибудь бинарник, то размер “сжатого” файла будет больше
исходного. Для того, чтобы получить метод сжатия для своего типа данных, нужно заменить данные о
вероятностях символов. Кроме того, символ – это не обязательно байт несжатых данных. Например,
если есть столбец таблицы, где значения должны быть уникальными, то каждое значение – это
символ, а после того, как символ встречается, сбрасываем его вероятность в ноль. Нижняя граница и ширина интервала хранятся в целочисленных переменных dwBuf1 и dwBuf2.
Если после обработки очередного символа старшие байты границ окажутся равными
(заметим, что это не то же самое, что если старший байт ширины равен нулю), то
соответствующий байт окончательного результата будет равен этому значению, и его можно
записать в файл. Запишем его и сдвинем буферы на 1 байт. При распаковке кроме переменных, обрабатываемых так же, как при упаковке, нам
понадобится еще одна, где будет информация из файла. Для того, чтобы определить очередной символ, нужно
найти символ с наименьшим номером, такой, что S[n] * dwBuf2 >= dwBuf3, т.е. P[n] >= dwBuf3 / dwBuf2. При работе с целыми числами возникает проблема: мы представляем вероятности (дробные
числа от 0 до 1) целочисленными переменными (0x100000000 * p). Для умножения и деления на них нужны
особые процедуры: при умножении берем старшее 32-битное слово 64-битного результата, а при делении
делим число, умноженное на 2^32. Компилятор не может, умножитв DWORD на DWORD, поместить результат
в 64-битную переменную – это недостаток языка С++. Поэтому пришлось написать специальные процедуры
на ассемблере.

void CArithmCompressorDlg::OnBnClickedCompress()
{
CFileDialog dlg1(TRUE);
if (dlg1.DoModal() != IDOK) return;
CFileDialog dlg2(FALSE, “compressed”, 0, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, “*.compressed|*.compressed|All files|*.*||”);
if (dlg2.DoModal() != IDOK) return;

CFile file1(dlg1.GetPathName(), CFile::modeRead);
CFile file2(dlg2.GetPathName(), CFile::modeCreate | CFile::modeWrite);

BYTE b;
ULONGLONG fs = file1.GetLength();

file2.Write(&fs, 8); // Запишем размер исходного файла

// m_mpd – это объект класса CMarkovProcessDef 
m_mpd.ResetProcess(); // Сбросим данные о предшествующих символах

// Здесь начинается сжатие
// Начальный интервал – от 0x00000000 до 0xFFFFFFFF
DWORD dwBuf1 = 0; // Нижняя граница
DWORD dwBuf2 = 0xFFFFFFFF; // Ширина
DWORD dww; // Временная переменная

while (file1.Read(&b, 1))
{
// Вычисляем новый интервал
if (b > 0) dww = MulHigh(m_mpd.GetDistribution(b-1), dwBuf2); else dww = 0;
/*
m_mpd.GetDistribution(b-1) – Это S[b], т. о.
p[b] – это m_mpd.GetDistribution(b) – m_mpd.GetDistribution(b-1)

Замените эту функцию на свою реализацию и получите метод сжатия для вашего типа данных.
*/
dwBuf1 += dww;
if (b Если старший байт буфера определен
{
file2.Write(((LPBYTE)&dwBuf1)+3, 1); // Записываем его
dwBuf1 = dwBuf1 И сдвигаем буфер
dwBuf2 = dwBuf2
}
/*
PushSymbol(b, 0) перемещает внутренний указатель на распределение для следующего символа
*/
m_mpd.PushSymbol(b, 0);
}
file2.Write(((LPBYTE)&dwBuf1)+3, 1); // Записываем последний байт
// Вот и всё
// Закрываем файлы
file1.Close();
file2.Close();
}

void CArithmCompressorDlg::OnBnClickedDecompress()
{
CFileDialog dlg1(TRUE, “compressed”, 0, 0, “*.compressed|*.compressed|All files|*.*||”);
if (dlg1.DoModal() != IDOK) return;
CFileDialog dlg2(FALSE);
if (dlg2.DoModal() != IDOK) return;

CFile file1(dlg1.GetPathName(), CFile::modeRead);
CFile file2(dlg2.GetPathName(), CFile::modeCreate | CFile::modeWrite);

ULONGLONG fs, i;

if (file1.Read(&fs, 8) != 8) return; // Читаем длину извлекаемого файла

m_mpd.ResetProcess();

DWORD dwBuf1 = 0, dwBuf2 = 0xFFFFFFFF, dwBuf3, dww;

// Читаем первые 4 байта
// Нужно поместить байты в переменную не в том порядке, в каком они в файле,
// поэтому читаем их по отдельности
for (int j = 3; j >= 0; j–) if (file1.Read(((LPBYTE)&dwBuf3)+j, 1) == 0) ((LPBYTE)&dwBuf3)[j] = 0xFF;

for (i = 0; i
{
DWORD l, h, m, v;
l = 0; 
h = 255;

v = DivLarge(dwBuf3, 0xFFFFFFFF, dwBuf2); // Это число >= S[m]

// Поиск методом половинного деления
do
{
m = (l+h)/2;
if (h
if (m_mpd.GetDistribution(m)
} while (true);

// Вычисляем новый интервал
if (m > 0) dww = MulHigh(m_mpd.GetDistribution(m-1), dwBuf2); else dww = 0;
dwBuf1 += dww;
dwBuf3 -= dww;
if (m Пишем символ
m_mpd.PushSymbol(m, 0); 

while (((dwBuf1 ^ (dwBuf1 + dwBuf2)) & 0xFF000000) == 0) // Если старший байт буфера определен
{
dwBuf1 = dwBuf1 сдвигаем буфер
dwBuf2 = dwBuf2
dwBuf3 = dwBuf3
if (file1.Read(&dwBuf3, 1) == 0) dwBuf3 |= 0xFF;
// Читаем следующий байт, если есть, иначе ставим 0xFF
}
}
// Закрываем файлы
file1.Close();
file2.Close();
}

Читайте также:  Какие свойства черного тмина

DWORD CArithmCompressorDlg::MulHigh(DWORD dw1, DWORD dw2)
{
/*
Эта функция возвращает старшее двойное слово
произведения данных двойных слов
*/
DWORD r;
_asm
{
mov eax, dw1;
mul dw2;
mov r, edx;
}
return r;
}

DWORD CArithmCompressorDlg::DivLarge(DWORD hi, DWORD lo, DWORD dw)
{
/*
Эта функция делит 64-битное беззнаковое целое (hi;lo)
на 32-битное
*/
DWORD r;
_asm
{
mov eax, lo;
mov edx, hi;
div dw;
mov r, eax;
}
return r;
}

Исходники

Источник

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

Значимость тех или иных свойств информации определяется конкретной ситуацией. В одних ситуациях важна актуальность и достоверность информации.

Пример:

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

В других ситуациях важную роль играют такие свойства, как доступность и понятность.

Пример:

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

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

Эффективность использования информации связана с такими её свойствами, как актуальность, доступность (понятность), достоверность, репрезентативность, адекватность и полнота.

Рассмотрим эти свойства более подробно.

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

Это свойство во многом зависит от интервала времени, прошедшего с момента появления данной информации, а также от того, насколько быстро изменяется ситуация.

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

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

В соответствии с этим же правилом учёные стараются найти более надёжные способы предупреждения о землетрясениях, ураганах и других стихийных бедствиях.

Доступность информации обеспечивается за счёт её преобразования в понятную форму. При этом одну и ту же информацию можно представить в разной форме в зависимости от её получателя.

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

Пример:

Учебник по физике 10-го класса совершенно непонятен восьмикласснику, так как в нем содержатся незнакомые термины и формулы, а учебник по физике 8-го класса содержит доступную информацию для восьмиклассника, но десятиклассник в нем не найдет ничего нового.

В книжном магазине вы найдете отдел детской литературы, где на каждой книге будет указан возраст ребёнка, на который она ориентирована. Это означает, что информация в этих книгах представлена так, чтобы быть доступной и понятной читателю данного возраста.

Широко внедряемая сейчас в библиотеках информационно-поисковая система библиотечного каталога спроектирована так, чтобы предоставить читателю информацию о наличии книг по запрошенной тематике в доступной и удобной для восприятия форме.

Достоверность информации определяется её свойством отражать состояние реально существующего объекта, процесса или явления. Недостоверная информация может привести к неправильному пониманию ситуации и, как следствие, к принятию неправильного решения.

Полнота (достаточность) информации означает, что она содержит минимальный, но достаточный для принятия правильного решения набор данных. О полноте информации можно говорить, когда какая-либо дополнительная информация об объекте будет уже избыточна.

Понятие полноты информации связано с её смысловым содержанием.

Как неполная, так и избыточная информация снижает эффективность решений, принимаемых человеком на её основе.

Таким образом, информация должна быть актуальной, доступной, достоверной и полной.

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

– Иногда бывает, что при разговоре по телефону шум мешает услышать собеседника. Из-за этого информация не всегда воспринимается точно и слова собеседника могут быть неправильно поняты и истолкованы.

– Предположим, вы отправляете телеграмму с информацией о дате приезда гостя, которого надо встретить на вокзале. Если при передаче телеграммы будет допущена ошибка в дате приезда, это приведет к неприятным последствиям.

Читайте также:  Какое масло с хорошими моющими свойствами

– Если человек сел за руль автомобиля, не зная, как им управлять, то вряд ли он далеко уедет. В этом случае можно сказать, что этот человек имеет неполную информацию для управления автомобилем.

Адекватность информации — это соответствие образа, создаваемого с помощью полученной информации (информационной модели), реальному объекту, процессу или явлению. В реальной жизни вряд ли возможна ситуация, когда существует полная адекватность информации. Всегда присутствует большая или меньшая степень неопределённости. Степень адекватности информации реальному состоянию объекта тоже влияет на правильность решений, принятых человеком.

Пример:

Вы успешно закончили школу и хотите продолжить образование по экономическому направлению. Поговорив с друзьями, вы узнаете, что подобную подготовку можно получить в разных вузах. В результате таких бесед вы получаете весьма разноречивые сведения, которые не позволяют вам принять решение в пользу того или иного варианта, то есть полученная информация не адекватна реальному состоянию дел. Для того чтобы получить более достоверные сведения, вы покупаете «Справочник для поступающих в вузы», из которого получаете исчерпывающую информацию. В этом случае можно говорить, что информация, полученная вами из справочника, адекватно отражает направления обучения в вузах и помогает вам определиться с окончательным выбором.

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

Важнейшее значение здесь имеют выбранные методики и методы отбора информации и её оценки.

Пример:

Перед социальной службой города поставлена проблема: выяснить, сколько денежных средств еженедельно каждая семья в среднем тратит на питание. Невозможно представить, что для этого социальные работники будут опрашивать всех жителей города. Значит, необходимо выбрать наиболее типичную группу людей, которая и будет опрошена. В результате опроса будет сформирован массив информации, называемый выборкой. Необходимо также определить методику опроса, методы обработки собранных данных, их оценки и анализа результатов. Если полученные результаты отражают ситуацию, характерную для большинства жителей города, то говорят о репрезентативности информации, полученной в результате опроса отобранной группы людей. Заключения об адекватности и репрезентативности информации могут быть сделаны на основании специальных методов, которыми занимаются такие науки, как статистика и математическая статистика.

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

Рассмотрим несколько примеров, где выделены наиболее важные свойства для конкретной ситуации.

Пример:

Утром, когда вы собираетесь в школу, вы обязательно смотрите на часы: вам нужна только достоверная информация. Скорее всего, вы выглянете в окно или посмотрите на термометр, чтобы решить, что следует надеть. Здесь важна актуальность информации. Затем вы идете в школу и находите кабинет, в котором проходит урок согласно расписанию. Вам нужна полная и достоверная информация, иначе невозможно найти нужный кабинет.

Вам необходимо воспользоваться географической картой для определения маршрута поездки, знакомства с новой страной, изучения исторических событий. Карта всегда служила человеку источником информации о земной поверхности. Она также является важным инструментом для исследования в различных областях. Такие задачи, как соотнесение с реальной местностью и координирование строительных работ, решаются с помощью карт. Поэтому здесь жизненно важна адекватность информации, содержащейся в картах, реальной местности.

Сейчас создаются геоинформационные системы – живые карты на компьютере. В них обрабатывается и анализируется информация, поступающая со спутников. Такие системы позволяют решать нетрадиционные задачи:

– прогнозировать объем продаж и потенциал рынка, так как могут отображать демографические данные и информацию о расположении магазинов, ассортименте товара;

– анализировать последствия экологических аварий и выбирать оптимальные решения для их ликвидации;

– строить модели гидрографической сети и определять участки затоплений;

– строить модели рельефов поверхности Земли.

Все карты «описаны» специальным языком, который понятен лишь специалисту. Это означает, что данная информация доступна не всем. Каждый символ для специалиста несет большой объем достоверной, объективной и понятной информации, которая недоступна тем, кто не знает используемого языка.

В современных «космических технологиях» решающую роль играет информация, полученная с помощью различных приборов. Например, расположение станции относительно Солнца важно для работы солнечных батарей. Малейшая неточность – и космический корабль лишится энергии. Такая информация должна быть актуальной, достоверной и полной.

Источник