Файл: Отчет по лабораторной работе 2 Изучение методов рационального кодирования сообщений по дисциплине Теоретические основы информационных процессов.docx

ВУЗ: Не указан

Категория: Отчет по практике

Дисциплина: Не указана

Добавлен: 09.01.2024

Просмотров: 13

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

Министерство науки и высшего образования Российской Федерации

Федеральное государственное бюджетное образовательное учреждение высшего образования

«Рязанский государственный радиотехнический университет имени В.Ф. Уткина»

Кафедра «Вычислительная и прикладная математика»

Отчет по лабораторной работе № 2

Изучение методов рационального кодирования сообщений

по дисциплине: «Теоретические основы информационных процессов»

Выполнил:
студент группы 143
Ярошенко А.М.
Проверил:
доц. каф. ВПМ
Филатов И.Ю.

Рязань 2023

Цель работы: выполнить программное моделирование алгоритма поиска кодовых комбинаций и алгоритма кодирования методами Шеннона-Фано и Хаффмана.

Задание (вариант №23): смоделировать дискретный источник сообщений нормального распределения при M(x) = 0, σ = 1 и определить по распределению вероятности алфавитов (цифры 0-9, кириллица и латиница, 1000 символов юникода).

Листинг программы:

from math import sqrt, pi, ceil, log

import numpy as np

from random import random

from operator import itemgetter

class Node:

def __init__(self, prob, symbol, left=None, right=None):

self.prob = prob

self.symbol = symbol

self.left = left

self.right = right

self.code = ''
codes = dict()

def calculate_codes(node: Node, val=''):

newVal = val + str(node.code)

if node.left:

calculate_codes(node.left, newVal)

if node.right:

calculate_codes(node.right, newVal)

if not node.left and not node.right:

codes[node.symbol] = newVal

return codes

def huffman_encoding(seq: dict()):

nodes = [Node(seq[symbol], symbol) for symbol in seq.keys()]

while len(nodes) > 1:

nodes = sorted(nodes, key=lambda x: x.prob)

right, left = nodes[0], nodes[1]

left.code, right.code = 0, 1

newNode = Node(left.prob + right.prob, left.symbol + right.symbol, left, right)

nodes.remove(left)

nodes.remove(right)

nodes.append(newNode)

huffman_dict = calculate_codes(nodes[0])

return huffman_dict

def shannon_fano_encoding(seq: dict(), code=""):

left, right = {}, {}

if len(seq) == 1:

dict_contained_symbols_and_codes_shannon_fano[seq.popitem()[0]] = code

return

if sum(seq.values()) == 0:

counter = 0

for k, v in sorted(seq.items(), key=itemgetter(1), reverse=True):

if counter < len(seq) / 2:

left[k] = v

else:

right[k] = v

counter += 1

else:

for k, v in sorted(seq.items(), key=itemgetter(1), reverse=True):

if sum(left.values()) < sum(seq.values()) / 2:

left[k] = v

else:

right[k] = v

shannon_fano_encoding(left, code + "0")

shannon_fano_encoding(right, code + "1")
def r():

r = 0

for _ in range(12):

r += random()

return r - 6


def random_value(n):

return [SIGMA * r() + MX for _ in range(n)]

def probabilities(array):

delta = (np.max(array) - np.min(array)) / INTERVAL

result = []

iter = np.min(array)

while abs(iter - np.max(array)) > EPS:

result.append(len(array[(array >= iter) & (array < iter + delta)]) / N)

iter += delta

return result

def encode_string(string, data: dict()):

return [data[char] for char in string]

def print_dict(data: dict(), string):

file = open(string, "w", encoding="utf-8")

for k, v in data.items():

file.writelines(str(k) + " " + str(v) + "\n")

file.close()
#Параметры для закона нормального распределения

K = sqrt(8 / pi)

MX = 0

SIGMA = 1

EPS = 1e-4

N = 100_0000

#Цифры

# list_symbols = [str(i) for i in range(10)]
#Символы из Юникода

# list_symbols = [chr(i) for i in range(32, 1200 + 1)]
#Алфавит

alphabet = "abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZабвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ"

list_symbols = [i for i in alphabet]
#Количество разбиений

INTERVAL = len(list_symbols)
#Сопоставляем символы с их вероятностями распределёнными по нормальному закону

prob = probabilities(np.array(random_value(N)))
#Словарь кодов по Хаффману

dict_contained_symbols_and_codes_huffman = huffman_encoding(dict(zip(list_symbols, prob)))
dict_contained_symbols_and_codes_shannon_fano = {}

#print(dict(zip(symbols, prob)))

shannon_fano_encoding(dict(zip(list_symbols, prob)))
print_dict(dict(zip(list_symbols, prob)), "probabilities.txt")

print_dict(dict_contained_symbols_and_codes_huffman, "huffman.txt")

print_dict(dict_contained_symbols_and_codes_shannon_fano, "shannon-fano.txt")
print('Результаты кодировки символов, вероятности которых распределены по нормальному закону')

print(f"Длина кодировки.Прямое кодировании: {ceil(log(len(list_symbols), 2))}")

print(f"Средняя длина кодовой последовательности по Хаффману: {len(''.join(dict_contained_symbols_and_codes_huffman.values())) / len(list_symbols):.2f}")

print(f"Средняя длина кодовой последовательности по Шеннону-Фано: {len(''.join(dict_contained_symbols_and_codes_shannon_fano.values())) / len(list_symbols):.2f}")

st = ''

while (st!='exit'):

st = input("Введите строку, которую хотите закодировать: ")

print(f"Длина исходной строки: {len(st) * 8} бит")

encoded_string_huffman = ''.join(map(str, encode_string(st, dict_contained_symbols_and_codes_huffman)))

encoded_string_shannon_fano = ''.join(map(str, encode_string(st, dict_contained_symbols_and_codes_shannon_fano)))

print(f"Кодовая последовательность, полученная при кодировании по Хаффману: {encoded_string_huffman}")

print(f"Длина строки: {len(encoded_string_huffman)} бит")

print(f"Кодовая последовательность, полученная при кодировании по Шеннону-Фано: {encoded_string_shannon_fano}")

print(f"Длина строки: {len(encoded_string_shannon_fano)} бит")

Результат работы программы:

Рассмотрим длины кодовых последовательностей символов алфавита, состоящего из цифр 0-9, распределённых по нормальному закону (рисунок 1):





Рисунок 1 – длины последовательностей

Распределение вероятностей представлена в таблице 1.

Таблица 1 – распределение вероятностей

0

0.000276

1

0.005329

2

0.042434

3

0.158443

4

0.297179

5

0.294982

6

0.155158

7

0.041089

8

0.004891

9

0.000219

Кодовые последовательности, полученные методом кодирования Хаффмана в соответствии с нормальным законом распределения представлены в таблице 2.

Таблица 2 – кодовые последовательности, полученные методом Хаффмана.

0

10101010

1

101011

2

1011

3

11

4

00

5

01

6

100

7

10100

8

1010100

9

10101011

Кодовые последовательности, полученные методом кодирования Шеннона - Фано в соответствии с нормальным законом распределения представлены в таблице 3.

Таблица 3 - Кодовые последовательности, полученные методом Шеннона - Фано

0

11110

1

11100

2

1100

3

100

4

00

5

01

6

101

7

1101

8

11101

9

11111


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

Закодируем последовательность ‘3455543435553’ (рисунок 2).



Рисунок 2 – кодирование последовательности ‘3455543435553’

Заметим, что длина кодовой последовательности по Хаффману короче, чем по Шеннону-Фано, что подтверждает вышесказанное, метод Хаффмана эффективен при кодировании высоковероятных символов.

Закодируем последовательность ‘39012930121009’ (рисунок 3).



Рисунок 3 – кодирование последовательности ‘39012930121009’

Заметим, что длина кодовой последовательности по Шеннону-Фано значительно короче кодовой последовательности по Хаффману, что подтверждает вышесказанное, метод Шеннона-Фано значительно эффективнее при кодировании символов с низкой вероятностью.

Рассмотрим принцип, по которому цифры 1-9 были закодированы методом Шеннона-Фано, используя вероятности из таблицы 1. (рисунок 3)



Рисунок 4 – Кодирование алфавита методом Шеннона-Фано

Рассмотрим принцип, по которому цифры 1-9 были закодированы методом Хаффмана, используя вероятности из таблицы 1. (рисунок 4)



Рисунок 5 – Кодирование алфавита методом Хаффмана
Рассмотрим принцип кодирования методом Шеннона-Фано в виде бинарного дерева (рисунок 5):


Рисунок 5 – Бинарное дерево по Шеннону-Фано

Рассмотрим кодирование символов алфавита (рисунок 6).




Рисунок 6 – длины последовательностей

Полученные вероятности, распределённые по нормальному закону представлены в таблице 4.

Таблица 4 – распределение вероятностей

W 0.02213

X 0.02323

Y 0.024127

Z 0.025078

а 0.025909

б 0.026715

в 0.026982

г 0.028007

д 0.028076

е 0.028461

ё 0.028526

ж 0.02846

з 0.028508

и 0.028178

й 0.027743

к 0.026839

л 0.026364

м 0.025398

н 0.024386

о 0.023522

п 0.02245

р 0.021173

с 0.02014

т 0.018789

у 0.017556

ф 0.016565

х 0.015163

ц 0.014001

ч 0.012668

ш 0.011554

щ 0.010394

ъ 0.009399

ы 0.008411

ь 0.00746

э 0.006688

ю 0.005661

я 0.005116

А 0.00439

Б 0.003909

В 0.003335

Г 0.002818

Д 0.002273

Е 0.002018

Ё 0.001691

Ж 0.001314

З 0.001176

И 0.000922

Й 0.000747

К 0.000617

Л 0.000501

М 0.000397

Н 0.000305

О 0.000252

П 0.000176

Р 0.000146

С 9.8e-05

Т 0.000103

У 6.6e-05

Ф 3.2e-05

Х 3.8e-05

Ц 2.4e-05

Ч 2.1e-05

Ш 1.2e-05

Щ 9e-06

Ъ 3e-06

Ы 2e-06

Ь 6e-06

Э 4e-06

Ю 1e-06

Я 0.0

Кодовые последовательности, полученные методами Шеннона-Фано и Хаффмана представлены в таблице 5.

Таблица 5

Хаффман

Шеннон - Фано

Ё 0000000000

z 0000000001

D 000000001

t 000000010000

С 00000001000100

j 0000000100010100

f 00000001000101010

Ь 000000010001010110

a 0000000100010101110

Ы 0000000100010101111

k 000000010001011

p 0000000100011

v 00000001001

Й 00000001010

П 0000000101100

m 00000001011010

Ч 0000000101101100

h 00000001011011010

Щ 00000001011011011

Х 000000010110111

Н 000000010111

Г 000000011

ш 0000001

о 000001

X 000010

N 0000110

ю 00001110

H 00001111

п 000100

W 000101

р 000110

V 000111

щ 0010000

C 001000100

Ж 0010001010

y 0010001011

я 00100011

с 001001

U 001010

M 0010110

G 00101110

К 00101111000

u 00101111001

З 0010111101

B 001011111

т 001100

T 001101

ъ 0011100

L 0011101

у 001111

S 010000

Д 010001000

x 0100010010

r 010001001100

Р 0100010011010

e 01000100110110000

g 01000100110110001

i 0100010011011001

Ф 010001001101101

У 01000100110111

Л 01000100111

А 01000101

ы 0100011

ф 010010

K 0100110

F 01001110

Е 010011110

A 010011111

R 010100

х 010101

Б 01011000

E 01011001

ь 0101101

Q 010111

ё 01100

з 01101

е 01110

ж 01111

и 10000

д 10001

J 1001000

О 100100100000

q 100100100001

s 10010010001

И 1001001001

w 1001001010

o 1001001011000

l 10010010110010

Э 100100101100110000

c 1001001011001100010

Ю 10010010110011000110

Я 100100101100110001110

b 100100101100110001111

Ъ 100100101100110010

d 100100101100110011

Ш 1001001011001101

Ц 100100101100111

Т 1001001011010

n 1001001011011

М 10010010111

В 10010011

ц 100101

г 10011

й 10100

в 10101

к 10110

б 10111

P 110000

э 1100010

I 1100011

л 11001

а 11010

м 11011

ч 111000

O 111001

Z 11101

н 11110

Y 11111

ё 000000

з 000001

е 00001

ж 00010

и 00011

д 00100

г 00101

й 00110

в 00111

к 010000

б 010001

л 01001

а 01010

м 01011

Z 011000

н 011001

Y 01101

о 01110

X 01111

п 100000

W 100001

р 100010

V 100011

с 100100

U 100101

т 10011

T 101000

у 101001

S 101010

ф 101011

R 101100

х 101101

Q 10111

ц 1100000

P 1100001

ч 110001

O 110010

ш 110011

N 1101000

щ 1101001

M 110101

ъ 1101100

L 1101101

ы 110111

K 1110000

ь 1110001

J 1110010

э 1110011

I 11101000

ю 11101001

H 1110101

я 1110110

G 1110111

А 11110000

F 11110001

Б 11110010

E 11110011

В 11110100

D 11110101

Г 11110110

C 11110111

B 111110000

Д 111110001

Е 11111001

A 111110100

Ё 111110101

z 111110110

Ж 111110111

y 1111110000

З 1111110001

x 111111001

И 1111110100

w 1111110101

v 1111110110

Й 1111110111

К 11111110000

u 11111110001

Л 1111111001

s 11111110100

М 11111110101

t 1111111011

Н 111111110000

r 111111110001

О 11111111001

q 11111111010

p 11111111011

П 1111111110000

Р 1111111110001

o 111111111001

Т 111111111010

n 111111111011

С 1111111111000

m 1111111111001

У 1111111111010

l 1111111111011

k 11111111111000

Х 11111111111001

Ф 111111111110100

j 111111111110101

Ц 11111111111011

Ч 111111111111000

i 111111111111001

f 111111111111010

Ш 111111111111011

h 1111111111111000

e 1111111111111001

Щ 1111111111111010

g 1111111111111011

Ь 11111111111111000

Э 11111111111111001

a 1111111111111101

d 11111111111111100

Ъ 11111111111111101

c 111111111111111100

Ы 111111111111111101

Ю 111111111111111110

b 1111111111111111110

Я 1111111111111111111