Sunteți pe pagina 1din 6

07.12.2022, 04:54 Copie a blocnotesului Lucrarea4.

ipynb - Colaboratory

Obiectivul lucrării
Stocarea și transmisia digitală a datelor necesită conversia informației transmise de sursă în biți. Creșterea e ficienței transmisiunii impune
codarea sursei primare, operație ce conduce la maximizarea transinformației. Lucrarea are ca scop introducerea noțiunilor legate de codarea
surselor discrete si prezentarea algoritmilor folosiți uzual pentru implementarea codării: Shannon Fano si Huffman.

Aspecte teoretice
Scopul principal al codării de surs este să permită trecerea de la alfabetul sursei la alfabetul canalului. Cazurile în care efectul perturbațiilor
asupra transmisiei datelor este nesemni cativ (transmisii la distanțe mici, putere de emisie mare, etc) impun codarea surselor discrete de
informație astfel încât să facă posibilă transmisia pe canal într-un timp cât mai scurt.

În plus, datele furnizate de o sursă discretă sunt adesea redundante. Conectarea directă a unei asemenea surse la canalul de comunicație
conduce la utilizarea neeconomică a acestuia. Distribuția de probabilitate a simbolurilor emise nu poate asigura entropia maximă a sursei și, ca
urmare, canalul nu poate utilizat la capacitatea sa, chiar dacă nu este afectat de perturbații, ceea ce conduce la o e ciența redusă a
transmisiunii în ansamblu.

Pentru a asigura prin canal transinformația la valoarea sa maximă, este necesar ca sursa primară să
fie transformată, prin operația de codare, într-o sursă secundară , specifi cat de setul de probabilități care maximizeaz transinformația (entropia
sursei secundare cât mai apropiat de cea maximă). Se introduce astfel un codor ce va realiza adaptarea statistică a sursei la canalul de
comunicație. Acesta implementează o codare compactă, care generează cuvinte de cod într-o reprezentare cu un numar de biți cât mai mic,
optim în raport cu un criteriu de compactare adecvat. Acest criteriu va lua în considerare maximizarea entropiei și posibilitatea realizării unei
decodări sigure și facile la recepție.

Fie sursa primară descrisă de alfabetul [S ] ce conține N simboluri a căror distribuție de probabilitati este [P S ] :
[S ] = [s1 , s2 , . . . . . sN ]

[P S ] = [p(s1 ), p(s2 ), . . . . . p(sN )]

Sursa secundară este descrisă de alfabetul [X] ce include D simboluri și distribuția de probabilități [P X ] :
[X] = [x1 , x2 , . . . . . xD ]

[P X ] = [p(x1 ), p(x2 ), . . . . . p(xD )]

Se alocă fiecărui simbol si din alfabetul sursei primare, prin codare compactă, un cuvânt de cod ci , de lungime li , format din literele xk ,
k = 1, . . . D . Codul astel obținut este: [C ] = [c1 , c2 , . . . . . cN ] .
si ∈ S     ⟹    ci ∈ C

Prin codare se urmărește eficiența transmisiei informației. În cazul canalelor fără zgomot mărirea eficienței presupune minimizarea unei
anumite funcții de cost, cea mai simplă funcție fiind cea care asociază costului ti durata cuvântului. Considerând faptul ca prețul exploatării
unui sistem de transmisiune poate fi estimat ca fiind aproximativ liniar crescător cu timpul, costul mediu pe mesaj devine:
N n
¯
¯¯¯
C = ∑ ti ⋅ p(ci ) = ∑ ti ⋅ p(si )

i=1 i=1

Dacă toate literele xi din alfabetul [X] al codului au aceeași durata τ care se poate considera egală cu unitatea (τ = 1) atunci:
ti = li ⋅ τ

¯
adică durata unui cuvânt este egală cu numărul de litere care formează acel cuvant ci , costul mediu fiind astfel asociat cu lungimea medie l a
unui cuvant de cod.
n
¯
¯¯¯ ¯
C = ∑ li ⋅ p(si ) = l

i=1

Creșterea eficienței se poate obține printr-o atribuire convenabilă a cuvintelor de cod fiecărui mesaj al sursei primare, luându-se în considerare
distribuția de probabilități a sursei.

Limita inferioară a lungimii medii a unui cuvănt de cod

Fie o sursă S , caracterizată de alfabetul [S ] = [s1 , s2 . . . . . sN ] cu distribuția de probabilități [P S ] = [p(s1 ), p(s2 ), . . . . . p(sN )] și un cod
[C ] = [c1 , c2 . . . . . cN ] , ale cărui cuvinte apar cu aceleași probabilități ca mesajele sursei p(ci ) = p(si ) . Lungimile cuvintelor de cod sunt:
[L] = [l1 , l2 . . . . . lN ] unde li este numărul de litere din alfabetul codului [X] = [x1 , x2 . . . . . xD ] care compun cuvântul ci .

https://colab.research.google.com/drive/1w45EEEubo5bVLrWn1GfuoN4bj8clTBuI#scrollTo=bFtLxJKId70R&printMode=true 1/6
07.12.2022, 04:54 Copie a blocnotesului Lucrarea4.ipynb - Colaboratory

Entropia sursei este:


N

H (S ) = H (C ) = − ∑ p(si ) log p(si )

i=1

unde H (C ) este entropia cuvintelor codului. Entropia alfabetului codului este:


D

H (X) = − ∑ p(xi ) log p(xi )

i=1

¯
Informația medie pe un cuvânt de cod este dată de produsul dintre numărul mediu de litere l și informația medie pe literă H (X) :
¯
H (S ) = l ⋅ H (X)

Valoarea maximă a entropiei H (X) se obține atunci când probabilitățile p(xi ) ale literelor codului sunt egale, respectiv Hmax (X) = log D .

Relația devine:
¯ ¯
H (S ) = l ⋅ H (X) ≤ l ⋅ log D

Altfel spus:
¯
H (S )
¯
l ≥ = lmin
log D

relație care arată că lungimea medie a unui cuvânt de cod are o margine inferioară egală cu entropia sursei împărțită la valoarea maximă a
entropiei alfabetului codului sau că:
H (S )
≤ log D
¯
l

informația medie pe o literă din alfabetul codului nu poate fi mai mare decat valoarea maximă a entropiei alfabetului codului.

Capacitatea, eficiența și redundanța codului

1. Capacitatea codului. Capacitatea unui canal fără perturbații este atinsă când sursa secundară este o sursă de entropie maximă:
C = sup[H (X) − H (X/Y )] = max H (X) = log D
p(x)

unde D reprezinta alfabetul de intrare al canalului și, în același timp, alfabetul codului. Deoarce H (X/Y ) = 0 se definește capacitatea
codului ca valoarea maximă a entropiei sursei secundare:
CC = max H (X) = log D
p(x)

2. Eficiența codului. este raportul dintre entropia sursei secundare H (X) și valoarea sa maximă Hmax (X) sau raportul dintre lungimea
¯ ¯
medie minimă lmin și lungimea medie l a cuvintelor de cod:

¯
H (S ) H (X) H (X) lmin
ηC = = = =
¯ ¯
Hmax (X) log D
l ⋅ log D l

3. Redundanța codului este mărimea complementară eficienței:


log D − H (X)
ρC = 1 − η C =
log D

¯ ¯
Codurile pentru care l = lmin ; η = 1; ρ = 0 sunt coduri absolut optimale. Dacă pentru un cod oarecare este îndeplinită aceasta relație nu
rezultă ca el este absolut optimal, însă, cu alfabetul și cu lungimile date se poate forma un cod absolut optimal.
¯ ¯
Codurile pentru care l > lmin ; η < 1; ρ > 0 sunt coduri optimal.

Considerând surse discrete cu debit controlabil și fără memorie, pentru codare compactă se folosesc algoritmii Shannon-Fano (Shannon 1948,
Fano 1949) si Huffman (1952).

Inegalitatea McMillan
¯¯
¯¯¯¯¯¯
¯
Condiția necesară de existență a unui cod fără prefix - instantaneu, de alfabet de dimensiune D, cu lungimea cuvintelor de cod li ,  i = 1, N

este dată de inegalitatea Kraft McMillan:


N

−li
∑D ≤ 1

i=1

Pentru codurile absolut optimale inegalitatea devine egalitate.

Codarea pe grupe de simboluri

Conform teoremei I a lui Shannon codarea extensiilor unei surse discrete de informație conduce la obținerea unor lungimi medii ale cuvintelor
de cod cu atât mai mici cu cât ordinul extensiei este mai mare. Aplicațiile practice nu permit însă codarea extensiei de ordinul m a sursei cand
m → ∞ din motive ce țin de complexitatea codorului asa încât, în general se realizează codări pe mesajele individuale ale sursei - simbol cu
simbol folosindu-se algoritmi ce conduc la coduri instantanee de eficiență cât mai mare.

Desfășurarea lucrării

https://colab.research.google.com/drive/1w45EEEubo5bVLrWn1GfuoN4bj8clTBuI#scrollTo=bFtLxJKId70R&printMode=true 2/6
07.12.2022, 04:54 Copie a blocnotesului Lucrarea4.ipynb - Colaboratory

PROBLEMA
Determinati dictionarul binar (D=2) al codului Huffman pentru un text la alegerea voastra. Folosind setul de probabilitati rezultat din cod,
realizati codarea, pe hartie si comparati rezultatele.

Codarea Huffman. Dacă sursa se codeaza simbol cu simbol problema care apare este identificarea unei metode de codare care să genereze un
cod optimal pentru orice distribuție de probabilități a sursei primare, altfel spus să nu existe o alta procedură de codare care să conducă la o
eficiență mai mare. În acest caz cuvintele de cod obținute vor avea cea mai mică lungime medie în raport cu lungimile medii ce se pot obține
prin alte metode.

Înainte de expunerea metodei două proprietăți generale ale codurilor optimale trebuie menționate:

1. Cel mai scurt cuvînt de cod să fie atribuit simbolului cu probabilitatea cea mai mare. În acest scop se ordonează simbolurile în ordinea
descrescatoare a probabilitaților. Ordonarea asigură existența unei lungimi medii minime!
2. Ultimele două cuvinte de cod au aceeași lungime.

Codarea Huffman cu D simboluri presupune parcurgerea următorilor pași:

1. Cele N simboluri ale sursei se aranjează în ordinea descrescătoare a probabilitatilor;


2. Se formează mulțimi de mesaje care să poată fi divizate în două submultimi de probabilitati cât mai apropiate. Se notează sursa primară
rezultată cu R0 ;
3. Se grupează ultimele D simboluri de cele mai mici probabilitati, într-un simbol artificial r1 cu probabilitatea p(r1 ) egală cu suma
probabilitatilor simbolurilor grupate; se obtine sursa restransa de ordin 1, R1 .
4. Se atribuie câte una din literele alfabetului codului celor D simboluri grupate;
5. Se repetă pașii precedenți până când se ajunge la o sursa restrânsă RN −D care furnizează doar D simboluri;
6. Cuvântul de cod complet, corespunzător unui simbol al sursei primare, este constituit din secvența literelor codului obținută prin
parcurgerea surselor restranse în sensul opus restrângerii, până la găsirea simbolului original; aceasta echivalează cu parcurgerea unui
arbore de la un nod final la rădacină.

EXEMPLU.Fie o sursa S ce emite patru simboluri cu probabilitățile [ 2 , . Identificați un cod Huffman binar pentru sursa dată.
1 1 1 1
, , ]
4 8 8

Observatie. Un cod optimal de alfabet D trebuie să îndeplinească relația:


N − D
∈ N
D − 1

unde N este num'arul de simboluri al sursei primare. Codarea ternară, D = 3 , a unei surse ce emite N = 6 simboluri presupune adaugarea
celui de-al 7 -lea simbol, de probabilitate p(s7 ) = 0 pentru realizarea codării.

from math import log2 
import sys

string = 'informatie'

# Creating tree nodes
class NodeTree(object):

    def __init__(self, left=None, right=None):
        self.left = left
        self.right = right

    def children(self):
        return (self.left, self.right)

    def nodes(self):
        return (self.left, self.right)

    def __str__(self):
        return '%s_%s' % (self.left, self.right)

https://colab.research.google.com/drive/1w45EEEubo5bVLrWn1GfuoN4bj8clTBuI#scrollTo=bFtLxJKId70R&printMode=true 3/6
07.12.2022, 04:54 Copie a blocnotesului Lucrarea4.ipynb - Colaboratory

# Main function implementing huffman coding
def huffman_code_tree(node, left=True, binString=''):
    if type(node) is str:
        return {node: binString}
    (l, r) = node.children()
    d = dict()
    d.update(huffman_code_tree(l, True, binString + '0'))
    d.update(huffman_code_tree(r, False, binString + '1'))
    return d

# Calculating frequency
freq = {}
for c in string:
    if c in freq:
        freq[c] += 1
    else:
        freq[c] = 1

freq = sorted(freq.items(), key=lambda x: x[1], reverse=True)

nodes = freq

while len(nodes) > 1:
    (key1, c1) = nodes[-1]
    (key2, c2) = nodes[-2]
    nodes = nodes[:-2]
    node = NodeTree(key1, key2)
    nodes.append((node, c1 + c2))

    nodes = sorted(nodes, key=lambda x: x[1], reverse=True)

huffmanCode = huffman_code_tree(nodes[0][0])

print(' Char | Huffman code ')
print('----------------------')
for (char, frequency) in freq:
    print(' %-4r |%12s' % (char, huffmanCode[char]))

Char | Huffman code


----------------------
'i' | 10
'n' | 001
'f' | 000
'o' | 011
'r' | 010
'm' | 1101
'a' | 1100
't' | 1111
'e' | 1110

https://colab.research.google.com/drive/1w45EEEubo5bVLrWn1GfuoN4bj8clTBuI#scrollTo=bFtLxJKId70R&printMode=true 4/6
07.12.2022, 04:54 Copie a blocnotesului Lucrarea4.ipynb - Colaboratory
print('Frecventele de aparitie ale literelor:')
print(freq)
print('Lungimea intregului sir, numarul de caractere:')
length = len(string) 
print(length)

#lungimile cuvintelor de cod
l=[];
#frecventele=[];
for  (char,frequency) in freq:
    l.append(len((huffmanCode[char])))
    #frecventele.append(frequency)
print('Lungimile cuvintelor de cod:')
print(l)
print('Probabilitatile literelor:')
probs = [float("{:.2f}".format(frequency[1]/length)) for frequency in freq]
print(probs)

#lungimea medie
l_med = sum([a*b for a, b in zip(l, probs)])
print('Lungimea medie a codului:')
print(round(l_med,2))
# determinarea lungimii minime medii H(S)/log2(D)
entropia = -sum([p * log2(p) for p in probs])
print("Entropia sursei - lungimea minima:", round(entropia,2))
eficienta=round(entropia/l_med,2)
print("Eficienta codului:", eficienta)
    

Frecventele de aparitie ale literelor:


[('i', 2), ('n', 1), ('f', 1), ('o', 1), ('r', 1), ('m', 1), ('a', 1), ('t', 1), ('e', 1)]
Lungimea intregului sir, numarul de caractere:
10
Lungimile cuvintelor de cod:
[2, 3, 3, 3, 3, 4, 4, 4, 4]
Probabilitatile literelor:
[0.2, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]
Lungimea medie a codului:
3.2
Entropia sursei - lungimea minima: 3.12
Eficienta codului: 0.98

Exercitii propuse
Fie o sursă S ce emite mesajele [S ] = [1, 2, 3, 4, 5] . Se considera doua distributii P S si QS ale variabilei aleatoare ce descrie sursa
prezentata in tabel. Ultimele doua coloane ale tabelului con'tin coduri binare asociate sursei date.

Scrieti in Python secventa de cod necesara* asa incat sa:

1. Calculati H (P S ) si H (QS ) ;
2. Verificati ca lungimea minima medie a codului C1 sub distributia P S este egala cu entropia H (P S ) . Este C1 absolut optimal pentru P S ?
Este C2 un cod absolut optimal pentru QS ?
3. Se presupune ca se utilizeaza codul C2 cand distributia este P S . Care este lungimea medie a cuvantului de cod? Cu cat este mai mare
aceasta fata de entropia H (P S ) ?
4. Care este pierderea daca este folosit codul C1 cand distributia este QS ?

creati un sir de caractere care sa genereze probabilitatile P si Q pentru codul anterior.

https://colab.research.google.com/drive/1w45EEEubo5bVLrWn1GfuoN4bj8clTBuI#scrollTo=bFtLxJKId70R&printMode=true 5/6
07.12.2022, 04:54 Copie a blocnotesului Lucrarea4.ipynb - Colaboratory
from math import log2
import sys
import numpy as np

ps=[1/2,1/4,1/8,1/16,1/16]
qs=[1/2,1/8,1/8,1/8,1/8]
l1=[1,2,3,4,4]
l2=[1,3,3,3,3]

def entropie(Xprob):
    H =[]
    for ps in Xprob:
        if ps != 0:
           H.append(ps * log2(ps))
    H = -sum(H)
    return H
print("1.")

H = entropie(ps) # entropia sursei
H=round(H,2)
print('H(Ps) = ',H, 'biti/simbol')

H = entropie(qs) # entropia sursei
H=round(H,2)
print('H(Qs) = ',H, 'biti/simbol')

print("2.")

# determinarea lungimii minime medii H(S)/log2(D)
entropia = -sum([p * log2(p) for p in ps])
print("Entropia sursei - lungimea minima C1 pentru Ps:", round(entropia,2))

l_med = sum([a*b for a, b in zip(l1, ps)])
print('Lungimea medie a codului C1 pentru Ps:')
print(round(l_med,2))
print('C1 este cod absolut optimal pentru Ps')
entropia = -sum([p * log2(p) for p in qs])
print("Entropia sursei - lungimea minima C2 pentru Qs:", round(entropia,2))
l_med = sum([a*b for a, b in zip(l2, qs)])
print('Lungimea medie a codului C2 pentru Qs:')
print(round(l_med,2))
print('C2 este cod absolut optimal pentru Qs')
print("3.")
l_med = sum([a*b for a, b in zip(l2, ps)])
print('Lungimea medie a codului C2 pentru Ps:')
print(round(l_med,2))
diferenta=entropie(ps)-round(l med,2)
1.
H(Ps) = 1.88 biti/simbol
H(Qs) = 2.0 biti/simbol
2.
Entropia sursei - lungimea minima C1 pentru Ps: 1.88
Lungimea medie a codului C1 pentru Ps:
1.88
C1 este cod absolut optimal pentru Ps
Entropia sursei - lungimea minima C2 pentru Qs: 2.0
Lungimea medie a codului C2 pentru Qs:
2.0
C2 este cod absolut optimal pentru Qs
3.
Lungimea medie a codului C2 pentru Ps:
2.0
Diferenta este de= 0.125 Produse cu plată din Colaborare - Anulați contractele de aici
4.
check 0 sec. s-a finalizat la 04:54

https://colab.research.google.com/drive/1w45EEEubo5bVLrWn1GfuoN4bj8clTBuI#scrollTo=bFtLxJKId70R&printMode=true 6/6

S-ar putea să vă placă și