Skip to content
Snippets Groups Projects
Commit 0f15f6e2 authored by Jacob Theisen's avatar Jacob Theisen
Browse files

Ferdig for faen

parent 0c4e5c85
Branches
No related tags found
No related merge requests found
...@@ -94,14 +94,19 @@ for i in range(0,len(lz_code),6): ...@@ -94,14 +94,19 @@ for i in range(0,len(lz_code),6):
value = int.from_bytes(value, 'little') value = int.from_bytes(value, 'little')
with open('./hm_uncomp', 'ab') as file: with open('./hm_uncomp', 'ab') as file:
file.write(value.to_bytes(2, 'little')) file.write(value.to_bytes(2, 'little'))
for k in huff_string[:value]: j = 0
if k not in string.printable and k not in extended_string: a = len(huff_string[:value])
print('nor') while True:
if j >= a:
break
if huff_string[:value][j] not in string.printable and huff_string[:value][j] not in extended_string:
a -= 2
counter += 2 counter += 2
elif k not in string.printable: elif huff_string[:value][j] not in string.printable:
print('extende') a -=1
counter += 1 counter += 1
print(counter) j += 1
#print(huff_string[:value-counter], counter)
with open('./hm_uncomp', 'a') as file: with open('./hm_uncomp', 'a') as file:
file.write(huff_string[:value-counter]) file.write(huff_string[:value-counter])
huff_string = huff_string[value-counter:] huff_string = huff_string[value-counter:]
......
No preview for this file type
No preview for this file type
...@@ -130,3 +130,695 @@ Seksjon 1 Tekstsøk ...@@ -130,3 +130,695 @@ Seksjon 1 Tekstsøk
• I praksis en tabell for hele alfabetet, hvor de fleste tegn • I praksis en tabell for hele alfabetet, hvor de fleste tegn
gir et flytt på m. (Regel om «upassende tegn») gir et flytt på m. (Regel om «upassende tegn»)
• Tabellen lager vi ved å pre-prosessere søketeksten
• Tegn som fins i søketeksten, gir kortere flytt
– En «s» i siste posisjon gir flytt på m-1, fordi ordet
starter på «s»
• \Omega\left(n/m\right) for søket. Mye bedre!
• Hvis tegnet ikke fins i søketeksten, kan vi flytte m steg
frem,
– hvis mismatch var på siste tegn i søketeksten
– med mismatch på nestsiste tegn kan vi flytte m-1 steg
– ved mismatch på nestnestsiste, flytter vi m-2 steg osv.
| m | e | t | e | o | r | i | t | t | s | t | e | i | n
-----+----+----+----+----+----+----+----+----+----+----+----+----+----+----
0 | m | e | n | e | | | | | | | | | |
1 | | | | m | e | n | e | | | | | | |
• Vi trenger altså en todimensjonal tabell:
– En indeks er det upassende tegnet
– Den andre indeksen er posisjonen i søketeksten
– Verdien i cellen er hvor langt vi kan flytte fremover
For hver posisjon p i søketeksten
For hvert tegn x i alfabetet
let mot start i søketeksten fra p
hvis vi finner x etter i steg,
sett Tab[p][x] = i
hvis vi ikke finner x, Tab[p][x]=p+1
| r | e | n | n | e | n | e |
-----+----+----+----+----+----+----+----+---
0 | e | n | e | | | | |
1 | | e | n | e | | | |
2 | | | e | n | e | | |
| | | | | e | n | e |
• 0,1: Når siste posisjon treffer «n», kan vi bare flytte ett
steg
• 2: Feil i første posisjon
– Regel om «upassende tegn» lar oss bare flytte ett hakk
• Regel om «passende endelse» lar oss flytte to hakk her
• «ne» passet, og «ene» overlapper med seg selv
• Vi slår opp både «upassende tegn» og passende endelse», og
bruker regelen som gir det lengste hoppet.
• Tabellen for «passende endelse»
– index er hvor mange tegn som passet
– verdien i cellen er hvor langt vi kan flytte
• Lages ved å prøve ut om søketeksten overlapper med seg selv
– ofte gjør den ikke det, og vi får lange hopp!
• Hvis vi søker etter «aaa» i «aaaaaa…», har vi dessverre O\left(n\cdot m\right)
– søkeordet passer overalt, de samme a-ene sjekkes flere
ganger
• Galil fant en måte å unngå unødvendige sammenligninger:
– Når vi flytter søkeordet kortere enn den delen av søkeordet
vi allerede har sjekket, trenger vi ikke sjekke det
overlappende området omigjen.
– Korte flytt skjer fordi søkeordet delvis matcher seg selv.
Hvis det ikke hadde passet, hadde vi flyttet lenger.
Teksten | . | . | . | O | l | a | l | a | . | . | . |
Mismatch O/a | | | l | a | l | a | l | a | | | |
Nytt forsøk | | | | | l | a | l | a | l | a | |
• Programmet trenger ikke sjekke den oransje regionen omigjen
• Dermed: O\left(n\right) og \Omega\left(n/m\right) for
tekstsøk
• Boyer og Moore sin artikkel:
http://www.cs.utexas.edu/~moore/publications/fstrpos.pdf
• Wikipedia:
https://en.wikipedia.org/wiki/Boyer_moore_string_search_algorithm
• Animasjon (Fyll ut, og velg Boyer-Moore) Trenger java
http://www.cs.pitt.edu/~kirk/cs1501/animations/String.html
• Demonstrasjon på Moore sin nettside:
http://www.cs.utexas.edu/users/moore/best-ideas/string-searching/fstrpos-example.html
Seksjon 2 Mer om datakompresjon
• Enkleste form for datakompresjon
• En serie repetisjoner erstattes med et antall:
– ABIIIIIIIIIIIIBBBCDEFFFGH \rightarrow AB12I3BCDE3FGH
• I praksis litt mer komplisert
– det kan jo være sifre i det vi komprimerer
– ser vanligvis på «bytes», ikke «tekst»
– må kunne skille mellom data og metadata
• Eks., bruker negativ byte for ukomprimerte sekvenser:
– ABIIIIIIIIIIIIBBBCDEFFFGH \rightarrow
[-2]AB[12]I[3]B[-3]CDE[3]F[-2]GH
– 25 byte ble redusert til 16
• Kan ikke komprimere ABABABABABAB…
• Leser gjennom fila
• Input kopieres til output
• Hvis en lang nok sekvens kommer omigjen:
– dropp den, skriv heller en referanse til output
– format: repeter X tegn, som vi har sett Y tegn tidligere
• Hjelper hvis sekvensen er lenger enn en slik referanse
• Søker bakover i et sirkulært buffer
• Output kan komprimeres videre med Huffman-koding
• Må være kompakt
– ellers kan vi ikke referere til korte strenger
– f.eks. 2–3 byte
• Å «se» langt bakover i datastrømmen, gir større sjanse for å
finne repetisjoner.
– men også lenger kjøretid
– påvirker formatet på referansene våre
∗ 1 byte kan peke 255 tegn bakover
∗ 2 byte kan peke 65 536 tegn bakover
∗ 3 byte kan peke 16 777 215 tegn bakover
• I blant kan vi ikke komprimere
– Må derfor også ha en måte å si:
– Her kommer X bytes ukomprimerte data
– Slik informasjon tar også plass!
• Vurdering:
– Skal dette være en del av en større ukomprimert blokk?
– Evt. bakover-ref + header for kortere ukomprimert blokk
• Det vi komprimerer må altså være lenger enn samlet lengde
for:
– en bakover-referanse
– header for en ukomprimert blokk
• Vi komprimerer ikke svært korte strenger, det hjelper ikke!
• Eksempeltekst:
Problemer, problemer. Alltid problemer!
Dette er dagens problem. Problemet er
å komprimere problematisk tekst.
• Eksempeltekst med avstander:
Problemer,^{10} problemer^{20}. Alltid p^{30}roblemer!
^{40}Dette er d^{50}agens prob^{60}lem. Probl^{70}emet er
å ^{80}komprimere^{90} problemat^{100}isk tekst.^{110}
• 110 tegn, inkludert linjeskift og blanke.
• Eksempeltekst med avstander:
Problemer,^{10} problemer^{20}. Alltid p^{30}roblemer!
^{40}Dette er d^{50}agens prob^{60}lem. Probl^{70}emet er
å ^{80}komprimere^{90} problemat^{100}isk tekst.^{110}
• Komprimert:
[12]Problemer, p[-11,8][8]. Alltid[-18,10][17]!
Dette er dagens[-27,7][2]. [-65,8][17]t er
å komprimere[-35,8][12]atisk tekst.
• Før komprimering, 110 tegn.
• Med 1 byte per tallkode, 84 tegn.
Vi sparte 110-84=26 tegn, eller 23%
• se også Lz-demo
• For hver tegnposisjon i input, må vi søke etter lengste match
i bufferet.
• Fil med n tegn, sirkulært buffer med størrelse m.
• Teste alle posisjoner, i verste fall O\left(nm^{2}\right)
• I praksis går det bedre, særlig hvis data varierer en del
• Kan bruke Boyer-Moore tekstsøk for bedre kjøretid.
• Lempel og Ziv sin artikkel:
http://www.cs.duke.edu/courses/spring03/cps296.5/papers/ziv_lempel_1977_universal_algorithm.pdf
• Wikipedia:
https://en.wikipedia.org/wiki/Lempel\%E2\%80\%93Ziv
• LZ leser input, og skriver
– bakover-referanser
– sekvenser med ukomprimerte tegn
• ukomprimerte tegn telles opp, og komprimeres videre med
Huffmannkoding
• Ligner LZ. Teoretisk samme kompresjon. Lettere å speede opp.
• Leser ett og ett tegn
• Bygger en ordliste (dictionary) underveis
– til å begynne med, alle 1-byte «ord»
• Finn et (lengst mulig) ord, skriv ordnummeret (med færrest
mulig bits!)
– lagre nytt «ord» = dette ordet + neste tegn
• Kompresjon hvis ordene blir lengre enn numrene
• LZW+Huffman \rightarrowDeflate (brukt i zip)
• Se eksempel «lzw»
• LZW
– leser input,
– bygger en dictionary,
– skriver «ordnumre»
• Noen «ord» forekommer oftere enn andre
• Programmet finner antall (frekvenser) for ulike ordnumre,
– skriver Huffmankoder i stedet for ordnumre
– ord som forekommer ofte, får kortere koder
• Komprimerer mer enn LZ-algoritmene
1. run-length coding
2. Burrows-Wheeler transformasjon (hoveddel)
3. Move-To-Front transformasjon (MFT)
4. run-length coding igjen
5. Huffmannkoding
• Hoveddelen av BZ2 (blokksorteringen)
• Dette steget komprimerer ikke selv, men transformerer en
blokk (typisk 900kB)
• Transformerer repeterte sekvenser (som ord) til repeterte
tegn
• Repeterte tegn er lettere å komprimere videre!
• Transformasjonen er reversibel (for dekomprimering)
• BWT på ordet «refererer●». Tegnet «●» markerer slutten
Rotasjoner Sortert
----------------------------
refererer• efererer•r
•refererer ererer•ref
r•referere erer•refer
er•referer er•referer
rer•refere fererer•re
erer•refer refererer•
rerer•refe rerer•refe
ererer•ref rer•refere
fererer•re r•referere
efererer•r •refererer
• BWT er siste kolonne med tegn fra sortert liste, «rfrre•eeer»
• Nå har vi mange like tegn ved siden av hverandre,
– lettere å komprimere med run-length coding
– Se også bw brukt på diverse filer
• Hvordan gå fra «rfrre•eeer» til «referere•»?
• Vet at «rfrre•eeer» er siste kolonne i sortert liste
• Lista bestod av ulike rotasjoner av samme ord
– alle kolonner inneholder de samme tegnene
• Lista var sortert
– første kolonne må altså ha de samme tegnene, sortert
– altså «eeeefrrrr•»
• Vi har nå to kolonner, i ei liste over rotasjoner
– kan rotere sidelengs, så siste kolonne blir første, og
første blir andre
– dette er fortsatt en del av løsningen
– sorterer vi dette, har vi de to første kolonnene
– så kan vi legge på siste kolonne igjen
– vi har nå tre kolonner. Repeter til vi har alle!
• Riktig rad er den som har «•» på siste plass
• Hvordan gå fra «rfrre•eeer» til «referere•»?
• Legg til sisteRotere mot høyreSortere
re ef fe er re er re er r•r
fe er re er re er r• •r ref
re er re er r• •r re ef fer
re er r• •r re ef fe er rer
ef fe er re er re er r• •re
•r re ef fe er re er re er• \Longleftarrow Der
er re er re er r• •r re efe
er re er r• •r re ef fe ere
er r• •r re ef fe er re ere
r• •r re ef fe er re er rer
• Komprimerer ikke data, men forbereder
• Initialiserer en tabell med alle byte-verdier. t[0]=0,
t[1]=1, t[2]=2, …
• Leser ett og ett tegn fra input
– finn tegnet i tabellen, skriv index til output
– flytt tegnet vi fant til første plass i tabellen (move to
front)
• input: caaaaacbbbbbabababab
inn:caaaaacbbbbbabababab
ut:21000012000021111111
tabell
0: aca....cb....abababab
1: bac....ac....babababa
2: cbb....ba....c.......
3: ddd....dd....d.......
• Alle repeterte tegn blir til nuller
• Korte repeterende sekvenser blir små tall
• Lett å gå andre veien ved utpakking
• Eksempel
inn:caaaaacbbbbbbbaaaabb
ut:21000012000000200010
Frekv. før | | Frekv. etter
------------------+--+--------------------
a 9 | | 0 14
b 9 | | 1 3
c 2 | | 2 3
• Før: like mange «a» som «b»
• Etter: overvekt av «0», som kan få kortere kode.
• Burrows-Wheeler sorterer så vi får mange repetisjoner
– 900 kB blokkstørrelse
• Move-to-front gjør ulike repetisjoner om til nuller
• Deretter fungerer run-length coding veldig bra!
• Huffmannkoding av det som blir igjen
• Huffmankoding av ei fil, bruker samme koding for hele fila
• Ei fil kan bestå av ulike deler (f.eks. norsk+engelsk)
– Ulike deler har ulik bokstavfordeling
– De komprimeres best med ulike Huffman-trær
• Noen forskere mener datakompresjon og AI er samme problem
– AI: det korteste programmet som oppfører seg intelligent
• Å oppdage repeterte mønstre (kan nyttes for kompresjon)
krever intelligens
• Mer intelligens gir bedre kompresjon
• Desimalene i \pi er et vanskelig datasett å komprimere. (mye
variasjon) Men:
– vi kjenner rekkeutviklinger som genererer \pi.
– Et program med endelig lengde, kan generere hele rekka. \infty
kompresjon!
• Ei zipfil er vanskelig å komprimere, selv om det fins bedre
kompresjon enn zip
– Hvis vi pakker ut zipfila, kan vi komprimere bedre med bz2
– Å oppdage at noe er zip-komprimert, og dermed kan behandles
slik, krever intelligens…
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a tortor nec odio vehicula porttitor et sed quam. Phasellus finibus dolor a sodales fringilla. Quisque egestas sapien eget tellus tincidunt pretium. Aenean quis mauris eu mi accumsan tincidunt. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Ut vel elit in urna placerat viverra mollis ut felis. Donec a maximus elit, ut fringilla neque. Sed a laoreet dui. Integer mauris est, imperdiet in enim ac, condimentum elementum erat. Curabitur massa turpis, rhoncus vitae felis elementum, vestibulum porttitor neque. Tekstsøk, Datakompresjon
Donec dapibus pretium nisi ac consequat. Mauris fermentum feugiat laoreet. Donec in sem non nisl hendrerit tristique. Phasellus tempor tellus sit amet tortor elementum molestie. Proin in ex diam. Aliquam molestie, quam et semper mollis, nibh nibh vehicula tortor, at faucibus metus ante sed sapien. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nullam vehicula, lacus sit amet pretium dignissim, tortor odio maximus sem, ut efficitur eros eros quis erat. Sed semper finibus ex sit amet dignissim. Vestibulum at ante eu purus ullamcorper hendrerit id mattis risus. Vestibulum nulla nisi, fermentum eget faucibus eu, elementum nec est. Nunc finibus fermentum semper. Helge Hafting
\ No newline at end of file
Institutt for datateknologi og informatikk
Seksjon 1 Tekstsøk
• Fritekstsøk i dokumenter, nettsider og lignende
• Fritekstsøk i databaser
• Søkemotorer
• Søke etter repeterte strenger for datakompresjon
• DNA-matching
Tekst: rabarbra (lengde n)
Søkeord: bra (lengde m)
Skyv søkeordet langs teksten, se om det passer
• tegn som passer, vises med fet skrift
• første feil med kursiv
• dobbeltløkke for n-m posisjoner, og m tegn i søkeordet.
Hele greia, O\left(n\cdot m\right),\Omega\left(n\right)
Forsøk | r | a | b | a | r | b | r | a
----------+----+----+----+----+----+----+----+----
0 | b | r | a | | | | |
Forsøk | r | a | b | a | r | b | r | a
----------+----+----+----+----+----+----+----+----
1 | | b | r | a | | | |
Forsøk | r | a | b | a | r | b | r | a
----------+----+----+----+----+----+----+----+----
2 | | | b | r | a | | |
Forsøk | r | a | b | a | r | b | r | a
----------+----+----+----+----+----+----+----+----
3 | | | | b | r | a | |
Forsøk | r | a | b | a | r | b | r | a
----------+----+----+----+----+----+----+----+----
4 | | | | | b | r | a |
Forsøk | r | a | b | a | r | b | r | a
----------+----+----+----+----+----+----+----+----
5 | | | | | | b | r | a
Forsøk | r | a | b | a | r | b | r | a
----------+----+----+----+----+----+----+----+----
0 | b | r | a | | | | |
1 | | b | r | a | | | |
2 | | | b | r | a | | |
3 | | | | b | r | a | |
4 | | | | | b | r | a |
5 | | | | | | b | r | a
• Se på siste tegn i søketeksten først
• Hvis det ikke passer, flytt søketeksten så langt vi kan
| r | a | b | a | r | b | r | a
-----+----+----+----+----+----+----+----+----
0 | b | r | a | | | | |
1 | | | b | r | a | | |
2 | | | | b | r | a | |
3 | | | | | | b | r | a
• Hvis det passer, se på nestsiste osv.
• Hvis tegnet ikke fins i søketeksten, kan vi flytte m steg
frem:
| m | e | t | e | o | r | i | t | t | s | t | e | i | n
-----+----+----+----+----+----+----+----+----+----+----+----+----+----+----
0 | s | t | e | i | n | | | | | | | | |
1 | | | | | | s | t | e | i | n | | | |
2 | | | | | | | | | | s | t | e | i | n
• Hvis tegnet fins til venstre i søkeordet, kan vi flytte ordet
så det passer med teksten
• Vi har vi en tabell for hvor mye vi kan flytte
• I praksis en tabell for hele alfabetet, hvor de fleste tegn
gir et flytt på m. (Regel om «upassende tegn»)
• Tabellen lager vi ved å pre-prosessere søketeksten
• Tegn som fins i søketeksten, gir kortere flytt
– En «s» i siste posisjon gir flytt på m-1, fordi ordet
starter på «s»
• \Omega\left(n/m\right) for søket. Mye bedre!
• Hvis tegnet ikke fins i søketeksten, kan vi flytte m steg
frem,
– hvis mismatch var på siste tegn i søketeksten
– med mismatch på nestsiste tegn kan vi flytte m-1 steg
– ved mismatch på nestnestsiste, flytter vi m-2 steg osv.
| m | e | t | e | o | r | i | t | t | s | t | e | i | n
-----+----+----+----+----+----+----+----+----+----+----+----+----+----+----
0 | m | e | n | e | | | | | | | | | |
1 | | | | m | e | n | e | | | | | | |
• Vi trenger altså en todimensjonal tabell:
– En indeks er det upassende tegnet
– Den andre indeksen er posisjonen i søketeksten
– Verdien i cellen er hvor langt vi kan flytte fremover
For hver posisjon p i søketeksten
For hvert tegn x i alfabetet
let mot start i søketeksten fra p
hvis vi finner x etter i steg,
sett Tab[p][x] = i
hvis vi ikke finner x, Tab[p][x]=p+1
| r | e | n | n | e | n | e |
-----+----+----+----+----+----+----+----+---
0 | e | n | e | | | | |
1 | | e | n | e | | | |
2 | | | e | n | e | | |
| | | | | e | n | e |
• 0,1: Når siste posisjon treffer «n», kan vi bare flytte ett
steg
• 2: Feil i første posisjon
– Regel om «upassende tegn» lar oss bare flytte ett hakk
• Regel om «passende endelse» lar oss flytte to hakk her
• «ne» passet, og «ene» overlapper med seg selv
• Vi slår opp både «upassende tegn» og passende endelse», og
bruker regelen som gir det lengste hoppet.
• Tabellen for «passende endelse»
– index er hvor mange tegn som passet
– verdien i cellen er hvor langt vi kan flytte
• Lages ved å prøve ut om søketeksten overlapper med seg selv
– ofte gjør den ikke det, og vi får lange hopp!
• Hvis vi søker etter «aaa» i «aaaaaa…», har vi dessverre O\left(n\cdot m\right)
– søkeordet passer overalt, de samme a-ene sjekkes flere
ganger
• Galil fant en måte å unngå unødvendige sammenligninger:
– Når vi flytter søkeordet kortere enn den delen av søkeordet
vi allerede har sjekket, trenger vi ikke sjekke det
overlappende området omigjen.
– Korte flytt skjer fordi søkeordet delvis matcher seg selv.
Hvis det ikke hadde passet, hadde vi flyttet lenger.
Teksten | . | . | . | O | l | a | l | a | . | . | . |
Mismatch O/a | | | l | a | l | a | l | a | | | |
Nytt forsøk | | | | | l | a | l | a | l | a | |
• Programmet trenger ikke sjekke den oransje regionen omigjen
• Dermed: O\left(n\right) og \Omega\left(n/m\right) for
tekstsøk
• Boyer og Moore sin artikkel:
http://www.cs.utexas.edu/~moore/publications/fstrpos.pdf
• Wikipedia:
https://en.wikipedia.org/wiki/Boyer_moore_string_search_algorithm
• Animasjon (Fyll ut, og velg Boyer-Moore) Trenger java
http://www.cs.pitt.edu/~kirk/cs1501/animations/String.html
• Demonstrasjon på Moore sin nettside:
http://www.cs.utexas.edu/users/moore/best-ideas/string-searching/fstrpos-example.html
Seksjon 2 Mer om datakompresjon
• Enkleste form for datakompresjon
• En serie repetisjoner erstattes med et antall:
– ABIIIIIIIIIIIIBBBCDEFFFGH \rightarrow AB12I3BCDE3FGH
• I praksis litt mer komplisert
– det kan jo være sifre i det vi komprimerer
– ser vanligvis på «bytes», ikke «tekst»
– må kunne skille mellom data og metadata
• Eks., bruker negativ byte for ukomprimerte sekvenser:
– ABIIIIIIIIIIIIBBBCDEFFFGH \rightarrow
[-2]AB[12]I[3]B[-3]CDE[3]F[-2]GH
– 25 byte ble redusert til 16
• Kan ikke komprimere ABABABABABAB…
• Leser gjennom fila
• Input kopieres til output
• Hvis en lang nok sekvens kommer omigjen:
– dropp den, skriv heller en referanse til output
– format: repeter X tegn, som vi har sett Y tegn tidligere
• Hjelper hvis sekvensen er lenger enn en slik referanse
• Søker bakover i et sirkulært buffer
• Output kan komprimeres videre med Huffman-koding
• Må være kompakt
– ellers kan vi ikke referere til korte strenger
– f.eks. 2–3 byte
• Å «se» langt bakover i datastrømmen, gir større sjanse for å
finne repetisjoner.
– men også lenger kjøretid
– påvirker formatet på referansene våre
∗ 1 byte kan peke 255 tegn bakover
∗ 2 byte kan peke 65 536 tegn bakover
∗ 3 byte kan peke 16 777 215 tegn bakover
• I blant kan vi ikke komprimere
– Må derfor også ha en måte å si:
– Her kommer X bytes ukomprimerte data
– Slik informasjon tar også plass!
• Vurdering:
– Skal dette være en del av en større ukomprimert blokk?
– Evt. bakover-ref + header for kortere ukomprimert blokk
• Det vi komprimerer må altså være lenger enn samlet lengde
for:
– en bakover-referanse
– header for en ukomprimert blokk
• Vi komprimerer ikke svært korte strenger, det hjelper ikke!
• Eksempeltekst:
Problemer, problemer. Alltid problemer!
Dette er dagens problem. Problemet er
å komprimere problematisk tekst.
• Eksempeltekst med avstander:
Problemer,^{10} problemer^{20}. Alltid p^{30}roblemer!
^{40}Dette er d^{50}agens prob^{60}lem. Probl^{70}emet er
å ^{80}komprimere^{90} problemat^{100}isk tekst.^{110}
• 110 tegn, inkludert linjeskift og blanke.
• Eksempeltekst med avstander:
Problemer,^{10} problemer^{20}. Alltid p^{30}roblemer!
^{40}Dette er d^{50}agens prob^{60}lem. Probl^{70}emet er
å ^{80}komprimere^{90} problemat^{100}isk tekst.^{110}
• Komprimert:
[12]Problemer, p[-11,8][8]. Alltid[-18,10][17]!
Dette er dagens[-27,7][2]. [-65,8][17]t er
å komprimere[-35,8][12]atisk tekst.
• Før komprimering, 110 tegn.
• Med 1 byte per tallkode, 84 tegn.
Vi sparte 110-84=26 tegn, eller 23%
• se også Lz-demo
• For hver tegnposisjon i input, må vi søke etter lengste match
i bufferet.
• Fil med n tegn, sirkulært buffer med størrelse m.
• Teste alle posisjoner, i verste fall O\left(nm^{2}\right)
• I praksis går det bedre, særlig hvis data varierer en del
• Kan bruke Boyer-Moore tekstsøk for bedre kjøretid.
• Lempel og Ziv sin artikkel:
http://www.cs.duke.edu/courses/spring03/cps296.5/papers/ziv_lempel_1977_universal_algorithm.pdf
• Wikipedia:
https://en.wikipedia.org/wiki/Lempel\%E2\%80\%93Ziv
• LZ leser input, og skriver
– bakover-referanser
– sekvenser med ukomprimerte tegn
• ukomprimerte tegn telles opp, og komprimeres videre med
Huffmannkoding
• Ligner LZ. Teoretisk samme kompresjon. Lettere å speede opp.
• Leser ett og ett tegn
• Bygger en ordliste (dictionary) underveis
– til å begynne med, alle 1-byte «ord»
• Finn et (lengst mulig) ord, skriv ordnummeret (med færrest
mulig bits!)
– lagre nytt «ord» = dette ordet + neste tegn
• Kompresjon hvis ordene blir lengre enn numrene
• LZW+Huffman \rightarrowDeflate (brukt i zip)
• Se eksempel «lzw»
• LZW
– leser input,
– bygger en dictionary,
– skriver «ordnumre»
• Noen «ord» forekommer oftere enn andre
• Programmet finner antall (frekvenser) for ulike ordnumre,
– skriver Huffmankoder i stedet for ordnumre
– ord som forekommer ofte, får kortere koder
• Komprimerer mer enn LZ-algoritmene
1. run-length coding
2. Burrows-Wheeler transformasjon (hoveddel)
3. Move-To-Front transformasjon (MFT)
4. run-length coding igjen
5. Huffmannkoding
• Hoveddelen av BZ2 (blokksorteringen)
• Dette steget komprimerer ikke selv, men transformerer en
blokk (typisk 900kB)
• Transformerer repeterte sekvenser (som ord) til repeterte
tegn
• Repeterte tegn er lettere å komprimere videre!
• Transformasjonen er reversibel (for dekomprimering)
• BWT på ordet «refererer●». Tegnet «●» markerer slutten
Rotasjoner Sortert
----------------------------
refererer• efererer•r
•refererer ererer•ref
r•referere erer•refer
er•referer er•referer
rer•refere fererer•re
erer•refer refererer•
rerer•refe rerer•refe
ererer•ref rer•refere
fererer•re r•referere
efererer•r •refererer
• BWT er siste kolonne med tegn fra sortert liste, «rfrre•eeer»
• Nå har vi mange like tegn ved siden av hverandre,
– lettere å komprimere med run-length coding
– Se også bw brukt på diverse filer
• Hvordan gå fra «rfrre•eeer» til «referere•»?
• Vet at «rfrre•eeer» er siste kolonne i sortert liste
• Lista bestod av ulike rotasjoner av samme ord
– alle kolonner inneholder de samme tegnene
• Lista var sortert
– første kolonne må altså ha de samme tegnene, sortert
– altså «eeeefrrrr•»
• Vi har nå to kolonner, i ei liste over rotasjoner
– kan rotere sidelengs, så siste kolonne blir første, og
første blir andre
– dette er fortsatt en del av løsningen
– sorterer vi dette, har vi de to første kolonnene
– så kan vi legge på siste kolonne igjen
– vi har nå tre kolonner. Repeter til vi har alle!
• Riktig rad er den som har «•» på siste plass
• Hvordan gå fra «rfrre•eeer» til «referere•»?
• Legg til sisteRotere mot høyreSortere
re ef fe er re er re er r•r
fe er re er re er r• •r ref
re er re er r• •r re ef fer
re er r• •r re ef fe er rer
ef fe er re er re er r• •re
•r re ef fe er re er re er• \Longleftarrow Der
er re er re er r• •r re efe
er re er r• •r re ef fe ere
er r• •r re ef fe er re ere
r• •r re ef fe er re er rer
• Komprimerer ikke data, men forbereder
• Initialiserer en tabell med alle byte-verdier. t[0]=0,
t[1]=1, t[2]=2, …
• Leser ett og ett tegn fra input
– finn tegnet i tabellen, skriv index til output
– flytt tegnet vi fant til første plass i tabellen (move to
front)
• input: caaaaacbbbbbabababab
inn:caaaaacbbbbbabababab
ut:21000012000021111111
tabell
0: aca....cb....abababab
1: bac....ac....babababa
2: cbb....ba....c.......
3: ddd....dd....d.......
• Alle repeterte tegn blir til nuller
• Korte repeterende sekvenser blir små tall
• Lett å gå andre veien ved utpakking
• Eksempel
inn:caaaaacbbbbbbbaaaabb
ut:21000012000000200010
Frekv. før | | Frekv. etter
------------------+--+--------------------
a 9 | | 0 14
b 9 | | 1 3
c 2 | | 2 3
• Før: like mange «a» som «b»
• Etter: overvekt av «0», som kan få kortere kode.
• Burrows-Wheeler sorterer så vi får mange repetisjoner
– 900 kB blokkstørrelse
• Move-to-front gjør ulike repetisjoner om til nuller
• Deretter fungerer run-length coding veldig bra!
• Huffmannkoding av det som blir igjen
• Huffmankoding av ei fil, bruker samme koding for hele fila
• Ei fil kan bestå av ulike deler (f.eks. norsk+engelsk)
– Ulike deler har ulik bokstavfordeling
– De komprimeres best med ulike Huffman-trær
• Noen forskere mener datakompresjon og AI er samme problem
– AI: det korteste programmet som oppfører seg intelligent
• Å oppdage repeterte mønstre (kan nyttes for kompresjon)
krever intelligens
• Mer intelligens gir bedre kompresjon
• Desimalene i \pi er et vanskelig datasett å komprimere. (mye
variasjon) Men:
– vi kjenner rekkeutviklinger som genererer \pi.
– Et program med endelig lengde, kan generere hele rekka. \infty
kompresjon!
• Ei zipfil er vanskelig å komprimere, selv om det fins bedre
kompresjon enn zip
– Hvis vi pakker ut zipfila, kan vi komprimere bedre med bz2
– Å oppdage at noe er zip-komprimert, og dermed kan behandles
slik, krever intelligens…
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment