Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Архиваторы. Алгоритмы. Дерево Хаффмана.  (Прочитано 27278 раз)
0 Пользователей и 8 Гостей смотрят эту тему.
Skif
Гость
« : 02-01-2006 14:33 » 

Возникла небольшая проблема в понимании алгоритма сжатия текста с помощью построения динамического двоичного дерева Хаффмана. Улыбаюсь

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

Если кто знает помогите. И вообще если у кого-нибудь есть пример реализации (всего алгоритма или отдельных ф-ций) на С или С++ скиньте ссылку или файлик буду очень благодарен.
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #1 : 02-01-2006 16:47 » 

Гугл рулит, http://aforge.ibd.lv/?6 Там описание + пример кода.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Skif
Гость
« Ответ #2 : 02-01-2006 21:30 » 

Большое спасибо!!! Отлично Честно говоря не ожидал, что можно найти толковое описание алгоритма. Есть еще один маленький вопрос, а есть что-нибудь лучше, чем алгоритм Хаффмана?
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #3 : 03-01-2006 01:10 » 

Конечно есть, Тот же Rar может сжимать текст до 10 процентов от наминала. В свое время я проводил эксперементы. Мне удалось достичь только 70 процентов. Я так думаю, в архиваторах используется какие то математические преобразования, слишком уж архивированные файлы равнораспределенными получаются. Причем используется весь спектр значений байта.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Skif
Гость
« Ответ #4 : 03-01-2006 12:12 » 

Неуверен в том, что RAR способен сжать текст до 10%.

Понимаешь, чисто теоритически нормальный русский текст можно сжать на 72,5%. Во всяком случае не больше(без потерь). Энтропия не позволяет (русский текст избыточен на 72,5%). Но это нормальный текст, осмысленный и достаточно длинный. По идеи даже простенькая прога, реализуящая алгоритм Хаффмана, должна давать близкие значения для нормального текста.

Не удивлюсь если  RAR испоьзует данный алгоритм, как один из этапов сжатия. Улыбаюсь

Проблема возникает с текстом в котором частота встречаемости символов равнозначна.
Например: фывфывфывфывфывфывфыв..... ну и т.д. Используя алгоритм Хаффмана мы добьемся сжатия (так как здесь всего 3 символа) 2 из них будут занимать два байта а 1 - один байт. Но нам с тобой понятно, что это не лучший метод сжатия ДАННОГО набора символов.

Если же мы будем сжимать допустим EXE-шник скорее всего вообще ничего не получиться.

Хотелось бы найти хороший алгоритм поиска закономерностей в равновероятном тексте. Который мог бы  с пользой дополнить алгоритм Хаффмана.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #5 : 23-07-2007 03:12 » 

есть ли более быстрые алгоритмы (чем код Хаффмана) которые сжимают именно текст ?
Нужна не столько степень сжатия (сойдёт и 50%), сколько скорость работы.
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #6 : 30-07-2007 10:04 » 

реализовал я код Хаффмана, работает быстро, сжимает текстовые файлы приемлимо (как и просил - 50% Отлично )
Но теперь хочу больше сжать, но в скорости не сильно потерять Улыбаюсь Что посоветуете ?

ps
Я пробовал сделать такую штуку - заменить все символы исходного файла по принципу

[0xAB] -> ['0'+A]['0'+B]

рассуждал так-
исходный файл в 2 раза увеличится, но , так как старшие тетрады символов текстового файла относительно часто повторяются (например, в цифрах - 0x30) вроде как мог получиться выигрыш при сжатии. Но не прокатило ) Сжимается хуже, видимо выигрыш в уменьшении длины кода перебивается именно двойным размером файла
« Последнее редактирование: 30-07-2007 10:24 от Алексей1153++ » Записан

nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 30-07-2007 16:11 » 

Сравнительная характеристика некоторых реализаций
 алгоритмов сжатия текстовой информации
Реализация   Пара¬метры   Алго¬ритм   Степень сжатия, бит/символ   Скорость упаковки, с   Скорость распаковки, с
RK 1.01b1       -mx2 1              PPM                                 1.4258                                   159.37                                162.34
ACB 2.00c         (u)f                АК                                      1.5621                                 332.40                              333.37
PPMD vE   -o5 -m28                   PPM                                1.6455                                    11.93                                  13.48
SZIP 1.11b   -b25o0                   BWT                                1.6476                                    42.22                                  10.57
LZAP 0.20.0   (none)                    LZP                                  1.8795                                     116.03                           123.74
PKZIP 2.04g   -ex                    LZ+ SF                               2.5646                                      19.79                             10.35
Записан

ещё один вопрос ...
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #8 : 30-07-2007 17:02 » 

PPMD vE   -o5 -m28
 - рулит ? Улыбаюсь
« Последнее редактирование: 30-07-2007 17:05 от Алексей1153++ » Записан

nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 30-07-2007 17:13 » new

НУ и применяй алгоритмы семейства LZ (Помню есть LZ77(где-то валяется реализация на С++), LZ78, LZSS, LZW и т.д.), SF не помню что такое, может коды Шеннона-Фоно.
А вообще посмотри еще в сторону РРМ, скорость-то лучшую он дал.
 Алгоритм PPM (prediction by partial matching) - это метод контекстно-ограниченного моделирования, позволяющий оценить вероятность символа в зависимости от предыдущих символов.
Записан

ещё один вопрос ...
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #10 : 30-07-2007 17:39 » 

угу, буду искать. Пасиба за наводку )

---------
вот что нарыл, кстати
-тут была фигня-
« Последнее редактирование: 31-07-2007 10:05 от Алексей1153++ » Записан

nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 30-07-2007 17:54 » 

ну ты прямо копатель Улыбаюсь). Накопал так накопал Улыбаюсь.
Записан

ещё один вопрос ...
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #12 : 30-07-2007 18:25 » 

nikedeforest, ) да лана тебе

ну да, там слофф много, а по делу чёт мало
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #13 : 31-07-2007 10:07 » 

вот PPM тут более толково расписан, с 3-этажными формулами и красочными примерами из их жизни. Пока вникаю...
http://www.maxime.net.ru/doc/PracticalPPM/
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #14 : 10-08-2007 05:54 » 

итак, на чём мы там остановились...

итог моих поисков:
1) код Хаффмана понятен с третьего раза в теории, вменяем на практике (реализовал)

2) арифметическое кодирование идеально в теории, НЕВМЕНЯЕМО на практике %)
(прямо таки утопия для длинных файлов. Ну нету типов данных с ТАКОЙ точностью Улыбаюсь  Ну его нафик...)

3) LZ (Лемпеля-Зива алгоритм) - в теории понятен с 4-го с половиной раза, (вскоре приступаю к реализации, вроде проблем больше не вижу)
предполагаю, что использование в последовательности
...1 LZ
...2 Хаффман
 улучшит степень сжатия, нежели по отдельности этими алгоритмами...
Почему считаю именно такую последовательность верной - LZ работает с целыми байтами, а Хаффман с битами, следовательно Хаффману достанется уже меньше работы-> выигрыш ещё и во времени. Если ошибаюсь - поправьте Улыбаюсь Хотя , реализую LZ - сам всё увидю...

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

Если кому интересно или нужно, вот реализация кода Хаффмана в виде класса CHuffman (в аттаче)

(критика принимается и приветствуется!!  Помидоры  Помидорами прошу не кидать!.. тоже, если свежие Улыбаюсь )

пример работы с классом:
Код:
//СЖАТИЕ БУФЕРА

CHuffman Huff;

BYTE* pFile=...;//буфер
DWORD dwdFileLen=...;//длина буфера

DWORD dwdPressedDataLen=0;

if(!Huff.PackData(pFile,dwdFileLen,&dwdPressedDataLen))
{
//ошибка
//...
}

//Huff.pArhivBuffer - буфер со сжатыми данными
//dwdPressedDataLen - длина сжатых данных


///////////////////////////////////////

//РАСПАКОВКА

BYTE* pArhiv=...;//буфер с архивом
DWORD dwdArhLen=...;//длина архива

CHuffman Huff;
DWORD dwdUnpackedFileLen=0;

if(!Huff.UnPackData(pArhiv,dwdArhLen,dwdUnpackedFileLen))
{
MessageBox("ошибка при распаковке");
return false;
}

//Huff.pUnpackBuffer - буфер со разжатыми данными
//dwdUnpackedFileLen - длина данных



* Huffman.zip (9.42 Кб - загружено 1245 раз.)
« Последнее редактирование: 10-08-2007 13:07 от Алексей1153++ » Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #15 : 24-08-2007 15:30 » 

вот, родил LZ )) , кому интересно.
Сжимает текстовые файла гораздо лучше , чем Хаффмановкий алгоритм , однако подсунул AVI - получился архив больше, чем файл. То есть хорошо сжимаются файлы с повторяющимися последовательностями байт

класс C_LZ16 (использует вспомогательный класс CDinBuffer, см в следующем посте)

в архиве используется контрольная сумма для определения правильности распаковки.


пример использования
Код:
//СЖАТИЕ БУФЕРА

C_LZ16 LZPack;

BYTE* pFile=...;//буфер
DWORD dwdFileLen=...;//длина буфера

if(!LZPack.PackData(pFile,dwdFileLen))
{
//ошибка
//...
}

//LZPack.GetDoneArhivBuffer() - буфер со сжатыми данными
//LZPack.GetDoneArhivBufferLen() - длина сжатых данных

///////////////////////////////////////

//РАСПАКОВКА

BYTE* pArhiv=...;//буфер с архивом
DWORD dwdArhLen=...;//длина архива

C_LZ16 LZunPack;
DWORD dwdUnpackedFileLen=0;

if(!LZunPack.UnPackData(pArhiv,dwdArhLen,dwdUnpackedFileLen))
{
MessageBox("ошибка при распаковке");
return false;
}

//LZunPack.pUnpackBuffer - буфер со разжатыми данными
//dwdUnpackedFileLen - длина данных

* LZ16.zip (7.1 Кб - загружено 1104 раз.)
« Последнее редактирование: 28-09-2007 10:59 от Алексей1153++ » Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #16 : 28-09-2007 10:52 » 

Исправил ошибку в файле DinBuffer.h
-----------
(для уже загрузивших код: )
было - если в конструкторе или в SetParams() указать начальный размер буфера dwdBeginSize меньше, чем шаг увеличения dwdSizeStep , то шаг делался равным указанному dwdBeginSize.

В итоге - если задать начальный размер несколько байт, а то и вообще 0 , то , в первом случаем дополнительное выделение памяти тормозило, а во втором - вообще висим...
------------
Тут прикреплён исправленный файл

* DinBuffer.zip (1.46 Кб - загружено 1142 раз.)
Записан

Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines