подготовка к экзамену 4 сем
.pdf
Пример
Пример псевдокода для данных в виде строки с сайта: https://stackabuse.com/run-length-
encoding/
Кодирование:
def rle_encode(data): encoding = '' prev_char = '' count = 1
if not data: return ''
for char in data:
#If the prev and current characters
#don't match...
if char != prev_char:
#...then add the count and character
#to our encoding
if prev_char:
encoding += str(count) + prev_char count = 1
prev_char = char else:
#Or increment our counter
#if the characters do match count += 1
else:
# Finish off the encoding
encoding += str(count) + prev_char return encoding
Декодирлование: def rle_decode(data):
decode = '' count = ''
for char in data:
# If the character is numerical...
if char.isdigit():
# ...append it to our count count += char
else:
#Otherwise we've seen a non-numerical
#character and need to expand it for
#the decoding
decode += char * int(count) count = ''
return decode
5. ПРЕОБРАЗОВАНИЕ БАРРОУЗА УИЛЬЯРА (BWT). ОБРАТНОЕ ПРЕОБРАЗОВАНИЕ. ЭФФЕКТИВНАЯ
РЕАЛИЗАЦИЯ
ОБРАТНОГО
ПРЕОБРАЗОВАНИЯ.
Алгоритм
1-Для строки (блока) составляется список всех возможных циклических перестановок. Например, перемещаем первый символ в конец, а остальные символы сдвигаем влево.
2-Получившийся список (массив) сортируем. Сначала сортировка происходит по первому символу, для тех строк, где первый символ совпадает - по второму, и т.д.
3-Записываем последний столбец и индекс исходной строки.
1. |
2. |
3. |
Обратное преобразование
1.Отсортируем символы полученного столбца (получился первый столбец матрицы циклических перестановок)
2.Символы последнего и первого столбца образуют пары, которые мы сортируем по возрастанию. Добавляя каждый раз последний символ в начало строки и сортируя снова все строки, получаем первоначальную матрицу. По индексу находим нужную строку.
|
|
1. |
|
|
|
|
2. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Оценка временной сложности: |
|
|
|
|
|
|
|
( ) |
|
|
|
|
|
||||||||||||||
нужно строки - |
|
(; |
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||
2 |
Рассмотрим временную сложность для обработки одного блока: |
Генерация циклических |
||||||||||||||||||||||||||
|
|
для |
( |
2 |
) |
2 |
|
|
|
|
( ) |
|
|
|
|
|
|
|
2 |
|
|
|
|
|
|
|||
сдвигов занимает |
|
|
|
, где m - размер блока; сортировка сдвигов - |
|
|
|
; поиск индекса |
||||||||||||||||||||
( ) |
|
|
|
|
|
|
|
2 |
|
|
|
|
|
= |
|
|
|
|
|
|
|
|
|
|
|
|||
|
, |
так как |
|
|
|
|
|
сбор последнего столбца - |
|
|
. Итоговая временная сложность составляет |
|||||||||||||||||
|
|
|
|
(∙ ) = ( ∙ ) |
|
|
|
|
|
|
|
|
|
|
|
|
|
( ∙ |
||||||||||
) |
|
|
одного блока. Так как данные делятся на |
|
|
блоков заданной длины m, то общая |
||||||||||||||||||||||
временная сложность |
|
|
|
|
|
|
|
. Декодирование для одного блока займет |
|
|
||||||||||||||||||
|
|
( ∙ ∙ ) = ( ∙ ) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||
|
|
|
|
сортируются символы только последнего столбца длиной n, значит для для всех |
||||||||||||||||||||||||
блоков |
|
|
|
|
|
|
|
|
|
|
. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Оценка пространственной сложности: |
|
|
|
|
|
|
( |
|
+ ) |
|
( |
|
+ ) |
|
|||||||||||||
декодирования потребуется |
( ) |
|
? Так как требуетс( ) |
|
|
|
|
|
|
|||||||||||||||||||
|
Для одного блока: Хранение циклических и отсортированных сдвигов - |
|
2 |
. Хранение |
||||||||||||||||||||||||
строку. |
|
|
|
|
|
|
|
|
( + ) |
|
|
|
|
|
|
|
|
|
2 |
|
= |
|
2 |
|
|
. Для |
||
преобразованных данных - |
|
; хранение индексов - |
|
|
. Итого: |
|
|
|
( ) |
|
|
|
||||||||||||||||
хранить только индексы и закодированную
Код из лабы
Def bwt(data, chunk_size):
Transformed_data = bytearray() Ind = []
For start in range(0, len(data), chunk_size): Chunk = data[start:Start + chunk_size]
Index, encoded_chunk = transform_chunk(chunk) Transformed_data.extend(encoded_chunk) Ind.append(index)
Return bytes(transformed_data), ind
Def transform_chunk(chunk):
Rotations = [chunk[i:] + chunk[:I] for i in range(len(chunk))] Rotations.sort()
Original_index = rotations.index(chunk)
Encoded_chunk = bytes(rotation[-1] for rotation in rotations) Return original_index, encoded_chunk
Def bwt_decode(encoded_data, indices, chunk_size):
Restored_data = bytearray() Position = 0
Index = 0
While position < len(encoded_data):
End = position + chunk_size if position + chunk_size <= len(encoded_data) else len(encoded_data) Chunk = encoded_data[position:End]
Original_index = indices[index]
Restored_chunk = reverse_transform_chunk(original_index, chunk) Restored_data.extend(restored_chunk)
Position = end Index += 1
Return bytes(restored_data)
Def reverse_transform_chunk(original_index, encoded_chunk):
Table = [(char, idx) for idx, char in enumerate(encoded_chunk)] Table.sort()
Result = bytearray() Current_row = original_index
For _ in range(len(encoded_chunk)): Char, current_row = table[current_row] Result.append(char)
Return bytes(result)
Код стивена:
Def bwt(s): N = len(s)
Bwm = [s[i:] + s[0:I] for i in range(n)] Bwm.sort()
Last_column_bwm = "".join([bwm[i][-1] for i in range(n)]) S_index = bwm.index(s)
Return last_column_bwm, s_index
# обратное преобразование барроуза-уилера
Def ibwt(last_column_bwm, s_index): # t(n) = o(n^2*logn) s(n) = o(n^2) N = len(last_column_bwm)
Bwm = ["" For _ in range(n)] For _ in range(n):
For j in range(n):
Bwm[j] = last_column_bwm[j] + bwm[j] Bwm.sort()
S = bwm[s_index] Return s
Эффективная реализация
Def better_ibwt(last_column_bwm, s_index): N = len(last_column_bwm)
P_inverse = counting_sort_arg(last_column_bwm) S = ""
J = s_index
For _ in range(n): J = p_inverse[j]
S = s+ last_column_bwm[j] Return s
# сортировка строки подсчетом и нахождение перестановки
Def counting_sort_arg(s): N = len(s)
M = 128
T = [0 for _ in range(m)] T_sub = [0 for _ in range(m)]
#массив счетчиков символов
For s in s: T[ord(s)] += 1
#массив индексов, с которым начинается последовательность повторяющихся символов
For j in range(1,m):
T_sub[j] = t_sub[j-1] + t[j-1] P = [-1 for _ in range(n)] P_inverse = [-1 for _ in range(n)] For i in range(n):
P_inverse[t_sub[ord(s[i])]] = i P[i] = t_sub[ord(s[i])] T_sub[ord(s[i])] +=1
Return p_inverse
6. ИНФОРМАЦИЯ. ЭНТРОПИЯ. СОБСТВЕННАЯ ЭНТРОПИЯ. ВЕРОЯТНОСТНАЯ МОДЕЛЬ
ИСТОЧНИКА
СООБЩЕНИЯ.
ЭНТРОПИЙНЫЕ
КОДИРОВЩИКИ.
https://vmath.ru/vf5/shannon чекнуть сайт
Наверное, не надо, но допустим,
формула Хартли:
Энтропия по Шеннону:
Код стивена:
# Вычисление энтропии строки def entropy(S):
P = prob_estimate(S)
P = numpy.array(list(filter(lambda x: x!=0,P))) E = -sum(numpy.log2(P) * P)
return E
Собственная энтропия
Также можно определить энтропию случайной величины, предварительно введя понятие распределения случайной величины A, имеющей конечное число значений[11]:
Немножко краткой инфы про обе энтропии
Вероятностная модель источника информации С какого-то рандом сайта, где стремно все написано, перепишу потом
Вероятностной модели ИОС соответствует источник случайных последовательностей. Пусть источник генерирует в алфавите Zm текст конечной или бесконечной длины. При моделировании полагается, что источник генерирует последовательность случайных переменных х0, х{, ..., хп_, ..., принимающих значения в Zm. Вероятность случайного сообщения (а0,..., ап_х) определяется как вероятность последовательности событий:
Множество случайных сообщений образует вероятностное пространство, если выполнено:
1) Р(а0,..., ап_{) > 0 для любого случайного сообщения (а0,ап_{)
2)
;
3)
, для любого случайного сообщения (а0,ап_х) и любого 5 > п> т.е. вероятность всякого случайного сообщения длины п есть сумма вероятностей всех продолжений этого сообщения до длины 5.
Текст, порождаемый таким источником, является вероятностным аналогом языка. Он обладает одинаковыми с языком частотными характеристиками мультиграмм. При конкретном вероятностном распределении на множестве открытых текстов получается соответствующая вероятностная модель ИОС. Рассмотрим часто используемые вероятностные модели ИОС.
Энтропийные кодировщики
Энтропийные кодировщики — это тип алгоритмов сжатия данных, которые стремятся закодировать информацию максимально близко к теоретическому минимуму — энтропии источника, как описано в теории информации Клода Шеннона.
https://external.software/archives/16730
Энтропийное кодирование — это метод сжатия данных без потерь, который использует информацию о распределении вероятностей символов для представления часто встречающихся символов более короткими кодами, а редко встречающихся — более длинными. Это позволяет уменьшить средний размер представления данных.
Код Хаффмана: строит дерево на основе частот символов и назначает каждому символу кодовое слово, соответствующее пути от корня дерева до листа, представляющего этот символ. Чем чаще встречается символ, тем короче соответствующее ему кодовое слово.
Арифметическое кодирование: представляет последовательность символов одним единственным числом в интервале [0, 1). Эффективность арифметического кодирования выше, чем у кода Хаффмана, особенно для небольших объемов данных и не равномерных распределений.
Примеры энтропийных кодов: Код Хаффмана, Арифметическое кодирование
И по идее здесь уже идет плавный переход к следующим двум билетам, но если вкратце:
Принцип арифметического кодирования
Арифметическое кодирование представляет собой последовательность символов одним числом в интервале [0, 1). Интервал делится на под-интервалы, пропорциональные вероятностям символов. Для каждого символа выбирается соответствующий под-интервал, и этот интервал становится новым текущим интервалом. Процесс повторяется для всех символов входной последовательности. В итоге выбирается любое число внутри конечного интервала, которое и является закодированным представлением данных.
Арифметическое кодирование: более эффективно, чем код Хаффмана, особенно для не равномерных распределений вероятностей и малых объемов данных. Но сложнее в реализации и вычислительно более затратно.
Код Хаффмана: проще в реализации и менее требователен к вычислительным ресурсам, но менее эффективен в сжатии.
7. АЛГОРИТМ ХАФФМАНА. СТАТИЧЕСКИЙ И ДИНАМИЧЕСКИЙ АЛГОРИТМЫ. КАНОНИЧЕСКИЕ
КОДЫ
ХАФФМАНА.
Алгоритм Хаффмана
Пример
Динамический алгоритм
Пример
