55
INF2810: Funksjonell Programmering Huffman-koding Stephan Oepen & Erik Velldal Universitetet i Oslo 22. februar, 2013

INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

  • Upload
    others

  • View
    7

  • Download
    0

Embed Size (px)

Citation preview

Page 1: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

INF2810: Funksjonell programmering

INF2810: Funksjonell Programmering

Huffman-koding

Stephan Oepen & Erik Velldal

Universitetet i Oslo

22. februar, 2013

Page 2: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Tema

Forrige ukeI Data-abstraksjonI Lister av listerI Tre-rekursjonI Prosedyrer som datastruktur

I dagI Hierarkisk og symbolsk dataI Eksempel: Huffman-koding

2

Page 3: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Repetisjon: Prosedyrer som datastruktur

(define (p-cons x y)(lambda (proc) (proc x y)))

(define (p-car proc)(proc (lambda (p q) p)))

(define (p-cdr proc)(proc (lambda (p q) q)))

? (p-cons 2 3)→ #<procedure>

? (p-cdr (p-cons 2 3))→ 3

? (p-car(p-cdr(p-cons 1 (p-cons 2 3))))

→ 2

I Selv datastrukturer kanimplementeres som prosedyrer!

I Vi definerer p-cons som en rentprosedyrebasert versjon av cons.

I Mest en kuriositet; eksempel påhvordan ren funksjonsorienteringkan strekkes overraskende langt.

I (Men vi skal senere i kurset seflere eksempler på prosedyrersom datastrukturer.)

3

Page 4: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Repetisjon: Prosedyrer som datastruktur

(define (p-cons x y)(lambda (proc) (proc x y)))

(define (p-car proc)(proc (lambda (p q) p)))

(define (p-cdr proc)(proc (lambda (p q) q)))

? (p-cons 2 3)→ #<procedure>

? (p-cdr (p-cons 2 3))→ 3

? (p-car(p-cdr(p-cons 1 (p-cons 2 3))))

→ 2

I Selv datastrukturer kanimplementeres som prosedyrer!

I Vi definerer p-cons som en rentprosedyrebasert versjon av cons.

I Mest en kuriositet; eksempel påhvordan ren funksjonsorienteringkan strekkes overraskende langt.

I (Men vi skal senere i kurset seflere eksempler på prosedyrersom datastrukturer.)

3

Page 5: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Repetisjon: Prosedyrer som datastruktur

(define (p-cons x y)(lambda (proc) (proc x y)))

(define (p-car proc)(proc (lambda (p q) p)))

(define (p-cdr proc)(proc (lambda (p q) q)))

? (p-cons 2 3)→ #<procedure>

? (p-cdr (p-cons 2 3))→ 3

? (p-car(p-cdr(p-cons 1 (p-cons 2 3))))

→ 2

I Selv datastrukturer kanimplementeres som prosedyrer!

I Vi definerer p-cons som en rentprosedyrebasert versjon av cons.

I Mest en kuriositet; eksempel påhvordan ren funksjonsorienteringkan strekkes overraskende langt.

I (Men vi skal senere i kurset seflere eksempler på prosedyrersom datastrukturer.)

3

Page 6: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Repetisjon: Prosedyrer som datastruktur

(define (p-cons x y)(lambda (proc) (proc x y)))

(define (p-car proc)(proc (lambda (p q) p)))

(define (p-cdr proc)(proc (lambda (p q) q)))

? (p-cons 2 3)→ #<procedure>

? (p-cdr (p-cons 2 3))→ 3

? (p-car(p-cdr(p-cons 1 (p-cons 2 3))))

→ 2

I Selv datastrukturer kanimplementeres som prosedyrer!

I Vi definerer p-cons som en rentprosedyrebasert versjon av cons.

I Mest en kuriositet; eksempel påhvordan ren funksjonsorienteringkan strekkes overraskende langt.

I (Men vi skal senere i kurset seflere eksempler på prosedyrersom datastrukturer.)

3

Page 7: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Repetisjon: Trær

I Et tre er en type graf, en mengdenoder forbundet med kanter.

I Interne noder har barn / døtre:nye subtrær.

I Den øverste noden kalles rot.

I Løvnoder har ikke barn (såkaltterminalnoder).

I Kantene kan ikke være sykliske.

I Binærtrær: nodene har maks todøtre, venstre/høyre.

I I Scheme kan vi representeretrær som lister av lister.

4

Page 8: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Repetisjon: Rekursjon på lister av lister

(define (fringe tree)(cond ((null? tree) ’())

((pair? tree)(append (fringe (car tree))

(fringe (cdr tree))))(else (list tree))))

? (fringe ’((1 2) ((3) 4)))→ (1 2 3 4)

;; ps: append kombinerer to lister,;; sammenlikning med cons:

? (append ’(1 2) ’(3)) → (1 2 3)

? (cons ’(1 2) ’(3)) → ((1 2) 3)

I fringe; samler alle løvnodene ién flat liste.

I Typisk eksempel på rekursjon pålister av lister:

I Vi ønsker å gjøre noe for hvertatomære element (løvnodene):

I Må passe på at rekursjonen gårned i hver liste. . .

5

Page 9: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Repetisjon: Rekursjon på lister av lister

(define (fringe tree)(cond ((null? tree) ’())

((pair? tree)(append (fringe (car tree))

(fringe (cdr tree))))(else (list tree))))

? (fringe ’((1 2) ((3) 4)))→ (1 2 3 4)

;; ps: append kombinerer to lister,;; sammenlikning med cons:

? (append ’(1 2) ’(3)) → (1 2 3)

? (cons ’(1 2) ’(3)) → ((1 2) 3)

I fringe; samler alle løvnodene ién flat liste.

I Typisk eksempel på rekursjon pålister av lister:

I Vi ønsker å gjøre noe for hvertatomære element (løvnodene):

I Må passe på at rekursjonen gårned i hver liste. . .

5

Page 10: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Repetisjon: Rekursjon på lister av lister

(define (fringe tree)(cond ((null? tree) ’())

((pair? tree)(append (fringe (car tree))

(fringe (cdr tree))))(else (list tree))))

? (fringe ’((1 2) ((3) 4)))→ (1 2 3 4)

;; ps: append kombinerer to lister,;; sammenlikning med cons:

? (append ’(1 2) ’(3)) → (1 2 3)

? (cons ’(1 2) ’(3)) → ((1 2) 3)

I fringe; samler alle løvnodene ién flat liste.

I Typisk eksempel på rekursjon pålister av lister:

I Vi ønsker å gjøre noe for hvertatomære element (løvnodene):

I Må passe på at rekursjonen gårned i hver liste. . .

5

Page 11: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Lister av lister, del 2:

I . . . men i dag skal vi også se eksempler der rekursjonen velger å kunfølge én gren (i stedet for å gå ned i alle subtrær).

I Vi skal også definere abstrakte datatyper for trær der ikke bareløvnodene men også de interne nodene kan ha verdier.

I Som praktiske eksempler skal vi se på hvordan både mengder ogkomprimeringskoder kan implementeres effektivt som trær.

6

Page 12: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Hvor vi er på vei først: Huffmankoding

I Ved komprimering er målet å kode informasjon med færrest mulig bits(og færre enn den opprinnelig representasjonen).

I Huffmankoding: En algoritme for generere en optimalkomprimeringskode automatisk fra data.

I Oppdaget i 1952.

I Brukes for å komprimere forskjellige typer data som lyd (f.eks mp3),bilder (jpeg), video (mpeg-1), og tekst (gzip / bzip2).

I Men aller først trenger vi litt terminologi. . .

7

Page 13: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Hvor vi er på vei først: Huffmankoding

I Ved komprimering er målet å kode informasjon med færrest mulig bits(og færre enn den opprinnelig representasjonen).

I Huffmankoding: En algoritme for generere en optimalkomprimeringskode automatisk fra data.

I Oppdaget i 1952.

I Brukes for å komprimere forskjellige typer data som lyd (f.eks mp3),bilder (jpeg), video (mpeg-1), og tekst (gzip / bzip2).

I Men aller først trenger vi litt terminologi. . .

7

Page 14: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Litt kompresjons- og kryptografi-sjargongI Vi har et alfabet av symboler

I F.eks {E, T, A, Z}

I En kodebok tilskriver en kode (kode-ord) til hvert symbol.I F.eks E = 00

I Vi ønsker å kunne gjøre to ting:

I å kode / komprimere data (ofte kalt melding) til en kompakt kode.

I å dekode / dekomprimere en kode tilbake til lesbare data.

I Koding for kompresjon vs kryptering; forskjellig mål:effektiv lagring / overføring vs effektiv skjuling av informasjon.

I Tapsfri (lossless):I Opprinnelig melding kan rekonstrueres eksakt.

I Ikke-tapsfri (lossy):I Opprinnelig melding kan ikke rekonstrueres eksakt.

8

Page 15: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Litt kompresjons- og kryptografi-sjargongI Vi har et alfabet av symboler

I F.eks {E, T, A, Z}

I En kodebok tilskriver en kode (kode-ord) til hvert symbol.I F.eks E = 00

I Vi ønsker å kunne gjøre to ting:

I å kode / komprimere data (ofte kalt melding) til en kompakt kode.

I å dekode / dekomprimere en kode tilbake til lesbare data.

I Koding for kompresjon vs kryptering; forskjellig mål:effektiv lagring / overføring vs effektiv skjuling av informasjon.

I Tapsfri (lossless):I Opprinnelig melding kan rekonstrueres eksakt.

I Ikke-tapsfri (lossy):I Opprinnelig melding kan ikke rekonstrueres eksakt.

8

Page 16: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Litt kompresjons- og kryptografi-sjargongI Vi har et alfabet av symboler

I F.eks {E, T, A, Z}

I En kodebok tilskriver en kode (kode-ord) til hvert symbol.I F.eks E = 00

I Vi ønsker å kunne gjøre to ting:

I å kode / komprimere data (ofte kalt melding) til en kompakt kode.

I å dekode / dekomprimere en kode tilbake til lesbare data.

I Koding for kompresjon vs kryptering; forskjellig mål:effektiv lagring / overføring vs effektiv skjuling av informasjon.

I Tapsfri (lossless):I Opprinnelig melding kan rekonstrueres eksakt.

I Ikke-tapsfri (lossy):I Opprinnelig melding kan ikke rekonstrueres eksakt.

8

Page 17: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Litt kompresjons- og kryptografi-sjargongI Vi har et alfabet av symboler

I F.eks {E, T, A, Z}

I En kodebok tilskriver en kode (kode-ord) til hvert symbol.I F.eks E = 00

I Vi ønsker å kunne gjøre to ting:

I å kode / komprimere data (ofte kalt melding) til en kompakt kode.

I å dekode / dekomprimere en kode tilbake til lesbare data.

I Koding for kompresjon vs kryptering; forskjellig mål:effektiv lagring / overføring vs effektiv skjuling av informasjon.

I Tapsfri (lossless):I Opprinnelig melding kan rekonstrueres eksakt.

I Ikke-tapsfri (lossy):I Opprinnelig melding kan ikke rekonstrueres eksakt.

8

Page 18: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Koder med fast lengde

I Eksempel på en binærkode; ASCII.I sekvens av 7 bits for hvert tegnI Gir mulighet for å representere 27 = 128 ulike tegn.

I Eksempel på såkalt fixed-length code

I For å skille mellom n symboler trenger vi log2 n bits per symbol.

I Enda mer generelt: må bruke logb n kodeposisjoner gitt et kodealfabet avstørrelse b (hvor b = 2 for bits / binærkode).

I Gitt alfabetet {E, T, A, Z } trenger vi log2 4 = 2 bits.

I En mulig kodebok: symbol E T A Zkode 00 01 10 11

I 0001 = ET, 1011 = AZ

9

Page 19: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Koder med fast lengde

I Eksempel på en binærkode; ASCII.I sekvens av 7 bits for hvert tegnI Gir mulighet for å representere 27 = 128 ulike tegn.

I Eksempel på såkalt fixed-length code

I For å skille mellom n symboler trenger vi log2 n bits per symbol.I Enda mer generelt: må bruke logb n kodeposisjoner gitt et kodealfabet avstørrelse b (hvor b = 2 for bits / binærkode).

I Gitt alfabetet {E, T, A, Z } trenger vi log2 4 = 2 bits.

I En mulig kodebok: symbol E T A Zkode 00 01 10 11

I 0001 = ET, 1011 = AZ

9

Page 20: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Koder med fast lengde

I Eksempel på en binærkode; ASCII.I sekvens av 7 bits for hvert tegnI Gir mulighet for å representere 27 = 128 ulike tegn.

I Eksempel på såkalt fixed-length code

I For å skille mellom n symboler trenger vi log2 n bits per symbol.I Enda mer generelt: må bruke logb n kodeposisjoner gitt et kodealfabet avstørrelse b (hvor b = 2 for bits / binærkode).

I Gitt alfabetet {E, T, A, Z } trenger vi log2 4 = 2 bits.

I En mulig kodebok: symbol E T A Zkode 00 01 10 11

I 0001 = ET, 1011 = AZ

9

Page 21: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Koder med fast lengde

I Eksempel på en binærkode; ASCII.I sekvens av 7 bits for hvert tegnI Gir mulighet for å representere 27 = 128 ulike tegn.

I Eksempel på såkalt fixed-length code

I For å skille mellom n symboler trenger vi log2 n bits per symbol.I Enda mer generelt: må bruke logb n kodeposisjoner gitt et kodealfabet avstørrelse b (hvor b = 2 for bits / binærkode).

I Gitt alfabetet {E, T, A, Z } trenger vi log2 4 = 2 bits.

I En mulig kodebok: symbol E T A Zkode 00 01 10 11

I 0001 = ET, 1011 = AZ

9

Page 22: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Med fast lengde ignoreres frekvens

I Svakhet: koden over tar ikke hensyn til symbolenes relative frekvens.

I Koden er kun optimal dersom alle symbolene er like sannsynlige.

I Vi kan få en mer kompakt kode dersom symboler som forekommer oftegis en kortere representasjon.

I På Engelsk er f.eks. bokstaven ’E’ mye vanligere enn ’Z’.

I Gjenspeiles f.eks i morsekode;I E = én prikkI Z = to streker og to prikker.

I Morsekode er eksempel på såkalt variable-length code.

10

Page 23: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Med fast lengde ignoreres frekvens

I Svakhet: koden over tar ikke hensyn til symbolenes relative frekvens.

I Koden er kun optimal dersom alle symbolene er like sannsynlige.

I Vi kan få en mer kompakt kode dersom symboler som forekommer oftegis en kortere representasjon.

I På Engelsk er f.eks. bokstaven ’E’ mye vanligere enn ’Z’.

I Gjenspeiles f.eks i morsekode;I E = én prikkI Z = to streker og to prikker.

I Morsekode er eksempel på såkalt variable-length code.

10

Page 24: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Kode med variabel lengde

I La oss lage en ny kodebok på bakgrunn av frekvensen for hvert symbol(som vi tenker oss at vi har observert fra data):

symbol E T A Zfrekvens 10 7 5 3kode 0 1 00 01

I Kodeordene har variabel lengde, men er ikke unikt dekodbare:I 01 = ET eller Z?I 0001 = EEET, AZ, EAT, eller AET?

I Mulig løsning: bruk en dedikert utvetydig kode som separator.

I F.eks kort pause i morsekode.

I Bedre: sørg for at ingen kode er prefiks for en annen kode!

11

Page 25: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Kode med variabel lengde

I La oss lage en ny kodebok på bakgrunn av frekvensen for hvert symbol(som vi tenker oss at vi har observert fra data):

symbol E T A Zfrekvens 10 7 5 3kode 0 1 00 01

I Kodeordene har variabel lengde, men er ikke unikt dekodbare:I 01 = ET eller Z?I 0001 = EEET, AZ, EAT, eller AET?

I Mulig løsning: bruk en dedikert utvetydig kode som separator.

I F.eks kort pause i morsekode.

I Bedre: sørg for at ingen kode er prefiks for en annen kode!

11

Page 26: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Kode med variabel lengde

I La oss lage en ny kodebok på bakgrunn av frekvensen for hvert symbol(som vi tenker oss at vi har observert fra data):

symbol E T A Zfrekvens 10 7 5 3kode 0 1 00 01

I Kodeordene har variabel lengde, men er ikke unikt dekodbare:I 01 = ET eller Z?I 0001 = EEET, AZ, EAT, eller AET?

I Mulig løsning: bruk en dedikert utvetydig kode som separator.

I F.eks kort pause i morsekode.

I Bedre: sørg for at ingen kode er prefiks for en annen kode!

11

Page 27: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Kode med variabel lengde

I La oss lage en ny kodebok på bakgrunn av frekvensen for hvert symbol(som vi tenker oss at vi har observert fra data):

symbol E T A Zfrekvens 10 7 5 3kode 0 1 00 01

I Kodeordene har variabel lengde, men er ikke unikt dekodbare:I 01 = ET eller Z?I 0001 = EEET, AZ, EAT, eller AET?

I Mulig løsning: bruk en dedikert utvetydig kode som separator.

I F.eks kort pause i morsekode.

I Bedre: sørg for at ingen kode er prefiks for en annen kode!

11

Page 28: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Prefikskode

I Nytt forslag til kodebok:symbol E T A Zfrekvens 10 7 5 3kode 0 10 110 111

I Her har vi en prefikskode med variabel lengde som er unikt dekodbar.

I Kodeordet som representerer et gitt symbol er aldri et prefiks forkodeordet for et annet symbol.

I Oppnår kompresjon kun dersom symbolene er ikke-uniformt distribuert.I Forekommer alle like ofte kunne vi like gjerne brukt fast lengde.

I Koden 010 står utvetydig for ET.

12

Page 29: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Prefikskode

I Nytt forslag til kodebok:symbol E T A Zfrekvens 10 7 5 3kode 0 10 110 111

I Her har vi en prefikskode med variabel lengde som er unikt dekodbar.

I Kodeordet som representerer et gitt symbol er aldri et prefiks forkodeordet for et annet symbol.

I Oppnår kompresjon kun dersom symbolene er ikke-uniformt distribuert.I Forekommer alle like ofte kunne vi like gjerne brukt fast lengde.

I Koden 010 står utvetydig for ET.

12

Page 30: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Prefikskode

I Nytt forslag til kodebok:symbol E T A Zfrekvens 10 7 5 3kode 0 10 110 111

I Her har vi en prefikskode med variabel lengde som er unikt dekodbar.

I Kodeordet som representerer et gitt symbol er aldri et prefiks forkodeordet for et annet symbol.

I Oppnår kompresjon kun dersom symbolene er ikke-uniformt distribuert.I Forekommer alle like ofte kunne vi like gjerne brukt fast lengde.

I Koden 010 står utvetydig for ET.

12

Page 31: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Prefikskode

I Nytt forslag til kodebok:symbol E T A Zfrekvens 10 7 5 3kode 0 10 110 111

I Her har vi en prefikskode med variabel lengde som er unikt dekodbar.

I Kodeordet som representerer et gitt symbol er aldri et prefiks forkodeordet for et annet symbol.

I Oppnår kompresjon kun dersom symbolene er ikke-uniformt distribuert.I Forekommer alle like ofte kunne vi like gjerne brukt fast lengde.

I Koden 010 står utvetydig for ET.

12

Page 32: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Prefikskode

I Nytt forslag til kodebok:symbol E T A Zfrekvens 10 7 5 3kode 0 10 110 111

I Her har vi en prefikskode med variabel lengde som er unikt dekodbar.

I Kodeordet som representerer et gitt symbol er aldri et prefiks forkodeordet for et annet symbol.

I Oppnår kompresjon kun dersom symbolene er ikke-uniformt distribuert.I Forekommer alle like ofte kunne vi like gjerne brukt fast lengde.

I Koden 010 står utvetydig for ET.

12

Page 33: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

David A. Huffman (1925 – 99)

I Huffman var en pioner i informasjonsteori og matematisk origami (!)

I Definerte en algoritme for å automatiskgenerere optimale prefikskoder fra data.

I Basert på at vi kjenner de relativefrekvensene til symbolene.

I Beskrevet i artikkelen “A Method for theConstruction of Minimum-RedundancyCodes” fra 1952.

I Såkalt Huffman-koding.

I Kodeboken representeres ved etHuffmantre.

13

Page 34: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Huffman-trær

I Kodeboken gitt ved et binærtre.I En venstregren representerer 0I En høyregren representerer 1

I Løvnoder, lagrer:I et symbol,I vekt (frekvens)

I Interne noder, lagrer:I mengden av symbolene iløvnodene under det i treet,

I summen av vektene,I to barn

I Gitt et Huffmantre kan viI kode en gitt datasekvensI dekode en gitt bitsekvens

14

Page 35: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Huffman-trær: koding

I For å kode en melding:

I For hvert symbol:

I Vi begynner ved roten og klatrernedover treet til løvnoden somrepresenterer symbolet.

I Velger gren ved å sjekke hvilkennode symbolet tilhører.

I Legger til 0 for hver venstregren.

I Legger til 1 for hver høyregren.

I F.eks: D = 1011, DB = 1011100

15

Page 36: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Huffman-trær: dekoding

I For å dekode en bitsekvens:

I Begyn ved roten og les av bits;

I Ta til venstre for hver 0.

I Ta til høyre for hver 1.

I Ved en løvnode: les av symboletog begynn fra roten igjen.

I F.eks: 10001010 = BAC

16

Page 37: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Å generere et Huffmantre

I Gitt et alfabet og de relative frekevensene til symbolene, hvordan kan vigenerere kodeboken som vil kode meldinger med færrest mulig bits?

1: Start med en liste av løvnodene.

2: Slå sammen de to nodene med lavest frekvens til en ny node(med summen av frekvensene og unionen av symbolene).

- La den ene noden tilsvare venstregrenen og den andre høyre.

3: Oppdater lista av noder og gjenta fra 2.- Legg til den nye noden og fjern nodene vi slo sammen.

4: Stopp når vi står igjen med kun én node (roten).

17

Page 38: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Å generere et Huffmantre (forts.)

Start: {(A 8) (B 3) (C 1) (D 1) (E 1) (F 1) (G 1) (H 1)}

Sammenslåing: {(A 8) (B 3) ({C D} 2) (E 1) (F 1) (G 1) (H 1)}Sammenslåing: {(A 8) (B 3) ({C D} 2) ({E F} 2) (G 1) (H 1)}Sammenslåing: {(A 8) (B 3) ({C D} 2) ({E F} 2) ({G H} 2)}Sammenslåing: {(A 8) (B 3) ({C D} 2) ({E F G H} 4)}Sammenslåing: {(A 8) ({B C D} 5) ({E F G H} 4)}Sammenslåing: {(A 8) ({B C D E F G H} 9)}Stopp: {({A B C D E F G H} 17)}

18

Page 39: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Å generere et Huffmantre (forts.)

Start: {(A 8) (B 3) (C 1) (D 1) (E 1) (F 1) (G 1) (H 1)}Sammenslåing: {(A 8) (B 3) ({C D} 2) (E 1) (F 1) (G 1) (H 1)}

Sammenslåing: {(A 8) (B 3) ({C D} 2) ({E F} 2) (G 1) (H 1)}Sammenslåing: {(A 8) (B 3) ({C D} 2) ({E F} 2) ({G H} 2)}Sammenslåing: {(A 8) (B 3) ({C D} 2) ({E F G H} 4)}Sammenslåing: {(A 8) ({B C D} 5) ({E F G H} 4)}Sammenslåing: {(A 8) ({B C D E F G H} 9)}Stopp: {({A B C D E F G H} 17)}

18

Page 40: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Å generere et Huffmantre (forts.)

Start: {(A 8) (B 3) (C 1) (D 1) (E 1) (F 1) (G 1) (H 1)}Sammenslåing: {(A 8) (B 3) ({C D} 2) (E 1) (F 1) (G 1) (H 1)}Sammenslåing: {(A 8) (B 3) ({C D} 2) ({E F} 2) (G 1) (H 1)}

Sammenslåing: {(A 8) (B 3) ({C D} 2) ({E F} 2) ({G H} 2)}Sammenslåing: {(A 8) (B 3) ({C D} 2) ({E F G H} 4)}Sammenslåing: {(A 8) ({B C D} 5) ({E F G H} 4)}Sammenslåing: {(A 8) ({B C D E F G H} 9)}Stopp: {({A B C D E F G H} 17)}

18

Page 41: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Å generere et Huffmantre (forts.)

Start: {(A 8) (B 3) (C 1) (D 1) (E 1) (F 1) (G 1) (H 1)}Sammenslåing: {(A 8) (B 3) ({C D} 2) (E 1) (F 1) (G 1) (H 1)}Sammenslåing: {(A 8) (B 3) ({C D} 2) ({E F} 2) (G 1) (H 1)}Sammenslåing: {(A 8) (B 3) ({C D} 2) ({E F} 2) ({G H} 2)}

Sammenslåing: {(A 8) (B 3) ({C D} 2) ({E F G H} 4)}Sammenslåing: {(A 8) ({B C D} 5) ({E F G H} 4)}Sammenslåing: {(A 8) ({B C D E F G H} 9)}Stopp: {({A B C D E F G H} 17)}

18

Page 42: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Å generere et Huffmantre (forts.)

Start: {(A 8) (B 3) (C 1) (D 1) (E 1) (F 1) (G 1) (H 1)}Sammenslåing: {(A 8) (B 3) ({C D} 2) (E 1) (F 1) (G 1) (H 1)}Sammenslåing: {(A 8) (B 3) ({C D} 2) ({E F} 2) (G 1) (H 1)}Sammenslåing: {(A 8) (B 3) ({C D} 2) ({E F} 2) ({G H} 2)}Sammenslåing: {(A 8) (B 3) ({C D} 2) ({E F G H} 4)}

Sammenslåing: {(A 8) ({B C D} 5) ({E F G H} 4)}Sammenslåing: {(A 8) ({B C D E F G H} 9)}Stopp: {({A B C D E F G H} 17)}

18

Page 43: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Å generere et Huffmantre (forts.)

Start: {(A 8) (B 3) (C 1) (D 1) (E 1) (F 1) (G 1) (H 1)}Sammenslåing: {(A 8) (B 3) ({C D} 2) (E 1) (F 1) (G 1) (H 1)}Sammenslåing: {(A 8) (B 3) ({C D} 2) ({E F} 2) (G 1) (H 1)}Sammenslåing: {(A 8) (B 3) ({C D} 2) ({E F} 2) ({G H} 2)}Sammenslåing: {(A 8) (B 3) ({C D} 2) ({E F G H} 4)}Sammenslåing: {(A 8) ({B C D} 5) ({E F G H} 4)}

Sammenslåing: {(A 8) ({B C D E F G H} 9)}Stopp: {({A B C D E F G H} 17)}

18

Page 44: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Å generere et Huffmantre (forts.)

Start: {(A 8) (B 3) (C 1) (D 1) (E 1) (F 1) (G 1) (H 1)}Sammenslåing: {(A 8) (B 3) ({C D} 2) (E 1) (F 1) (G 1) (H 1)}Sammenslåing: {(A 8) (B 3) ({C D} 2) ({E F} 2) (G 1) (H 1)}Sammenslåing: {(A 8) (B 3) ({C D} 2) ({E F} 2) ({G H} 2)}Sammenslåing: {(A 8) (B 3) ({C D} 2) ({E F G H} 4)}Sammenslåing: {(A 8) ({B C D} 5) ({E F G H} 4)}Sammenslåing: {(A 8) ({B C D E F G H} 9)}

Stopp: {({A B C D E F G H} 17)}

18

Page 45: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Å generere et Huffmantre (forts.)

Start: {(A 8) (B 3) (C 1) (D 1) (E 1) (F 1) (G 1) (H 1)}Sammenslåing: {(A 8) (B 3) ({C D} 2) (E 1) (F 1) (G 1) (H 1)}Sammenslåing: {(A 8) (B 3) ({C D} 2) ({E F} 2) (G 1) (H 1)}Sammenslåing: {(A 8) (B 3) ({C D} 2) ({E F} 2) ({G H} 2)}Sammenslåing: {(A 8) (B 3) ({C D} 2) ({E F G H} 4)}Sammenslåing: {(A 8) ({B C D} 5) ({E F G H} 4)}Sammenslåing: {(A 8) ({B C D E F G H} 9)}Stopp: {({A B C D E F G H} 17)}

18

Page 46: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Å generere et Huffmantre (forts.)

Start: {(A 8) (B 3) (C 1) (D 1) (E 1) (F 1) (G 1) (H 1)}Sammenslåing: {(A 8) (B 3) ({C D} 2) (E 1) (F 1) (G 1) (H 1)}Sammenslåing: {(A 8) (B 3) ({C D} 2) ({E F} 2) (G 1) (H 1)}Sammenslåing: {(A 8) (B 3) ({C D} 2) ({E F} 2) ({G H} 2)}Sammenslåing: {(A 8) (B 3) ({C D} 2) ({E F G H} 4)}Sammenslåing: {(A 8) ({B C D} 5) ({E F G H} 4)}Sammenslåing: {(A 8) ({B C D E F G H} 9)}Stopp: {({A B C D E F G H} 17)}

18

Page 47: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Noen kommentarer

I En Huffman-kode er optimal i den forstand at den gir minstgjennomsnittlig kodestørrelse.

I Premisser:I Faktiske symbolfrekvenser i meldingen vi skal kode stemmer overens medfrekvensene som ble brukt for å generere kodetreet.

I Kodeboken må også overføres eller allerede være kjent.I Vi koder ett symbol av gangen.

I Det siste punktet kan i praksis omgås ved at et separat trinn førstdefinerer symbolene i alfabetet.

I Symbolene kan f.eks være lengre sekvenser av tegn eller ord.I Bruk av to trinn er også grunnen til at Huffman-koding, som gir entapsfri kode, kan brukes i ikke-tapsfrie formater:

I F.eks; ved kvantisering mappes flere opprinnelige symboler til et mindresett av symboler (ikke-tapsfritt), som så Huffman-kodes (tapsfritt).

19

Page 48: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Enda flere kommentarer

I Definerer ikke alltid et unikt treI Avhenger av hvordan vi velger hvilken node som blir venstre-/høyregren,I og hvordan vi velger hvilke noder for sammenslåing når flere enn to harsamme verdi.

I Det kan altså finnes flere optimale koder.

I EffektiviseringI Hold nodelista frekvenssortert; kan da alltid slå sammen de to første.

I Vi skal se på en abstraksjonsbarriere for å jobbe mot Huffmantrær.

20

Page 49: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Litt repetisjon: Abstraksjonsbarrierer

I Hva mener vi med abstraksjonsbarriere?I Ikke en barriere mot abstraksjon.I Men en abstraksjon som fungerer som en barriere.

I Når vi introduserer en ny abstrakt datatype definerer vi også etgrensesnitt mot datatypen:

I F.eks konstruktorer, aksessorer og predikat.I Danner en abstraksjonsbarriere.

I Andre deler av programmet har kun kontakt med datatypen gjennomdette grensesnittet.

I Skjuler detaljene om nøyaktig hvordan datatypen er implementert.

21

Page 50: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Huffmantrær: Abstraksjonsbarriere

I Løvnoder; representert av enliste med tre elementer:

- leaf (typetagg)- symbol- vekt (frekvens)

I Konstruktor:- make-leaf

I Predikat- leaf?

I Aksessorer:- symbol-leaf- weight-leaf

(define (make-leaf symbol weight)(list ’leaf symbol weight))

(define (leaf? object)(eq? (car object) ’leaf))

(define (symbol-leaf x) (cadr x))

(define (weight-leaf x) (caddr x))

22

Page 51: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Huffmantrær: Abstraksjonsbarriere (forts.)

I Interne noder; liste medfire elementer:

- venstre-gren,- høyre-gren- liste av symboler- vekt

I Konstruktor:- make-code-tree

I Aksessorer:- left-branch- right-branch- symbols- weight

(define (make-code-tree left right)(list left

right(append (symbols left)

(symbols right))(+ (weight left) (weight right))))

(define (left-branch tree) (car tree))

(define (right-branch tree) (cadr tree))

(define (symbols tree)(if (leaf? tree)

(list (symbol-leaf tree))(caddr tree)))

(define (weight tree)(if (leaf? tree)

(weight-leaf tree)(cadddr tree)))

23

Page 52: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Dekoding

(define (decode bits tree)(define (decode-1 bits current-branch)

(if (null? bits)’()(let ((next-branch

(choose-branch (car bits) current-branch)))(if (leaf? next-branch)

(cons (symbol-leaf next-branch)(decode-1 (cdr bits) tree))

(decode-1 (cdr bits) next-branch)))))(decode-1 bits tree))

(define (choose-branch bit branch)(cond ((= bit 0) (left-branch branch))

((= bit 1) (right-branch branch))(else (error "bad bit – CHOOSE-BRANCH" bit))))

I Hvorfor bruker vi decode-1? Kalles jo med de samme argumentene,hvorfor ikke bare kalle decode?

I Kan vi skrive en halerekursiv versjon av decode?

24

Page 53: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Dekoding

(define (decode bits tree)(define (decode-1 bits current-branch)

(if (null? bits)’()(let ((next-branch

(choose-branch (car bits) current-branch)))(if (leaf? next-branch)

(cons (symbol-leaf next-branch)(decode-1 (cdr bits) tree))

(decode-1 (cdr bits) next-branch)))))(decode-1 bits tree))

(define (choose-branch bit branch)(cond ((= bit 0) (left-branch branch))

((= bit 1) (right-branch branch))(else (error "bad bit – CHOOSE-BRANCH" bit))))

I Hvorfor bruker vi decode-1? Kalles jo med de samme argumentene,hvorfor ikke bare kalle decode?

I Kan vi skrive en halerekursiv versjon av decode?

24

Page 54: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Dekoding

(define (decode bits tree)(define (decode-1 bits current-branch)

(if (null? bits)’()(let ((next-branch

(choose-branch (car bits) current-branch)))(if (leaf? next-branch)

(cons (symbol-leaf next-branch)(decode-1 (cdr bits) tree))

(decode-1 (cdr bits) next-branch)))))(decode-1 bits tree))

(define (choose-branch bit branch)(cond ((= bit 0) (left-branch branch))

((= bit 1) (right-branch branch))(else (error "bad bit – CHOOSE-BRANCH" bit))))

I Hvorfor bruker vi decode-1? Kalles jo med de samme argumentene,hvorfor ikke bare kalle decode?

I Kan vi skrive en halerekursiv versjon av decode?24

Page 55: INF2810: Funksjonell Programmering [4ex]Huffman …...Repetisjon: Prosedyrersomdatastruktur (define (p-consx y) (lambda (proc) (proc x y))) (define (p-carproc) (proc (lambda (p q)

Andre ting som gjenstår

I Flere prosedyrer dere kommer til åskrive i neste innlevering:

I encodeI Input: et Huffmantre og enmelding (liste av symboler).

I Output: en bitsekvens(liste av 0 og 1).

I generate-codebookI Input: en liste av symboler ogfrekvenser.

I Output: et Huffmantre.

25