La codifica di Huffman
Codici ottimi - I Un codice è ottimo se ha la lunghezza media di parola L più piccola Si può vedere come un problema di ottimizzazione
Codici ottimi - II Facciamo 2 assunzioni per semplificare la trattazione 1.nessun vincolo di interezza sulle lunghezze di parola 2.la disuguaglianza di Kraft vale all'uguaglianza Problema ai moltiplicatori di Lagrange
Codici ottimi - III Sostituiamo nella (dis)uguaglianza di Kraft cioè Notare che l'entropia, se usiamo la base D per i logaritmi
Codici ottimi - IV In pratica, le lunghezze di parola devono essere intere, quindi il risultato ottenuto è un limite inferiore TEOREMA La lunghezza media di un qualunque codice istantaneo con alfabeto a D simboli per una variabile casuale X soddisfa Questo risultato fondamentale è opera di Shannon
Codici ottimi - V E per quanto riguarda il limite superiore? TEOREMA Dato un alfabeto sorgente (cioè una var. casuale) X entropia H(X) è possibile trovare un codice istantaneo binario la cui lunghezza media soddisfi Un teorema simile vale anche nel caso in cui utilizziamo un insieme di probabilità {q i } non corrette, al posto di {p i }; l'unica differenza consiste in un termine che tiene conto della entropia relativa dei due insiemi
Ridondanza Si definisce come la lunghezza media del codice meno l'entropia Si noti che - perché?
Rapporto di compressione E' il rapporto fra il numero medio di bit/simbolo nel messaggio originale e la stessa quantità nel messaggio compresso, ossia
Codici univocamente decodificabili L'insieme dei codici istantanei è una piccola frazione dei codici univocamente decodificabili E' possibile ottenere una lunghezza media del codice inferiore utilizzando un codice univocamente decodificabile ma non istantaneo? NO Perciò si usano i codici istantanei che sono più facili da decodificare...
Riassunto Lunghezza media di parola (del codice) L L ≥ H(X) per i codici univocamente decodificabili (e per quelli istantanei) In pratica per ogni variabile casuale X con entropia H(X) si può costruire un codice con lunghezza media tale che
Codifica di Shannon-Fano Il principale vantaggio della codifica di Shannon-Fano è la sua semplicità 1.I simboli sorgenti sono ordinati per probabilità non decrescente 2.La lista viene divisa in due parti in modo tale da essi abbiano probabilità totale il più simile possibile 3.Ciascun simbolo nel primo gruppo riceve uno 0 come prima cifra del suo codice, mentre quelli del secondo gruppo ricevono un 1 4.Ciascuno di questi due gruppi è suddiviso di nuovo cono lo stesso criterio usato prima e ulteriori cifre sono aggiunte ad ogni simbolo 5.Si procede finché ogni gruppo non contiene esattamente un simbolo
Esempio H= bits L= bits
Esercizio sulla codifica di Shannon-Fano Si crei il codice corrispondente all'algoritmo di codifica di Shannon-Fano
La codifica di Shannon-Fano è ottima? H = bits L = 2.31 bits L 1 =2.3 bits
La codifica di Huffman - I C'è un altro algoritmo le cui performance sono leggermente migliori dell'algoritmo di Shannon- Fano, la famosa codifica di Huffman Essa funziona costruendo un albero dal basso verso l'alto, e nelle foglie stanno i simboli con le loro probabilità Le due foglie con le probabilità più piccole diventano sorelle sotto un nodo padre la cui probabilità è la somma delle loro probabilità
La codifica di Huffman - II A questo punto l'intera operazione viene ripetuta, considerando anche il padre ma ignorando i nodi figli già scelti Il processo continua fino a quando non si ottiene un solo nodo con probabilità 1, che è la radice dell'albero Quindi i due rami che partono da ogni nodo non foglia sono etichettati con 0 e 1 (tipicamente, si usa lo 0 per i rami di sinistra, ma l'ordine non ha importanza)
La codifica di Huffman - esempio 0 a b c 0. 1 d 0. 2 e 0. 3 f 0. 2 g a b c 0. 1 d 0. 2 e 0. 3 f 0. 2 g
La codifica di Huffman - esempio Esercizio: calcolare H(X) e L(X) H(X)= bits L(X)=2.6 bits !!
La codifica di Huffman - esercizio Codificare la sequenza aeebcddegfced e calcolare il rapporto di compressione Sol: Lungh. media per simbolo orig. = 3 bits Lungh. media per simbolo compr. = 34/13 C=.....
La codifica di Huffman - esercizio Decodificare Sol: dfdcadgf
La codifica di Huffman - esercizio Codificare con Huffman la sequenza 01$cc0a02ba10 e calcolare l'entropia, la lunghezza media del codice ed il rapporto di compressione
La codifica di Huffman - esercizio Decodificare (se possibile) il seguente stream di bit codificato con Huffman
La codifica di Huffman - note Se durante la codifica esistono più coppie possibili con le probabilità più piccole, qualunque scelta va bene Talvolta la lista delle probabilità è inizializzata ordinandola in ordine non decrescente e riordinata dopo la creazione di ogni nodo. Ciò non ha conseguenze sulla correttezza dell'algoritmo ma consente di avere un'implementazione più efficiente. (perché?)
La codifica di Huffman - note Esistono casi in cui la codifica di Huffman non determina univocamente la lunghezza delle parole di codice, a causa delle scelte arbitrarie fra coppie di probabilità minime. Per esempio nel caso di una sorgente con probabilità {0.4, 0.2, 0.2, 0.1, 0,1} è possibile ottenere parole di codice di lunghezza [2, 2, 2, 3, 3] e [1, 2, 3, 4, 4] Sarebbe meglio avere parole di codice la cui lunghezza ha varianza minima, dal momento che questa soluzione avrebbe bisogno di buffer di lunghezza minima per il trasmittente e per il ricevente
La codifica di Huffman - note Schwarz ha proposto una variante dell'algoritmo di Huffman che consente di costruire il codice che ha la minima lunghezza lmax Esistono molte altre varianti dell'algoritmo di Huffman e più avanti vedremo le principali
Ottimalità della codifica di Huffman - I E' possibile dimostrare che, nel caso di codifica un simbolo alla volta (un simbolo, una parola di codice), il codice di Huffman è ottimo Detto in altri termini, esso ha minima ridondanza E' stato trovato un limite superiore per la ridondanza dove p 1 è la probabilità del simbolo più probabile
Ottimalità della codifica di Huffman - II Come mai l'algoritmo di Huffman “soffre” quando c'è un simbolo con probabilità molto alta? Ricorda la nozione di incertezza... Il problema principale è il vincolo che la lunghezza delle parole deve essere un numero intero!! Questa considerazione ci porterà ad una codifica migliore... la vedremo in seguito
La codifica di Huffman - implementazione La codifica di Huffman (cioè i codici) può essere generata in tempo O(n), dove n è il numero di simboli dell'alfabeto sorgente, supponendo che le probabilità siano state preordinate (comunque questo ordinamento costa O(nlogn)...) Nonostante tutto, la codifica è molto veloce
La codifica di Huffman - implementazione Naturalmente, la complessità spaziale e temporale della decodifica sono di gran lunga più importanti perché, in media, la decodifica avverrà più spesso Si consideri un albero di Huffman con n simboli n foglie e n-1 nodi interni ha un puntatore ad un simbolo e l'informazione che è una foglia ha due puntatori
La codifica di Huffman - implementazione 1 milione di simboli → 16 MB di memoria! Inoltre attraversare l'albero dalla radice alle foglie implica seguire molti puntatori, con poca località del codice. Ciò comporta molti page fault e cache miss. Per risolvere questo problema è stata proposta una variante al codice di Huffman: il codice di Huffman canonico
Codice di Huffman canonico - I b c d e f a (0) (1) ?
Codice di Huffman canonico - II Non si può ottenere questo codice con un albero di Huffman! Viene comunque chiamato codice di Huffman perché è istantaneo e le lunghezze di parola sono le stesse rispetto ad un codice di Huffman PROPRIETÀ DI SEQUENZA NUMERICA Ordinando le parole di codice con la stessa lunghezza si ottengono simboli ordinati lessicograficamente
Codice di Huffman canonico - III Il vantaggio principale è che non è più necessario memorizzare un albero per effettuare la decodifica Abbiamo bisogno soltanto di 1.una lista di simboli ordinati secondo l'ordine lessicografico delle parole di codice 2.un array con la prima parola di codice di ogni lunghezza differente
Codice di Huffman canonico - IV Codifica. Supponiamo ci siano n simboli distinti, che per ogni simbolo i abbiamo calcolato la lunghezza l i e che ∀ i l i ≤ maxlength numl[k] = numero di parole con lunghezza k firstcode[k] = num intero per il primo codice di lunghezza k nextcode[k] = num intero per la prossima parola di codice di lunghezza k symbol[-,-] usato per la decodifica codeword[i] gli bit più a destra di questo intero sono il codice per il simbolo i
Huffman canonico - esempio 1. calcola l'array numl 2. Calcola l' array firstcode 3. Costruisci l'array codeword and symbol gfcb d -hea ---- symbol
Codice di Huffman canonico - V Decodifica. Abbiamo gli array firstcode e symbol nextinputbit() funzione che ritorna il prossimo input bit firstcode[k] = numero intero per il primo codice di lunghezza k symbol[k,n] ritorna il simbolo n con lunghezza di parola di codice pari a k
Huffman canonico - esempio gfcb d -hea ---- symbol Decodifica: dhebad symbol[3,0] = d symbol[2,2] = h symbol[2,1] = e symbol[5,0] = b symbol[2,0] = a symbol[3,0] = d symbol[2,2] = h symbol[2,1] = e symbol[5,0] = b symbol[2,0] = a symbol[3,0] = d