Avainsanat ja sanonnat: Tiedonpakkaus, algoritmit, Huffmanin koodaus, aritmeettinen koodaus, sanakirjat, informaatioteoria. CR luokat: E.

Koko: px
Aloita esitys sivulta:

Download "Avainsanat ja sanonnat: Tiedonpakkaus, algoritmit, Huffmanin koodaus, aritmeettinen koodaus, sanakirjat, informaatioteoria. CR luokat: E."

Transkriptio

1 Häviöttömät tiedonpakkausalgoritmit Jukka Pollari Tiivistelmä. Tässä tutkielmassa käsitellään häviöttömiä pakkausalgoritmeja, tarkemmin määriteltynä sellaisia, joilla voidaan pakata kaikenlaista dataa. Työssä tutkitaan sitä, mihin algoritmien pakkaustehot perustuvat ja selvitetään pakkausalgoritmeista niiden historia sekä algoritmien toiminta. Tutkielman tarkoituksena on antaa selkeä kuva algoritmien rakenteesta ja siitä miksi ne pakkaavat dataa sekä antaa kuva siitä, millaisten rajojen sisällä yleensä ottaen tietoa voidaan pakata. Avainsanat ja sanonnat: Tiedonpakkaus, algoritmit, Huffmanin koodaus, aritmeettinen koodaus, sanakirjat, informaatioteoria. CR luokat: E.4 1. Johdanto Tiedonpakkaus on muodostumassa yhä tärkeämmäksi osaksi yhteiskuntaa bittimuotoisen tiedon määrän kasvaessa huimaa vauhtia. Tietoa pakataan monin eri tavoin arkipäivässä, sekä tietokoneiden maailmassa että kodin sähkölaitteissa. Vaikka tiedonpakkaus ei ole kovin näkyvä osa maailmaa, on se ollut suuressa roolissa monissa teknisissä innovaatioissa, esimerkiksi internetin tiedonsiirtomekanismien suunnittelussa. Ilman tiedonpakkausta tiedonsiirtokapasiteettien täytyisi olla huomattavasti suurempia nykyisiin verrattuna. Tämän teoksen tutkimusongelmana on häviöttömien pakkausalgoritmien historian selvittäminen sekä yksittäisten algoritmien toiminta. Tutkimuksessa selvitetään mitä algoritmeja käytetään laajalti ja pohditaan syitä algoritmien yleistymiseen. Tutkimusalueen rajaamiseksi teoksessa keskitytään esittelemään vain sellaisia häviöttömiä algoritmeja, joilla voidaan pakata kaikenlaista dataa. Tutkimuksessa ei siis käsitellä sellaisia häviöttömiä pakkausalgoritmeja, joilla voidaan pakata vain esimerkiksi ääntä, kuvaa tai videokuvaa. Tutkimuksen aluetta rajataan myös niin, että siinä ei perehdytä matemaattiseen teoriaan kovin laajasti, mutta käydään tiiviisti läpi informaatioteoria ensimmäisessä kappaleessa. Lähdin ratkaisemaan tutkimusongelmaa kirjallisuuskartoituksen avulla. Halusin mahdollisimman tuoreen näkemyksen algoritmeihin, joten päätin etsiä eri tietokannoista mahdollisimman tuoreita aihetta käsitteleviä teoksia. Yksittäisiä algoritmeja ja niiden soveltamista erilaisissa tilanteissa löytyi

2 2 tietokannasta runsaasti, mutta pohjatietoa käsitteleviä teoksia oli niukalti. Tietokannasta löytyi kuitenkin kuitenkin Sayoodin tuore kirja Introduction to Data Compression (Third Edition) vuodelta Tämä teos oli tärkein lähde tutkimuksessa, koska siinä käsiteltiin tuoreimpia algoritmeja. Toinen tutkimuksessa käyttämäni teos on Nelson ja Gaillyn The Data Compression Book 2nd edition vuodelta Nelson ja Gaillyn kirja ei käsittele algoritmeja niin matemaattisesti kuin Sayoodin kirja, joten se on ideaalinen omaan tarkoitukseeni. Kolmas käyttämäni pääteos oli Lelewer ja Hirschbergin yleisteos Data compression vuodelta Pääteosten lisäksi tietokannoista sekä www:stä löytyi algoritmien kehittäjien omia teoksia, joissa he itse käyvät läpi algoritmien toimintaa. Tutkimuksen ensimmäisessä kappaleessa esitellään informaatioteoria ja seuraavissa esitellään siihen perustuvista algoritmeista Huffmanin staattinen ja mukautuva algoritmi sekä aritmeettinen koodaus ja sitä kautta siirrytään Lempelin ja Zivin alkujaan kehittämiin sanakirja algoritmeihin. 2. Informaatioteoria Nykyaikaisen tiedonpakkauksen juuret ovat 1940 luvun lopulla, jolloin Bell Labsin Claude Shannon kehitti informaatioteorian. Informaatioteoriassa tutkitaan redundanssia, entropiaa ja tilastollista informaatiosisältöä. Redundanssilla eli toistolla viitataan siihen tietoon, joka on käytännössä turhaa ja jonka poistamalla voidaan tietoa pakata tiiviimpään tilaan. Entropia taas on se mitta, jolla lasketaan kuinka paljon informaatiota viesti sisältää [Sayood, 2006; Nelson ja Gailly, 1995; Lelewer ja Hirschberg, 1987]. Näitä informaatioteorian matemaattisia teorioita voidaan soveltaa myös binäärimuotoiseen tietoon. Shannon kehitti teoriassaan suureen, jota hän kutsui itseinformaatioksi (self information). Määritellään A tapahtumaksi, joka on jonkin satunnaisen tapahtuman tulos. Tällöin itseinformaatiolla I(A) tarkoitetaan sitä entropista informaation määrää, minkä luku A sisältää [Sayood, 2006]. Shannon määritteli, että jos P(A) on todennäköisyys sille, että tapahtuma A tapahtuu, niin A:n sisältämä itseinformaatio I(A) voidaan laskea kaavasta 1 I( A) = logb = loga P( A). (1) P( A) Kaavassa (1) kantaluku a kertoo informaation yksikön. Se voi olla mikä tahansa luku a > 1. Tyypillisiä esimerkkejä on 2 (bittiä), e (nattia) tai 10 (dittiä). 2

3 3 Jos siis halutaan laskea informaation sisältöä bitteinä, sijoitetaan kantaluvuksi 2. Itseinformaatio bittityyppiselle yksikölle voidaan laskea kaavasta ln P( A) I ( A) = log2 P( A) = (2) ln 2 Määritellään esimerkiksi, että merkki a esiintyy todennäköisyydellä P(A) 1 = 4. Tällöin entropisten bittien määrä voidaan laskea kaavasta (2) seuraavasti: 1 ln 4 I(A)= ln 2 = 2 bittiä. Kirjaimen a informaatiosisältö on siis tässä tilanteessa 2 bittiä. Jokaisen merkin vaatima tila yleisellä Ascii koodauksella on 8 bittiä, joten pakkauksella olisi mahdollista säästää tässä tilanteessa 6 bittiä. Pakkausalgoritmeissa informaation sisällön entropiaa on kuitenkin käytännössä mahdotonta mitata, koska pakkausalgoritmin käyttämä malli (model) määrää merkkien todennäköisyydet. Tämä johtuu siitä, että mallin suuruusluokka (order) määrää sen montako edellistä merkkiä malli lukee [Nelson ja Gailly, 1995]. Esimerkiksi suurusluokan 0 malli lukee vain nykyisen merkin, suurusluokan 1 lukee yhden ja niin edelleen. Jos suuruusluokan 0 malli lukee esimerkiksi vain nykyisen kirjaimen, joka on a ja saa todennäköisyydeksi 1/70, suuruusluokan 1 malli voi lukea myös edellisen kirjaimen saaden näin tulokseksi esimerkiksi at jonka todennäköisyys voi olla 2/3. Todennäköisyydet vaihtuvat siis aina mallin muuttuessa. Jotta pakkaus olisi mahdollisimman tehokasta, on valittava malli joka osaa ennustaa ne symbolit, joita esiintyy usein ja tämän jälkeen pakattava nämä symbolit mahdollisimman pienillä bittimäärillä. 3. Todennäköisyyksiin perustuva staattinen mallinnus Informaatioteorian kehittämisen jälkeen tuli tarve etsiä tapoja, joilla saataisiin tietoa pakattua informaatioteorian antamien mahdollisuuksien mukaisesti pienempään tilaan. Ensimmäiset pakkausalgoritmit perustuivat staattisiin todennäköisyystaulukoihin, joita päivitettiin vain kerran algoritmin ajon aikana. Tällaisen mallin etu on, että se säästää tietokonetehoja [Nelson ja Gailly, 1995]. Yksinkertaisin tapa tällaisessa algoritmissa olisi esimerkiksi luoda taulukko, joka sisältää symbolit ja niiden todennäköisyyden. Pakkausohjelma pääsee käsiksi kyseiseen taulukkoon, jonka avulla se pakkaa ja purkaa tiedoston. Aineistoon perustuvan taulukon sijaan voidaan käyttää myös universaalia yleistä taulukkoa, jota ei ole räätälöity aineiston mukaan. On kuitenkin selvä, että tällaisen mallin ongelmana voi olla pakkaussuhde, koska 3

4 4 sisään tuleva tietovirta ei välttämättä vastaa taulukon symbolien esiintymistiheyksiä. Huonoimmassa tapauksessa universaalin taulukon tapauksessa pakattu tiedosto voi olla suurempi kuin alkuperäinen. Shannon Fanon koodaus oli ensimmäinen suosittu ja tehokas staattista mallia käyttävä pakkausalgoritmi. Algoritmi sai nimensä Bell Lapsin Claude Shannonin ja MIT:n R.M. Fanon mukaan, jotka kehittivät algoritmin lähes yhtäaikaisesti vuonna Algoritmia käytettiin tietokoneiden lisäksi aluksi myös muissa laitteissa, esimerkiksi kaukokirjoittimissa [Nelson ja Gailly, 1995; Lelewer ja Hirschberg, 1987]. Shannon Fanon algoritmi muodostaa järjestetyn frekvenssilistan avulla binääripuun, jossa jokaisella symbolilla on eri bittikoodi. Frekvenssilista jaetaan kahteen mahdollisimman yhtä suureen ryhmään. Tätä tehdään rekursiivisesti, kunnes kaikki frekvenssilistan osat olivat lehtisolmuja. Shannon Fano oli suuri harppaus eteenpäin pakkaustekniikoissa, mutta lyhytikäinen, sillä Huffmanin koodaus korvasi Shannon Fano pakkauksen tehokkaampana algoritmina [Nelson ja Gailly, 1995; Lelewer ja Hirschberg, 1987]. David Huffman julkaisi tutkimusraporttinsa A Method for the Construction of Minimum Redundancy Code vuonna Huffmanin algoritmi on myöhemmin kehittynyt yhdeksi maailman yleisimmistä pakkausmenetelmistä. Algoritmia käytetään useissa pakkausohjelmissa, kuten ZIP ja GZIP sekä kuvankäsittelymuodoista suositussa JPEG kuvanpakkauksessa. Sitä käytetään myös esimerkiksi monissa elektronisissa laitteissa kuten FAX laitteissa. Huffman ja Shannon Fano koodaukset ovat teholtaan melko samaa tasoa, mutta Huffman koodaus on aina vähintään yhtä tehokas kuin Shannon Fano [Nelson ja Gailly, 1995]. Tästä syystä Huffmanin koodausta käytetään Shannon Fanoa useammin. Yksi Shannon Fanon algoritmin ja Huffman algoritmin eroista on, että Huffman aloittaa datan läpikäymisen lopusta ja päätyy alkuun, kun taas Shannon Fano kulkee alusta loppuun Shannon Fano algoritmi Ennen Shannon Fano algoritmia luodaan kaikista symboleista lista, joka sisältää symbolin sekä sen luvun, montako kertaa symboli esiintyy aineistossa. Lista jaetaan joka kierroksella kahteen osaan niin, että molempien summa on mahdollisimman samanlainen: 1. Järjestetään frekvenssilista suuruusjärjestykseen niin, että ne symbolit joilla on suurin todennäköisyys, ovat alkupäässä ja ne joilla on pienin, ovat loppupäässä. 4

5 5 2. Jaetaan lista kahteen ryhmään niin, että vasemman ja oikean puoliskon yhteenlasketut todennäköisyydet ovat mahdollisimman lähellä toisiaan. 3. Lisätään kaikille vasemman puolen symboleille koodiluvuksi 0 ja oikean puolen symboleille Käydään rekursiivisesti läpi kaikki jaetut ryhmät jakaen ne kohdan 2 ja 3 mukaisesti ja lisäten niille koodiluvut. Tehdään tätä niin kauan, että jokainen ryhmä sisältää vain yhden symbolin. Algoritmi 1. Shannon-Fano algoritmi [Lelewer ja Hirschberg, 1987]. Kun lista on jaettu kahteen osaan, toisesta puoliskosta tulee binääripuun oikea lapsi ja toisesta vasen lapsi. Lopulta koko aineisto on jaettu yhdeksi binääripuuksi. Tämä binääripuu lisätään ensin pakattavan tiedoston alkuun purkamisen mahdollistamiseksi, jonka jälkeen pakataan aineisto bittimuotoisesti kyseisellä binääripuulla Huffman algoritmi Ennen Huffmanin algoritmia on luettava aineisto ja luotava frekvenssilista, joka sisältää jokaisen symbolin ja sen frekvenssin eli määrän, montako kertaa symboli esiintyy aineistossa. Frekvenssilistan pienimmät alkiot yhdistetään solmuksi, jonka juurena on summafrekvenssi. Tätä tehdään niin kauan, että lista on yksittäinen binääripuu: 1. Luodaan uusi binääripuusolmu. 2. Poistetaan kaksi listan pienintä alkiota frekvenssilistasta ja lisätään ne uuden binääripuusolmun oikeaksi ja vasemmaksi lapseksi. Vasemman lapsen bittikoodi on 0 ja oikean Asetetaan solmun juureksi vasemman ja oikean lapsen frekvenssien summa. 4. Lisätään binääripuusolmu listaan. 5. Tehdään niin kauan kohdasta 1 lähtien, kunnes lista sisältää vain yhden binääripuun. Algoritmi 2. Huffmanin algoritmi [Cormen, Leiserson, Rivest ja Stein, 2001; Nelson ja Gailly, 1995]. Kuten Shannon Fano algoritmissakin (1), Huffmanin algoritmin (2) suorittamisen jälkeen pakatun tiedoston alkuun lisätään ensiksi pakattu 5

6 6 Huffman puu ja sen jälkeen aineisto koodataan bittimuotoisesti binääripuun avulla Staattisten mallien analysointia Huffman koodauksen avulla saavutetaan minimimäärä redundanssia koodeilla, joiden bittikoko vaihtelee symbolien esiintymismäärän mukaan. Huffmanin koodaus ei ole optimaalinen, mutta se tarjoaa hyvän likiarvollisen tuloksen. Se miksi Huffman ei ole optimaalinen johtuu siitä, että sekä Huffman, että Shannon Fano koodauksissa symbolin esitykseen käytetty bittimäärä esitetään kokonaislukuna. Esimerkiksi Huffmanin koodauksessa bittimäärä pyöristetään lähimpään kokonaislukuun. Kummassakaan ei voida siis päästä tarkalleen informaatioteorian mukaiseen tulokseen. Huffmanin koodauksesta tuli kuitenkin suosittu, koska se oli helppo ottaa käyttöön ja sen pakkaussuhteet olivat hyviä [Nelson ja Gailly, 1995]. Sekä Huffmanin koodaus, että Shannon Fano koodaus käyttävät molemmat suuruusluokan 0 mallia, jossa keskitytään yksittäiseen symboliin eikä oteta huomioon sitä, millaisessa kokonaisuudessa symboli esiintyy. Tällaisessa tapauksessa saadaan aikaan pakkausta, jos kaikkia symboleita ei ole aineistossa tarkalleen samaa määrää. Suuruusluokan 0 Huffman kooditaulukko sisältää 256 bittiä, mutta suuremmilla suuruusluokilla todennäköisyystaulukon vaatima tila kasvaa kovaa vauhtia. Suuruusluokassa 1 se on jo bittiä. Tästä seuraa, että vaikka korkeampi suuruusluokka parantaa pakkauksen tehokkuutta, se kasvattaa todennäköisyystaulukon koon niin suureksi, että pakkauksen tuoma etu katoaa [Nelson ja Gailly, 1995]. Suuruusluokkaongelmaan on kuitenkin olemassa ratkaisu, jota käsitellään seuraavassa kappaleessa. 4. Mukautuva Huffman koodaus Huffman koodauksessa todennäköisyystaulukon täytyy olla aina pakatun aineiston mukana, joka muodostuu ongelmaksi, jos malli on suurempaa suuruusluokkaa kuin 0. Suuruusluokassa 0 tällä ei ole suurempaa merkitystä, koska taulukko vie enimmillään n. 250 tavua [Nelson ja Gailly, 1995]. Kuitenkin jo kun siirrytään suuruusluokan 1 malliin, annetaan yhden todennäköisyystaulukon sijaan 257 taulukkoa, joka kasvattaa pakatun aineiston kokoa merkittävästi. Jos pakattavat tiedostot eivät ole kovin suuria, tarkempien pakkaussuhteiden edut katoavatkin suuren todennäköisyystaulukon vuoksi. Tämä ongelma voidaan ratkaista niin, että ei käytetä staattista binääripuuta vaan päivitetään puuta sitä mukaa, kun pakattavaa aineistoa luetaan. Tällaisessa tapauksessa binääripuun luomiseen täytyy ottaa uudenlainen 6

7 7 lähestymistapa, koska puun luomiseen ei voida käyttää perinteistä Huffmanin algoritmia. Faller (1973) ja Gallagher (1978) loivat ensimmäiset mukautuvat Huffman algoritmit, joita myöhemmin päivittivät Knuth (1985) ja Vitter (1987) [Sayood, 2006]. Heidän algoritminsa perustuvat siihen, että Huffman puussa kaikilla solmuilla lukuun ottamatta juurisolmua on sisarsolmu. Pitämällä yllä tätä ominaisuutta voidaan varmistaa, että binääripuu pysyy Huffman puuna. Symbolit, joita ei vielä ole esitetty koodissa muodostavat ongelman mukautuvassa koodauksessa. Ratkaisu on käyttää EVV (ei vielä välitetty) solmua, joka sisältää käyttämättömien symbolien määrän. EVV solmu on aina, myös tyhjässä puussa, sisällytettynä puuhun painoarvolla 0. Mukautuvan Huffmanin algoritmin periaate on seuraavanlainen: 1. Jos nykyinen symboli on EVV, luodaan EVV solmulle kaksi lasta. Ensimmäiseksi lapseksi asetetaan uusi EVV - solmu ja toiseksi solmu, joka sisältää puuhun lisättävän symbolin. Siirrytään entiseen EVV - solmuun kohtaan ja siirrytään algoritmissa kohtaan Muussa tapauksessa siirrytään solmuun, joka sisältää kyseisen symbolin. 3. Tarkistetaan onko solmun painoarvo kyseisessä lohkossa suurin. 4. Jos solmun painoarvo ei ole suurin, vaihdetaan solmun ja lohkon suurimman paikkaa. 5. lisätään solmun painoarvoa yhdellä. 6. Tutkitaan, onko kyseessä juurisolmu. Jos ei, niin siirrytään kohtaan 3. Tehdään tätä niin kauan, että kyseessä on juurisolmu. Algoritmi 3. Algoritmi mukautuvan Huffman puun luomiselle ja päivitykselle [Sayood, 2006]. Algoritmin 3 ensimmäisessä vaiheessa tarkastetaan onko kyseessä EVV symboli ja jos on, luodaan EVV solmulle kaksi lasta ja asetetaan toiseksi lapseksi uusi EVV ja toiseksi kyseinen symboli. Päivitysoperaation tarkoitus on ylläpitää sisarsolmuperiaatetta, joten binääripuu on päivitettävä aina lisäyksen jälkeen. Tämän takia solmun luomisen jälkeen vaihdellaan binääripuun solmujen paikkaa, kunnes puu täyttää Huffman puun ehdot. Jos kyseessä on symboli, joka löytyy jo puusta, lisätään solmun painoarvoa, eli sitä määrää, montako kertaa symboli aineistossa esiintyy. Tämän jälkeen vaihdetaan tarvittaessa solmujen paikkaa kuten EVV solmun tilanteessa. 7

8 8 Kun mukautuva Huffman puu on luotu, on vuorossa aineiston pakkaus, jonka algoritmissa käydään läpi kaikki symbolit ja kutsutaan päivitysalgoritmia (3) jokaisen symbolin jälkeen: 1. Luetaan symboli. 2. Jos tämä on ensimmäinen kerta kun symboli esiintyy, pakataan EVV listan osoitin sekä väylä, jota kautta EVV - solmuun päästiin. 3. Muussa tapauksessa pakataan koodi, joka on väylä, joka kuljetaan juuresta kyseiseen solmuun. 4. Kutsutaan päivitysalgoritmia. 5. Siirrytään kohtaan 1 niin kauan, kunnes kyseessä on viimeinen symboli. Algoritmi 4. Algoritmi mukautuvan Huffman puun pakkaukselle [Sayood, 2006]. Algoritmin 4 kohdan 2 erikoistapauksessa ilmoitetaan pakatussa datassa, että kyseessä on symboli, jota ei ole vielä listassa. Muussa tapauksessa koodataan väylä, jota kautta päästän solmuun juuresta lähtien. Väylä muodostuu niin, että aina, kun puussa kuljetaan vasemmalle, on bittikoodi 0 ja kun kuljetaan oikealle, on koodi 1. Esimerkiksi jos symboliin päästään juuren kulkiessa ensin vasemmalle, sitten oikealle ja sitten vasemmalle, on bittikoodi tällöin 010. Mukautuvan Huffman puun purkaminen tapahtuu yksittäisten bittien avulla niin, että liikutaan puussa juuresta lähtien niin kauan, että vastaan tulee ulkosolmu tai EVV: 1. Aloitetaan Huffman puun juuresta. 2. Luetaan seuraava bitti pakatusta aineistosta. 3. Siirrytään joko vasempaan tai oikeaan lapseen bitin mukaisesti. Jos Huffman puussa kyseessä on sisäsolmu, siirrytään takaisin algoritmin kohtaan 2. Tehdään tätä niin kauan, kunnes tullaan ulkosolmuun tai EVV:hen. 4. Jos kyseessä on ulkosolmu ja se on EVV, puretaan aineistosta symboli sen mukaan, mitä indeksiä se vastaa EVV:ssä. 5. Jos kyseessä on ulkosolmu, tulostetaan symboli, joka sijaitsee kyseisessä solmussa. 8

9 6. Pienennetään symbolin painoarvoa ja kutsutaan päivitysalgoritmia. 7. Jatketaan kohdasta 1, kunnes kyseessä on viimeinen bitti. 9 Algoritmi 5. Algoritmi mukautuvan Huffman puun purkamiselle [Sayood, 2006]. Aina, kun yksi symboli on luettu, vähennetään sen arvoa binääripuussa. Näin siis Algoritmissa 5 ylläpidetään puuta myös purkamisen aikana. 5. Aritmeettinen koodaus Kappaleissa 3 ja 4 käsiteltiin todennäköisyyksiin perustuvia algoritmeja. Tärkeimpänä algoritmina esiteltiin Huffmanin koodaus, joka hallitsi pitkän aikaa tutkimusta pakkausteknologioiden alalla. Tässä kappaleessa esitellään aritmeettinen koodaus, joka on nousemassa yhä suositummaksi todennäköisyyksiin perustuvaksi koodaustavaksi Huffmanin koodauksen ohella. Huffman koodauksen yksi suurimmista ongelmista on se, että se pystyy pakkaamaan tietoa vain todennäköisyyksillä, jotka ovat kokonaislukumääräisiä. Monesti kuitenkin symbolien optimaalinen bittimäärä sisältää desimaaleja. Jos tietosisältö on esimerkiksi 2,6 bittiä, on Huffman puussa se koodattava joko 2 tai 3 bitillä. Tämä ongelma kasvaa suurimmaksi, kun jonkin yksittäisen symbolin todennäköisyys on erittäin suuri. Jos esimerkiksi symbolin todennäköisyys on 9/10, sen sisältämä informaatiosisältö on 0,15. Tässäkin tapauksessa symboli on pakattava yhdellä bitillä, joten ero alkuperäiseen tietosisältöön on suuri. Tämä ongelma muodostuu suureksi varsinkin binäärimuotoisessa datassa, kuten FAX laitteiden kaksivärisissä kuvissa, joissa todennäköisyys on välillä [0,1) [Sayood, 2006; Nelson ja Gailly, 1995]. Aritmeettinen koodaus tekee parannuksen tähän desimaaliluvulliseen todennäköisyysongelmaan. Aritmeettinen koodaus on siis käyttökelpoinen varsinkin binäärimuotoisissa kuvissa sekä aineistoissa, joissa erilaisia symboleita on vähän sekä sellaisissa aineistoissa, joissa todennäköisyydet ovat vinoutuneet (skewed), eli niiden jakauma ei ole normaalijakauman muotoinen [Sayood, 2006]. Aritmeettinen koodaus ei luo yksittäistä koodia jokaiselle symbolille, vaan koodiluku luodaan koko aineistolle. Tällä tavalla symbolin bittimäärä voidaan määritellä tarkemmin ja informaatiosisältö saadaan hyödynnettyä Huffman koodausta paremmin. Aritmeettinen koodaus on pakkausnopeudeltaan Huffman koodaukseen verrattuna hitaampi, mutta pakkausteho on yleensä parempi [Sayood, 2006; Nelson ja Gailly, 1995]. 9

10 10 Aritmeettisessa koodauksessa jokaisella symbolilla on oma paikkansa todennäköisyysvälillä [0, 1). Kaikkien todennäköisyyksien summa on aina 1. Koodauksessa jokainen merkki omistaa rivissä sen alueen, johon se kuuluu. Symbolit järjestetään ensin johonkin järjestykseen, jonka jälkeen jokaiselle symbolille annetaan väli jolle se kuuluu. Symbolien järjestyksellä ei ole väliä, kunhan purkuoperaatiossa käytetään samaa järjestystä kuin pakkauksessa. Esimerkiksi symbolijono binääripuu voitaisiin järjestää aakkosjärjestykseen. Tässä tapauksessa kirjain b omistaisi ensimmäisenä lukuna välin [0, 0,1). Seuraavan välin voisi omistaa symboli i, jota löytyy kaksi kappaletta, jolloin i omistaisi välin [0,1, 0,3) ja niin edelleen Aritmeettinen pakkausalgoritmi Aritmeettisessa pakkausalgoritmissa symbolimäärän ja aineiston suuretessa jokainen uusi symboli rajaa symbolin aluetta.: 1. Pienin luku <- 0,0 ja suurin luku <- 1,0 2. Luetaan merkkijonosta seuraava luku 3. nykyisen symbolin ala <- suurin luku-pienin luku 4. suurin luku <- pienin luku + nykyisen symbolin ala * nykyisen symbolin yläraja 5. pienin luku <- pienin luku + nykyisen symbolin ala * nykyisen symbolin alaraja 6. Palataan kohtaan 2, kunnes on luettu aineiston jokainen symboli. 7. Pakattu aineisto on pienin luku. Algoritmi 6. Aritmeettinen pakkausalgoritmi [Sayood, 2006]. Algoritmissa 6 Koodaus alkaa ensimmäisestä merkistä, jonka todennäköisyyden sisällä toimitaan symbolijonon loppuaika. Tätä tehdään rekursiivisesti, eli aina kun uusi merkki esiintyy, siirrytään rekursiossa sen todennäköisyyteen aikaisempien todennäköisyyksien sisällä. Esimerkiksi symbolijonossa binääripuu siirrytään aluksi ensimmäinen merkin todennäköisyyden sisälle, b = [0, 0,1). Tämän jälkeen esimerkissä siirrytään merkkiin i ja sijaitsee välillä [0,1, 0,3). Tällöin siirrytään ensimmäisen symbolin sisälle ja todennäköisyys muuttuu luvuksi [0,01, 0,03). Kolmas merkki toistaa tätä. Symboli n, jonka todennäköisyys rivillä on [0,3, 0,4) muuttaa koko merkkijonon todennäköisyydeksi [0,016, 0,018). Kun kaikki symbolit on 10

11 11 käyty läpi, saadaan alue, jonka alaraja on algoritmista saatu pakkaustulos. binääripuu lauseen esimerkissä tulos on Aritmeettinen purkualgoritmi Aritmeettisessa purkualgoritmissa lähdetään pakatun datan alusta ja käydään jokainen desimaali läpi. Jokaisen puretun symbolin jälkeen poistetaan sitä vastaava desimaali: 1. Luku <- Pakkauksen tuottama koodi. 2. Nykyinen symboli <- Symbolitaulukosta luvun osoittama väli 3. Lisätään symboli purettuun dataan. 4. Ala <- nykyisen symbolin yläraja - nykyisen symbolin alaraja 5. Numero <- numero - nykyisen symbolin alaraja 6. Numero <- numero / ala 7. Palataan kohtaan 2, kunnes on luettu jokainen desimaali. Algoritmi 7. Aritmeettinen purkualgoritmi [Nelson ja Gailly, 1995]. Purkualgoritmin (7) havainnollistamiseksi puretaan pakkausalgoritmissa käytetty esimerkki binääripuu, jonka pakattu data oli Ensimmäinen desimaali on 0 eli voidaan olettaa että kyseessä on symboli b, joka lisätään ensimmäisenä merkkinä purettuun dataan. Symbolien todennäköisyysjakauma toimitetaan pakkausalgoritmille, joten tiedämme että symbolin b :n alue on [0, 0,1). Tämä alue poistetaan pakatusta datasta, jonka jälkeen pakattu data esimerkissä on Poistoa tehdään niin kauan, kunnes pakattu data on kokonaan purettu Aritmeettisen algoritmin vertailua Huffmanin algoritmiin Tutkimme merkkijonoa aaaaaaa ja määrittelemme, että merkin a todennäköisyys koko aineistossa on 0,9. Tässä tapauksessa ensimmäinen a koodataan välillä [0,0, 0,9), toinen [0,0, 0,81) ja niin edelleen. Koko merkkijonon todennäköisyys muodostuu lopulta lopetussymbolin kanssa seuraavaksi: [0, , 0, ). aaaaaaa merkkijono voidaan tällöin merkitä esimerkiksi luvulla 0,45. Tämä desimaaliluku vie alle seitsemän bittiä. Kyseisen merkkijonon pituus Huffman koodauksessa veisi vähimmillään yhdeksän bittiä. Kuten aikaisemmin todettiin, aritmeettinen koodaus tuo parannusta Huffmanin koodaukseen esimerkiksi binäärimuotoisissa kuvissa sekä aineistoissa, joissa aakkosto on pieni [Sayood, 2006; Nelson ja Gailly, 1995]. 11

12 12 6. Sanakirjat tiedonpakkauksen uusi aika Aikaisemmissa kappaleissa kerrottiin pakkausteknologioista, jotka keskittyivät tutkimaan tiedon pakkausta informaatioteorian avulla. Tärkeitä käsitteitä olivat muun muassa entropia, redundanssi informaatio sekä tilastolliset todennäköisyydet. Esittelimme Huffmanin koodauksen sekä aritmeettisen koodauksen, jotka olivat tärkeimpiä teorioita koodauksen tutkimisessa luvun lopulla alkoi muutos kohti sanakirjoja, kun Jacob Ziv ja Abraham Lempel julkaisivat vuonna 1977 teoksen A Universal Algorithm for Sequential Data Compression. Tämä teos ei kuitenkaan välittömästi tuonut suosiota. Suuren yleisön tietoon sanakirjat tulivat vasta vuonna 1984 Terry Welchin julkaistua oman teoksensa A Technique for High Performance Data Compression [Welch, 1984]. Informaatioteoriaan perustuvissa koodauksissa yksittäiselle symbolille lasketaan todennäköisyys ja mallin pitää sekä arvioida, että ennustaa keskiarvosta eroavia todennäköisyyksiä. Sanakirjoissa koodaus perustuu yksittäisten symbolien sijaan symboliryhmiin, jotka muodostavat sanakirjan. Pakatussa aineistossa käytetään symboliryhmien sijaan osoittimia (pointer) kyseiseen sanakirjan kohtaan Sanakirjoihin siirtymisen vaiheet Sanakirjoihin siirryttiin kohtalaisen hitaasti. Vuonna 1977 julkaistu algoritmi otettiin tietokonemaailman käyttöön vasta 1984, kun Terry Welchin LZW:ksi nimeämän algoritmin myötä. Terry Welch käytti algoritminsa pohjana vuonna 1978 Lempelin ja Zivin julkaisemaa LZ78 algoritmia. LZW algoritmi oli alun perin suunniteltu kasettiasemien ja levykeasemien käyttöön, mutta siitä sai helposti muunneltua yleisesti toimivan pakkausohjelman. Lähes välittömästi artikkelin julkaisun jälkeen alettiin kehitellä LZW:llä toimivaa Unix pakkausohjelmaa. Ohjelma valmistui noin vuosi artikkelin julkaisun jälkeen ja sen nimi oli Compress [Nelson ja Gailly, 1995]. Vuonna 1985 julkaistiin LZ78 algoritmilla toimiva ARC pakkausohjelma, joka nousi välittömästi MS DOS käyttöjärjestelmien keskuudessa suureen suosioon. ARC:n avulla pystyttiin ensimmäistä kertaa MS DOS käyttöjärjestelmässä siirtämään useita tiedostoja samaan aikaan, joka oli ollut jo mahdollista Unix koneissa tar pakkausten avulla. PKARC nimisen kilpailijan markkinoille tulo lisäsi LZ78:n suosiota, mutta 1990 luvulla PKZIP, LHarc ja ARJ ohjelmistojen ilmestyminen muutti suuntausta LZ78 algoritmista LZ77 algoritmiin. Myös Internetissä suosittu PNG kuvanpakkausformaatti käyttää LZ77:aa, johtuen Unisys yhtiön LZW algoritmia käyttävän GIF pakkausformaatin patenttiongelmista [Nelson ja 12

13 13 Gailly, 1995]. Paneudumme yksittäisten sanakirjojen historiaan lähemmin seuraavassa kappaleessa Staattiset ja mukautuvat sanakirjat Staattinen sanakirja on pysyvä sanakirja, joka luodaan ennen pakkausta, eikä sitä muuteta pakkauksen aikana. Yksi staattisen sanakirjan hyvistä puolista on se, että sanakirja voidaan optimoida tarkasti pakattavan aineiston mukaan. Joissain tilanteissa tämä on tarpeen, esimerkiksi tietokonepeliin ohjelmoitava pysyvä tietokanta voisi käyttää tällaista ratkaisua. Staattisella sanakirjalla on kuitenkin sama ongelma kuin muissakin staattisissa malleissa, eli sanakirja täytyy välittää pakatun aineiston mukana ja tämä lisää tiedoston kokoa [Sayood, 2006; Nelson ja Gailly, 1995]. Yleisimmät tunnetut sanakirja algoritmit, kuten LZ77, LZ78 ja LZW edustavat mukautuvia sanakirjoja. Mukautuvat sanakirjat toimivat staattisen sanakirjan sijaan niin, että sanakirja on aluksi tyhjä ja siihen lisätään symbolijonoja sitä mukaa, kun pakkaus etenee. Tällaisessa pakkausalgoritmissa jaetaan aineisto ensin osiin, verrataan niitä sanakirjaan ja sen jälkeen lisätään ne sanakirjaan. Lopulta osoittimet ja aineisto pakataan yhdeksi tiedostoksi. Purkualgoritmissa puretaan tietovirta symboleiksi tai sanakirjaviittauksiksi ja lisätään sanat sanakirjaan, minkä jälkeen muutetaan sanakirja osiksi ja muutetaan osat symboleiksi. Purku, ja pakkausalgoritmit eivät vaadi paljoa prosessoritehoa, minkä takia mukautuvat sanakirjat ovat staattisia sanakirjoja suositumpia [Sayood, 2006; Nelson ja Gailly, 1995]. 7. Ikkunoihin perustuvat sanakirja algoritmit 7.1. LZ77 Ensimmäinen Lempelin ja Zivin esittelemä algoritmi oli vuonna 1977 ilmestynyt LZ77. Algoritmi sisältää ennalta määrätyn kokoisen ikkunan, joka on jaettu kahteen osaan. Ensimmäinen osa sisältää tietyn osan aikaisemmin koodatuista symboleista, alkaen edellisestä symbolista taaksepäin. Toinen osa sisältää etukäteispuskurin (look ahead buffer), joka lukee aineistosta tietyn kokoisen osan tulevia merkkejä. Edelliset symbolit sisältävä osa on etukäteispuskuria huomattavasti suurikokoisempi. Algoritmin toimintatapa perustuu näiden kahden osan vertaamiseen. Jos ikkunasta ei löydy symbolia ennestään, lisätään se sanakirjaan. Lopulta usein esiintyvät symbolijonot ryhmitellään suuremmiksi merkkiryhmiksi ja harvemmin esiintyvät pienemmiksi. Pakkausteho riippuu siitä kuinka pitkiä sanakirjan symbolijonot ovat, kuinka suuri ikkuna pakkauksessa on käytössä ja kuinka suuri entropia alkuperäisessä aineistossa on. 13

14 LZ77 pakkausalgoritmi sanakirjan luomiseen LZ77:ssa sanakirja muodostetaan samalla, kun aineistoa luetaan sisään. Etukäteispuskurista luetaan dataa ja verrataan sitä ikkunan sisältöön. Jos vastaavuus löytyy, tallennetaan osoitin tähän symboliin sekä vastaavuuden jälkeinen symboli: 1. Lähdetään lukemaan aineistoa alusta. 2. Käydään ikkunan aikaisemmin koodatut symbolit läpi ja etsitään se kohta, jolla on pisin vastaavuus etukäteispuskurin kanssa. 4. Jos vastaavuus löytyy, tallennetaan suurimmasta vastaavuuden kohdasta osoitin, joka sisältää tiedot: {[Osoittimen kohta, josta pisin vastaavuus alkoi], [Vastaavuuden pituus], [Koko vastaavuutta seuraava symboli]} 5. Muussa tapauksessa tallennetaan osoitin, joka sisältää etukäteispuskurin ensimmäisen symbolin arvoilla {0, 0, [Ensimmäinen symboli etukäteispuskurissa]}. 6. Jos etukäteispuskuri ei ole tyhjä, siirrytään aineistossa yksi symboli eteenpäin sekä algoritmissa kohtaan 2. Algoritmi 8. LZ77 pakkausalgoritmi [Sayood, 2006; Christina Zeeh, 2003]. Esimerkiksi jos algoritmissa 8 vertailtaisiin etukäteispuskurissa binääripuu symbolijonoa ja ikkunasta löytyisi jo symbolijono binää, tallennettaisiin sanakirjaan osoitin, joka viittaisi tähän kohtaan, sekä seuraava merkki eli r. Seuraavan kerran, kun sana binääripuu tulee vastaan, lisätään osoitin tähän kyseiseen sanakirjan esiintymään, joka sisältää nyt siis binäär ja seuraava merkki eli i. Kun etukäteispuskuri on tyhjä, on pakkausalgoritmi käyty läpi ja luotu sanakirja, jolla aineiston voi pakata. LZ77 sisältää suorituskyvyllisiä sekä koodaustehollisia ongelmia. Ensimmäinen ongelma on suorituskyvyllinen. Algoritmissa tehdään vertailu aikaisemmin koodattujen merkkien ja etukäteispuskurin aloitusmerkin kanssa, mikä on raskas operaatio. Ongelma pahenee entisestään, jos yritetään parantaa pakkaussuhdetta suurentamalla ikkunan kokoa. Toinen ongelma voi tulla pakkaustehon kanssa. Algoritmi olettaa symbolijonojen esiintyvän lähellä toisiaan, joka johtaa siihen, että merkkijonoa ei koodata, jos se toistuu etukäteispuskuria suuremmalla merkkijonovälillä. Pahimmassa tapauksessa koodattu aineisto on suurempi kuin alkuperäinen. Kolmas ongelma tulee vastaan, jos vastaantulevia symboleita ei löydy sanakirjasta. Tässäkin tapauksessa sen sijaan, että kerrottaisiin ainoastaan symboli, algoritmi käyttää 14

15 15 osoitinta, joka kertoo kohdan, pituuden ja seuraavan symbolin. Tämä tapa vie enemmän tilaa kuin vain alkuperäisen symbolin esittäminen, joten tässäkin tilanteessa pahimmassa tapauksessa koodaus vain suurentaa alkuperäisen tiedoston kokoa [Sayood, 2006; Nelson ja Gailly, 1995; Zeeh, 2003] LZSS LZ77 algoritmiin on tehty useita parannuksia, joista suosituin on vuonna 1982 julkaistu Storerin ja Szymanskin LZSS. LZSS käyttää LZ77:n tavoin ikkunaa ja korjaa tehokkuusongelmia, joita LZ77:ssa oli. Ensimmäinen parannus on siinä, kuinka ikkunaa hallitaan. LZSS parantaa koodausvaiheen koodauksen lisäämällä teksti ikkunan koodatut symbolit binäärihakupuuhun. Tällä tavoin saadaan LZ77:n O(n 2 ) aikavaatimuksellisesta algoritmista O(n log n) tyyppinen. Tämän uudistuksen ansiosta on mahdollista suurentaa tekstiikkunaa huomattavasti ilman suurempia aikavaatimusongelmia [Nelson ja Gailly, 1995]. Toinen parannus LZSS:ssä on symbolijonojen koodaamisessa. LZ77:ssa koko aineisto koodattiin osoittimella, joka kertoi aloituskohdan, pituuden ja symbolijonoa seuraavan symbolin. Myös sellaiset symbolit, joita ei löytynyt ikkunasta, muutettiin osoittimiksi. LZSS algoritmi voi sen sijaan tuottaa sekä osoittimia, että symboleja. Pelkkinä symboleina esitetään siis sellaiset symbolit, joita ei ikkunasta löydy ennestään [Nelson ja Gailly, 1995]. 8. LZ78 ja perilliset 8.1. LZ78 LZ77:n suurimpana ongelmana pidetään sitä, että jos toistoa tapahtuu alkuperäisessä aineistossa liian harvoin, saattaa toistuva symbolijono jäädä ikkunan ja pakkauksen ulkopuolelle. Tilannetta voidaan yrittää parantaa suurentamalla etukäteispuskuria, mutta tämä johtaa vielä huonompiin tuloksiin, koska osoittimen kohdan ilmoittaminen sekä symbolijonon koodaus vievät enemmän tilaa. Tämän lisäksi prosessoriajan kulutus kasvaa nopeasti, varsinkin puskurin kokoa nostaessa [Nelson ja Gailly, 1995]. LZ77:n ongelmien ratkaisemiseksi Lempel ja Ziv julkaisivat vuonna 1978 Compression of Individual Sequences via Variable Rate Coding nimisessä artikkelissa LZ78 algoritmin, jossa he paransivat LZ77:n ongelmia. LZ78 algoritmi ratkaisee LZ77:n suorituskykyongelman ja koodausteho ongelman niin, että se poistaa pakkausalgoritmista ikkunan jolloin koko sanakirjaa verrataan sisään tulevaan tietovirtaan [Sayood, 2006; Nelson ja Gailly, 1995]. 15

16 LZ78 pakkausalgoritmi LZ78 pakkausalgoritmissa koko sanakirjaa verrataan sisään tulevaan tietovirtaan toisin kuin LZ77:ssa, jossa luotiin ikkuna vertailun avuksi: 1. Asetetaan väliaikainen i muuttuja tyhjäksi. 2. Luetaan seuraava symboli s. 3. Jos i + s sijaitsee sanakirjassa, asetetaan i:n arvoksi i + s ja siirrytään kohtaan Muussa tapauksessa lisätään koodattuun dataan {[viittaus siihen indeksiin jossa sijaitsee i], [s]}. Jos sanakirjassa ei ole viittausta i:hin, asetetaan viitteeksi Lisätään i + s sanakirjaan ja tyhjennetään i. 6. jatketaan kohdasta 2, kunnes koko aineisto on luettu. Algoritmi 9. LZ78 pakkausalgoritmi [Christina Zeeh, 2003]. Esimerkkinä pakkauksesta koodataan algoritmissa 9 sana abab. Algoritmissa luetaan ensin symboli a, joka lisätään koodattuun dataan arvolla {0, a }. Tämän jälkeen sanakirjaan lisätään symboli a indeksillä 1 ja jatketaan seuraavasta merkistä. Seuraavaa merkkiä b :kään ei näytä löytyvän sanakirjasta, joten lisätään se koodattuun dataan arvolla {0, b }, lisätään b sanakirjaan indeksiin 2 ja Jatketaan seuraavan symboliin. Seuraava symboli on a ja näyttää olevan jo sanakirjassa, joten lisätään se väliaikaiseen muuttujaan ja aloitetaan alusta. Seuraava merkki on b, joten merkkijono on nyt i + s, eli ab. Tätä ei näytä olevan sanakirjassa, joten lisätään koodattuun dataan a :n indeksi ja symboli, eli {1, b }. Tämän jälkeen lisätään sanakirjaan ab indeksiin 3. LZ78 algoritmi sisältää ongelmallisia kohtia, joita on yritetty korjata erilaisilla tavoilla. Suurin ongelma algoritmissa on sanakirja, joka voi kasvaa rajattoman suureksi. Sanakirjan kasvua voidaan kuitenkin yrittää rajoittaa muokkaamalla algoritmia. Esimerkiksi UNIXin compress pakkausohjelmassa tarkkaillaan tiedoston pakkaussuhdetta. Jos pakkaussuhde alkaa heiketä, sanakirja poistetaan ja ohjelma aloittaa pakkauksen alusta. Vaihtoehtoisesti ohjelmassa voidaan käyttää nykyistä sanakirjaa, mutta ei lisätä siihen enempää sanakirjamerkintöjä tulevasta tietovirrasta [Nelson ja Gailly, 1995; Zeeh, 2003]. 16

17 LZW Terry Welch julkaisi vuonna 1984 A Technique for High Performance Data Compression artikkelin. Kuten 6.1 kohdassa todettiin, tämä artikkeli aloitti sanakirjojen nopean leviämisen. LZW on LZ78 algoritmin jälkeläinen. Algoritmissa luetaan sanakirjaan kaikki yksittäiset symbolit ennen koodauksen aloittamista, joten algoritmissa ei tarvitse ottaa huomioon symboleita ja koko aineisto voidaan tallentaa ainoastaan osoittimina. Tämä yksinkertaistaa algoritmia LZ78:aan verrattuna jonkin verran. Welch otti artikkelissaan kantaa myös jo LZ78 algoritmissa mainittuun sanakirjan rajattomaan kasvuun. Hän ehdotti, että osoittimien koko olisi 12 bittiä, jolloin sanakirjaan voitaisiin lisätä enimmillään 4096 sanakirjamerkintää. Tämän jälkeen sanakirja muuttuisi staattiseksi [Sayood, 2006; Nelson ja Gailly, 1995; Zeeh, 2003] LZW algoritmi LZW algoritmin toimintatapa on seuraavanlainen: 1. Asetetaan väliaikainen i muuttuja tyhjäksi. 2. Luetaan seuraava symboli s. 3. Jos i + s sijaitsee sanakirjassa, asetetaan i:n arvoksi i + s ja siirrytään kohtaan Muussa tapauksessa lisätään koodattuun dataan {[viittaus siihen indeksiin jossa sijaitsee i]}. 5. Lisätään i + s sanakirjaan ja asetetaan i:ksi s. 6. jatketaan kohdasta 2, kunnes koko aineisto on luettu. Algoritmi 10. LZ78 pakkausalgoritmi [Christina Zeeh, 2003]. LZW sanakirja algoritmi (10) vastaa LZ78 algoritmia ainoastaan sillä erolla, että LZW:ssä luetaan kaikki käytettävät symbolit sanakirjaan ennen koodauksen aloittamista. Tämä yksinkertaistaa algoritmia niin, ettei sanakirjaan tarvitse lisätä kuin osoittimia. 9. Yhteenveto Nykyaikainen tiedonpakkausteorioiden kehittely sai alkunsa Bell Labsin Claude Shannonin 1940 luvulla kehittelemästä informaatioteoriasta. Informaatioteoria antoi hyvän kuvan siitä, missä rajoissa tietoa pystyttiin binäärimuodossa pakkaamaan poistamalla redundassi informaatio. David A. Huffman ( ) kehitti tämän teorian pohjalta vuonna

18 18 algoritmiteorian, joka muodostui vuosikymmenten ajaksi tärkeimmäksi pakkaustekniikoiden tutkimuskohteeksi. Ajan mittaan informaatioteorian perusteella kehitettiin myös Huffmanin algoritmista eroavia pakkausalgoritmeja. Huffman koodauksen perilliseksi muodostui tietokoneiden kehittyessä aritmeettinen koodaus, joka oli Huffman koodausta tehokkaampi, mutta tietokoneteholtaan vaativampi. Todennäköisyyksiin perustuva pakkaus oli 1970 luvun loppuun asti ainoa varteenotettava tekniikka harrastaa tiedonpakkausta, kunnes Jacob Ziv ja Abraham Lempel julkaisivat LZ77 ja LZ78 algoritmit. Sanakirjat olivat aivan uudenlainen lähtökohta tiedonpakkauksen tutkimisessa ja ne erosivat aikaisemmista algoritmeista, koska ne eivät perustuneet informaatioteoriaan. Nämä algoritmit eivät yleistyneet välittömästi. Vasta Terry Welchin julkaistessa LZ78:aan perustuvan LZW algoritmin vuonna 1984 tiedonpakkauksen tutkimus siirtyi kohti sanakirjoja. 18

19 19 Viiteluettelo [Nelson ja Gailly, 1995] Mark Nelson ja Jean loup Gailly, The Data Compression Book 2nd edition, M&T Books, New York, NY, [Sayood, 2006] Khalid Sayood, Introduction to Data Compression (Third Edition), Elsevier Inc, [Lelewer ja Hirschberg, 1987] Debra A. Lelewer ja Daniel S. Hirschberg, Data compression, ACM Computing Surveys 19 (Sep. 1987), [Stix, 1991] Gary Stix, Profile: David A. Huffman, Scientific American, [Cormen, Leiserson, Rivest ja Stein, 2001] Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein, Introduction to Algorithms, Second Edition, MIT Press and McGraw Hill, [Zeeh, 2003] Christina Zeeh, Seminar Famous Algorithms, January 16, [Huffman, 1952] David A. Huffman, A Method for the construction of minimumredundancy codes, Proc. IRE 40, 1098 (1952). [Welch, 1984] Terry A. Welch, A technique for high performance data compression, Computer 17 (Jun. 1984), [Ziv ja Lempel, 1977] Jacob Ziv and Abraham Lempel, A Universal Algorithm for Sequential Data Compression, IEEE Transactions on Information Theory, 23(3), (May 1977), [Ziv ja Lempel, 1978] Jacob Ziv and Abraham Lempel, Compression of Individual Sequences via Variable Rate Coding, IEEE Transactions on Information Theory, 24, (1978),

Algoritmit 1. Luento 7 Ti Timo Männikkö

Algoritmit 1. Luento 7 Ti Timo Männikkö Algoritmit 1 Luento 7 Ti 31.1.2017 Timo Männikkö Luento 7 Järjestetty binääripuu Binääripuiden termejä Binääripuiden operaatiot Solmun haku, lisäys, poisto Algoritmit 1 Kevät 2017 Luento 7 Ti 31.1.2017

Lisätiedot

Algoritmit 1. Luento 8 Ke Timo Männikkö

Algoritmit 1. Luento 8 Ke Timo Männikkö Algoritmit 1 Luento 8 Ke 1.2.2017 Timo Männikkö Luento 8 Järjestetty binääripuu Solmujen läpikäynti Binääripuun korkeus Binääripuun tasapainottaminen Graafit ja verkot Verkon lyhimmät polut Fordin ja Fulkersonin

Lisätiedot

Luku 8. Aluekyselyt. 8.1 Summataulukko

Luku 8. Aluekyselyt. 8.1 Summataulukko Luku 8 Aluekyselyt Aluekysely on tiettyä taulukon väliä koskeva kysely. Tyypillisiä aluekyselyitä ovat, mikä on taulukon välin lukujen summa tai pienin luku välillä. Esimerkiksi seuraavassa taulukossa

Lisätiedot

Graafin 3-värittyvyyden tutkinta T Graafiteoria, projektityö (eksakti algoritmi), kevät 2005

Graafin 3-värittyvyyden tutkinta T Graafiteoria, projektityö (eksakti algoritmi), kevät 2005 Graafin 3-värittyvyyden tutkinta T-79.165 Graafiteoria, projektityö (eksakti algoritmi), kevät 2005 Mikko Malinen, 36474R 29. maaliskuuta, 2005 Tiivistelmä Artikkelissa käydään läpi teoriaa, jonka avulla

Lisätiedot

TAMPEREEN TEKNILLINEN YLIOPISTO

TAMPEREEN TEKNILLINEN YLIOPISTO TAMPEREEN TEKNILLINEN YLIOPISTO Digitaali- ja Tietokonetekniikan laitos TKT-3200 Tietokonetekniikka ASSEMBLER: QSORT 06.09.2005 Ryhmä 00 nimi1 email1 opnro1 nimi2 email2 opnro2 nimi3 email3 opnro3 1. TEHTÄVÄ

Lisätiedot

Algoritmit 1. Luento 6 Ke Timo Männikkö

Algoritmit 1. Luento 6 Ke Timo Männikkö Algoritmit 1 Luento 6 Ke 25.1.2017 Timo Männikkö Luento 6 Järjestetty lista Listan toteutus dynaamisesti Linkitetyn listan operaatiot Vaihtoehtoisia listarakenteita Puurakenteet Binääripuu Järjestetty

Lisätiedot

Tehtävä 2: Loppuosataulukko

Tehtävä 2: Loppuosataulukko Tehtävä 2: Loppuosataulukko Tutustu tarkoin seuraavaan tekstiin ja vastaa sitä hyväksi käyttäen tehtävän loppuosassa esitettyihin viiteen kysymykseen. Annetun merkkijonon (ns. hahmo) esiintymän haku pidemmästä

Lisätiedot

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1 Ohjelmoinnin peruskurssi Y1 CSE-A1111 30.9.2015 CSE-A1111 Ohjelmoinnin peruskurssi Y1 30.9.2015 1 / 27 Mahdollisuus antaa luentopalautetta Goblinissa vasemmassa reunassa olevassa valikossa on valinta Luentopalaute.

Lisätiedot

Hakupuut. tässä luvussa tarkastelemme puita tiedon tallennusrakenteina

Hakupuut. tässä luvussa tarkastelemme puita tiedon tallennusrakenteina Hakupuut tässä luvussa tarkastelemme puita tiedon tallennusrakenteina hakupuun avulla voidaan toteuttaa kaikki joukko-tietotyypin operaatiot (myös succ ja pred) pahimman tapauksen aikavaativuus on tavallisella

Lisätiedot

Toisessa kyselyssä alueella on 1 ruudussa A ja 3 ruudussa B, joten suosituin ehdokas on B.

Toisessa kyselyssä alueella on 1 ruudussa A ja 3 ruudussa B, joten suosituin ehdokas on B. A Alueet Bittimaassa järjestetään vaalit, joissa on 26 ehdokasta. Jokaisella ehdokkaalla on kirjaintunnus välillä A...Z. Bittimaa on suorakulmion muotoinen ja jaettu neliöruutuihin. Tehtäväsi on selvittää

Lisätiedot

Tietorakenteet ja algoritmit

Tietorakenteet ja algoritmit Tietorakenteet ja algoritmit Rekursio Rekursion käyttötapauksia Rekursio määritelmissä Rekursio ongelmanratkaisussa ja ohjelmointitekniikkana Esimerkkejä taulukolla Esimerkkejä linkatulla listalla Hanoin

Lisätiedot

ALGORITMIT 1 DEMOVASTAUKSET KEVÄT 2012

ALGORITMIT 1 DEMOVASTAUKSET KEVÄT 2012 ALGORITMIT 1 DEMOVASTAUKSET KEVÄT 2012 1.1. (a) Jaettava m, jakaja n. Vähennetään luku n luvusta m niin kauan kuin m pysyy ei-negatiivisena. Jos jäljelle jää nolla, jaettava oli tasan jaollinen. int m,

Lisätiedot

Algoritmit 2. Luento 9 Ti Timo Männikkö

Algoritmit 2. Luento 9 Ti Timo Männikkö Algoritmit 2 Luento 9 Ti 19.4.2016 Timo Männikkö Luento 9 Merkkitiedon tiivistäminen LZW-menetelmä Taulukointi Editointietäisyys Peruutus Verkon 3-väritys Algoritmit 2 Kevät 2016 Luento 9 Ti 19.4.2016

Lisätiedot

811312A Tietorakenteet ja algoritmit, , Harjoitus 5, Ratkaisu

811312A Tietorakenteet ja algoritmit, , Harjoitus 5, Ratkaisu 1312A Tietorakenteet ja algoritmit, 2016-2017, Harjoitus 5, Ratkaisu Harjoituksen aihe ovat hash-taulukot ja binääriset etsintäpuut Tehtävä 5.1 Tallenna avaimet 10,22,31,4,15,28,17 ja 59 hash-taulukkoon,

Lisätiedot

Tietorakenteet ja algoritmit syksy Laskuharjoitus 1

Tietorakenteet ja algoritmit syksy Laskuharjoitus 1 Tietorakenteet ja algoritmit syksy 2012 Laskuharjoitus 1 1. Tietojenkäsittelijä voi ajatella logaritmia usein seuraavasti: a-kantainen logaritmi log a n kertoo, kuinka monta kertaa luku n pitää jakaa a:lla,

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 15.3.2010 T-106.1208 Ohjelmoinnin perusteet Y 15.3.2010 1 / 56 Tiedostoista: tietojen tallentaminen ohjelman suorituskertojen välillä Monissa sovelluksissa ohjelman

Lisätiedot

58131 Tietorakenteet (kevät 2009) Harjoitus 9, ratkaisuja (Antti Laaksonen)

58131 Tietorakenteet (kevät 2009) Harjoitus 9, ratkaisuja (Antti Laaksonen) 58131 Tietorakenteet (kevät 2009) Harjoitus 9, ratkaisuja (Antti Laaksonen) 1. Lisäysjärjestämisessä järjestetään ensin taulukon kaksi ensimmäistä lukua, sitten kolme ensimmäistä lukua, sitten neljä ensimmäistä

Lisätiedot

Luku 6. Dynaaminen ohjelmointi. 6.1 Funktion muisti

Luku 6. Dynaaminen ohjelmointi. 6.1 Funktion muisti Luku 6 Dynaaminen ohjelmointi Dynaamisessa ohjelmoinnissa on ideana jakaa ongelman ratkaisu pienempiin osaongelmiin, jotka voidaan ratkaista toisistaan riippumattomasti. Jokaisen osaongelman ratkaisu tallennetaan

Lisätiedot

ja λ 2 = 2x 1r 0 x 2 + 2x 1r 0 x 2

ja λ 2 = 2x 1r 0 x 2 + 2x 1r 0 x 2 Johdatus diskreettiin matematiikkaan Harjoitus 4, 7.10.2015 1. Olkoot c 0, c 1 R siten, että polynomilla r 2 c 1 r c 0 on kaksinkertainen juuri. Määritä rekursioyhtälön x n+2 = c 1 x n+1 + c 0 x n, n N,

Lisätiedot

Jokaisella tiedostolla on otsake (header), joka sisältää tiedostoon liittyvää hallintatietoa

Jokaisella tiedostolla on otsake (header), joka sisältää tiedostoon liittyvää hallintatietoa Tietojen tallennusrakenteet Jokaisella tiedostolla on otsake (header), joka sisältää tiedostoon liittyvää hallintatietoa tiedot tiedostoon kuuluvista lohkoista esim. taulukkona, joka voi muodostua ketjutetuista

Lisätiedot

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset 815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 3 vastaukset Harjoituksen aiheena ovat imperatiivisten kielten muuttujiin liittyvät kysymykset. Tehtävä 1. Määritä muuttujien max_num, lista,

Lisätiedot

VÄRISPEKTRIKUVIEN TEHOKAS SIIRTO TIETOVERKOISSA

VÄRISPEKTRIKUVIEN TEHOKAS SIIRTO TIETOVERKOISSA VÄRISPEKTRIKUVIEN TEHOKAS SIIRTO TIETOVERKOISSA Juha Lehtonen 20.3.2002 Joensuun yliopisto Tietojenkäsittelytiede Kandidaatintutkielma ESIPUHE Olen kirjoittanut tämän kandidaatintutkielman Joensuun yliopistossa

Lisätiedot

Ohjelmassa muuttujalla on nimi ja arvo. Kääntäjä ja linkkeri varaavat muistilohkon, jonne muuttujan arvo talletetaan.

Ohjelmassa muuttujalla on nimi ja arvo. Kääntäjä ja linkkeri varaavat muistilohkon, jonne muuttujan arvo talletetaan. Osoittimet Ohjelmassa muuttujalla on nimi ja arvo. Kääntäjä ja linkkeri varaavat muistilohkon, jonne muuttujan arvo talletetaan. Muistilohkon koko riippuu muuttujan tyypistä, eli kuinka suuria arvoja muuttujan

Lisätiedot

Bayesin pelit. Kalle Siukola. MS-E2142 Optimointiopin seminaari: Peliteoria ja tekoäly

Bayesin pelit. Kalle Siukola. MS-E2142 Optimointiopin seminaari: Peliteoria ja tekoäly Bayesin pelit Kalle Siukola MS-E2142 Optimointiopin seminaari: Peliteoria ja tekoäly 12.10.2016 Toistetun pelin esittäminen automaatin avulla Ekstensiivisen muodon puu on tehoton esitystapa, jos peliä

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 2.3.2009 T-106.1208 Ohjelmoinnin perusteet Y 2.3.2009 1 / 28 Puhelinluettelo, koodi def lue_puhelinnumerot(): print "Anna lisattavat nimet ja numerot." print

Lisätiedot

(d) 29 4 (mod 7) (e) ( ) 49 (mod 10) (f) (mod 9)

(d) 29 4 (mod 7) (e) ( ) 49 (mod 10) (f) (mod 9) 1. Pätevätkö seuraavat kongruenssiyhtälöt? (a) 40 13 (mod 9) (b) 211 12 (mod 2) (c) 126 46 (mod 3) Ratkaisu. (a) Kyllä, sillä 40 = 4 9+4 ja 13 = 9+4. (b) Ei, sillä 211 on pariton ja 12 parillinen. (c)

Lisätiedot

AVL-puut. eräs tapa tasapainottaa binäärihakupuu siten, että korkeus on O(log n) kun puussa on n avainta

AVL-puut. eräs tapa tasapainottaa binäärihakupuu siten, että korkeus on O(log n) kun puussa on n avainta AVL-puut eräs tapa tasapainottaa binäärihakupuu siten, että korkeus on O(log n) kun puussa on n avainta pohjana jo esitetyt binäärihakupuiden operaatiot tasapainotus vie pahimmillaan lisäajan lisäys- ja

Lisätiedot

2. Seuraavassa kuvassa on verkon solmujen topologinen järjestys: x t v q z u s y w r. Kuva 1: Tehtävän 2 solmut järjestettynä topologisesti.

2. Seuraavassa kuvassa on verkon solmujen topologinen järjestys: x t v q z u s y w r. Kuva 1: Tehtävän 2 solmut järjestettynä topologisesti. Tietorakenteet, laskuharjoitus 11, ratkaisuja 1. Leveyssuuntaisen läpikäynnin voi toteuttaa rekursiivisesti käsittelemällä jokaisella rekursiivisella kutsulla kaikki tietyllä tasolla olevat solmut. Rekursiivinen

Lisätiedot

TKHJ:ssä on yleensä komento create index, jolla taululle voidaan luoda hakemisto

TKHJ:ssä on yleensä komento create index, jolla taululle voidaan luoda hakemisto Indeksin luonti ja hävitys TKHJ:ssä on yleensä komento create index, jolla taululle voidaan luoda hakemisto Komentoa ei ole standardoitu ja niinpä sen muoto vaihtelee järjestelmäkohtaisesti Indeksi voidaan

Lisätiedot

Esimerkkejä vaativuusluokista

Esimerkkejä vaativuusluokista Esimerkkejä vaativuusluokista Seuraaville kalvoille on poimittu joitain esimerkkejä havainnollistamaan algoritmien aikavaativuusluokkia. Esimerkit on valittu melko mielivaltaisesti laitoksella tehtävään

Lisätiedot

Harjoitus 6 ( )

Harjoitus 6 ( ) Harjoitus 6 (30.4.2014) Tehtävä 1 Määritelmän (ks. luentomoniste s. 109) mukaan yleisen, muotoa min f(x) s.t. g(x) 0 h(x) = 0 x X (1) olevan optimointitehtävän Lagrangen duaali on max θ(u,v) s.t. u 0,

Lisätiedot

4. Joukkojen käsittely

4. Joukkojen käsittely 4 Joukkojen käsittely Tämän luvun jälkeen opiskelija osaa soveltaa lomittuvien kasojen operaatioita tuntee lomittuvien kasojen toteutuksen binomi- ja Fibonacci-kasoina sekä näiden totetutusten analyysiperiaatteet

Lisätiedot

ATK tähtitieteessä. Osa 3 - IDL proseduurit ja rakenteet. 18. syyskuuta 2014

ATK tähtitieteessä. Osa 3 - IDL proseduurit ja rakenteet. 18. syyskuuta 2014 18. syyskuuta 2014 IDL - proseduurit Viimeksi käsiteltiin IDL:n interaktiivista käyttöä, mutta tämä on hyvin kömpelöä monimutkaisempia asioita tehtäessä. IDL:llä on mahdollista tehdä ns. proseduuri-tiedostoja,

Lisätiedot

58131 Tietorakenteet ja algoritmit (syksy 2015)

58131 Tietorakenteet ja algoritmit (syksy 2015) 58131 Tietorakenteet ja algoritmit (syksy 2015) Harjoitus 2 (14. 18.9.2015) Huom. Sinun on tehtävä vähintään kaksi tehtävää, jotta voit jatkaa kurssilla. 1. Erään algoritmin suoritus vie 1 ms, kun syötteen

Lisätiedot

A TIETORAKENTEET JA ALGORITMIT KORVAAVAT HARJOITUSTEHTÄVÄT 3, DEADLINE KLO 12:00

A TIETORAKENTEET JA ALGORITMIT KORVAAVAT HARJOITUSTEHTÄVÄT 3, DEADLINE KLO 12:00 A274101 TIETORAKENTEET JA ALGORITMIT KORVAAVAT HARJOITUSTEHTÄVÄT 3, DEADLINE 9.2.2005 KLO 12:00 PISTETILANNE: www.kyamk.fi/~atesa/tirak/harjoituspisteet-2005.pdf Kynätehtävät palautetaan kirjallisesti

Lisätiedot

Kohdissa 2 ja 3 jos lukujen valintaan on useita vaihtoehtoja, valitaan sellaiset luvut, jotka ovat mahdollisimman lähellä listan alkua.

Kohdissa 2 ja 3 jos lukujen valintaan on useita vaihtoehtoja, valitaan sellaiset luvut, jotka ovat mahdollisimman lähellä listan alkua. A Lista Aikaraja: 1 s Uolevi sai käsiinsä listan kokonaislukuja. Hän päätti laskea listan luvuista yhden luvun käyttäen seuraavaa algoritmia: 1. Jos listalla on vain yksi luku, pysäytä algoritmi. 2. Jos

Lisätiedot

S: siirtää listan ensimmäisen luvun viimeiseksi V: vaihtaa keskenään listan kaksi ensimmäistä lukua

S: siirtää listan ensimmäisen luvun viimeiseksi V: vaihtaa keskenään listan kaksi ensimmäistä lukua A Lista Sinulle on annettu lista, joka sisältää kokonaisluvut 1, 2,, n jossakin järjestyksessä. Tehtäväsi on järjestää luvut pienimmästä suurimpaan käyttäen seuraavia operaatioita: S: siirtää listan ensimmäisen

Lisätiedot

Sinulle on annettu bittijono, ja tehtäväsi on muuttaa jonoa niin, että jokainen bitti on 0.

Sinulle on annettu bittijono, ja tehtäväsi on muuttaa jonoa niin, että jokainen bitti on 0. A Bittien nollaus Sinulle on annettu bittijono, ja tehtäväsi on muuttaa jonoa niin, että jokainen bitti on 0. Saat käyttää seuraavia operaatioita: muuta jokin bitti vastakkaiseksi (0 1 tai 1 0) muuta kaikki

Lisätiedot

AV-muotojen migraatiotyöpaja - ääni. KDK-pitkäaikaissäilytys 2013 -seminaari 6.5.2013 / Juha Lehtonen

AV-muotojen migraatiotyöpaja - ääni. KDK-pitkäaikaissäilytys 2013 -seminaari 6.5.2013 / Juha Lehtonen AV-muotojen migraatiotyöpaja - ääni KDK-pitkäaikaissäilytys 2013 -seminaari 6.5.2013 / Juha Lehtonen Äänimuodot Ääneen vaikuttavia asioita Taajuudet Äänen voimakkuus Kanavien määrä Näytteistys Bittisyvyys

Lisätiedot

D B. Levykön rakenne. pyöriviä levyjä ura. lohko. Hakuvarsi. sektori. luku-/kirjoituspää

D B. Levykön rakenne. pyöriviä levyjä ura. lohko. Hakuvarsi. sektori. luku-/kirjoituspää Levyn rakenne Levykössä (disk drive) on useita samankeskisiä levyjä (disk) Levyissä on magneettinen pinta (disk surface) kummallakin puolella levyä Levyllä on osoitettavissa olevia uria (track), muutamasta

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 1.4.2009 T-106.1208 Ohjelmoinnin perusteet Y 1.4.2009 1 / 56 Tentti Ensimmäinen tenttimahdollisuus on pe 8.5. klo 13:00 17:00 päärakennuksessa. Tämän jälkeen

Lisätiedot

Kenguru 2012 Junior sivu 1 / 8 (lukion 1. vuosi)

Kenguru 2012 Junior sivu 1 / 8 (lukion 1. vuosi) Kenguru 2012 Junior sivu 1 / 8 Nimi Ryhmä Pisteet: Kenguruloikan pituus: Irrota tämä vastauslomake tehtävämonisteesta. Merkitse tehtävän numeron alle valitsemasi vastausvaihtoehto. Väärästä vastauksesta

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 10.2.2010 T-106.1208 Ohjelmoinnin perusteet Y 10.2.2010 1 / 43 Kertausta: listat Tyhjä uusi lista luodaan kirjoittamalla esimerkiksi lampotilat = [] (jolloin

Lisätiedot

Matematiikan tukikurssi, kurssikerta 3

Matematiikan tukikurssi, kurssikerta 3 Matematiikan tukikurssi, kurssikerta 3 1 Epäyhtälöitä Aivan aluksi lienee syytä esittää luvun itseisarvon määritelmä: { x kun x 0 x = x kun x < 0 Siispä esimerkiksi 10 = 10 ja 10 = 10. Seuraavaksi listaus

Lisätiedot

Algoritmit 1. Luento 1 Ti Timo Männikkö

Algoritmit 1. Luento 1 Ti Timo Männikkö Algoritmit 1 Luento 1 Ti 10.1.2017 Timo Männikkö Luento 1 Algoritmi Algoritmin toteutus Ongelman ratkaiseminen Algoritmin tehokkuus Algoritmin suoritusaika Algoritmin analysointi Algoritmit 1 Kevät 2017

Lisätiedot

Luku- ja merkkikoodit. Digitaalitekniikan matematiikka Luku 12 Sivu 1 (15)

Luku- ja merkkikoodit. Digitaalitekniikan matematiikka Luku 12 Sivu 1 (15) Digitaalitekniikan matematiikka Luku 12 Sivu 1 (15) A = a = i i w i Digitaalitekniikan matematiikka Luku 12 Sivu 2 (15) Johdanto Tässä luvussa esitetään kymmenjärjestelmän lukujen eli BCD-lukujen esitystapoja

Lisätiedot

T Luonnollisen kielen tilastollinen käsittely Vastaukset 8, ti , 8:30-10:00 Tilastolliset yhteydettömät kieliopit, Versio 1.

T Luonnollisen kielen tilastollinen käsittely Vastaukset 8, ti , 8:30-10:00 Tilastolliset yhteydettömät kieliopit, Versio 1. T-61.281 Luonnollisen kielen tilastollinen käsittely astaukset 8, ti 16.3.2004, 8:30-10:00 Tilastolliset yhteydettömät kielioit, ersio 1.0 1. Jäsennysuun todennäköisyys lasketaan aloittelemalla se säännöstön

Lisätiedot

Algebralliset tietotyypit ym. TIEA341 Funktio ohjelmointi 1 Syksy 2005

Algebralliset tietotyypit ym. TIEA341 Funktio ohjelmointi 1 Syksy 2005 Algebralliset tietotyypit ym. TIEA341 Funktio ohjelmointi 1 Syksy 2005 Tällä luennolla Algebralliset tietotyypit Hahmonsovitus (pattern matching) Primitiivirekursio Esimerkkinä binäärinen hakupuu Muistattehan...

Lisätiedot

MAY1 Tehtävien ratkaisut Kustannusosakeyhtiö Otava päivitetty 12.4.2016 Julkaiseminen sallittu vain koulun suljetussa verkossa.

MAY1 Tehtävien ratkaisut Kustannusosakeyhtiö Otava päivitetty 12.4.2016 Julkaiseminen sallittu vain koulun suljetussa verkossa. KERTAUS Lukujono KERTAUSTEHTÄVIÄ K1. Ratkaisussa annetaan esimerkit mahdollisista säännöistä. a) Jatketaan lukujonoa: 2, 4, 6, 8, 10, 12, 14, 16, Rekursiivinen sääntö on, että lukujonon ensimmäinen jäsen

Lisätiedot

Algoritmi on periaatteellisella tasolla seuraava:

Algoritmi on periaatteellisella tasolla seuraava: Algoritmi on periaatteellisella tasolla seuraava: Dijkstra(V, E, l, v 0 ): S := { v 0 } D[v 0 ] := 0 for v V S do D[v] := l(v 0, v) end for while S V do valitse v V S jolle D[v] on minimaalinen S := S

Lisätiedot

811312A Tietorakenteet ja algoritmit III Lajittelualgoritmeista

811312A Tietorakenteet ja algoritmit III Lajittelualgoritmeista 811312A Tietorakenteet ja algoritmit 2016-2017 III Lajittelualgoritmeista Sisältö 1. Johdanto 2. Pikalajittelu 3. Kekolajittelu 4. Lajittelualgoritmien suorituskyvyn rajoista 811312A TRA, Lajittelualgoritmeista

Lisätiedot

20. Javan omat luokat 20.1

20. Javan omat luokat 20.1 20. Javan omat luokat 20.1 Sisällys Application Programming Interface (API). Pakkaukset. Merkkijonoluokka String. Math-luokka. Kääreluokat. 20.2 Java API Java-kielen Application Programming Interface (API)

Lisätiedot

Sisällys. 20. Javan omat luokat. Java API. Pakkaukset. java\lang

Sisällys. 20. Javan omat luokat. Java API. Pakkaukset. java\lang Sisällys 20. Javan omat luokat Application Programming Interface (API). Pakkaukset. Merkkijonoluokka String. Math-luokka. Kääreluokat. 20.1 20.2 Java API Java-kielen Application Programming Interface (API)

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 16.2.2010 T-106.1208 Ohjelmoinnin perusteet Y 16.2.2010 1 / 41 Kännykkäpalautetteen antajia kaivataan edelleen! Ilmoittaudu mukaan lähettämällä ilmainen tekstiviesti

Lisätiedot

4.5 Kaksivaiheinen menetelmä simplex algoritmin alustukseen

4.5 Kaksivaiheinen menetelmä simplex algoritmin alustukseen 4.5 Kaksivaiheinen menetelmä simplex algoritmin alustukseen Käypä kantaratkaisu löytyy helposti, esimerkiksi tapauksessa Ax b, b 0 x 0 jolloin sen määräävät puutemuuttujat. Tällöin simplex-menetelmän alustus

Lisätiedot

2 Konekieli, aliohjelmat, keskeytykset

2 Konekieli, aliohjelmat, keskeytykset ITK145 Käyttöjärjestelmät, kesä 2005 Tenttitärppejä Tässä on lueteltu suurin piirtein kaikki vuosina 2003-2005 kurssin tenteissä kysytyt kysymykset, ja mukana on myös muutama uusi. Jokaisessa kysymyksessä

Lisätiedot

Paikkatiedon käsittely 6. Kyselyn käsittely

Paikkatiedon käsittely 6. Kyselyn käsittely HELSINGIN YLIOPISTO HELSINGFORS UNIVERSITET UNIVERSITY OF HELSINKI Paikkatiedon käsittely 6. Kyselyn käsittely Antti Leino antti.leino@cs.helsinki.fi 1.2.2007 Tietojenkäsittelytieteen laitos Kysely indeksin

Lisätiedot

SELECT-lauseen perusmuoto

SELECT-lauseen perusmuoto SQL: Tiedonhaku SELECT-lauseen perusmuoto SELECT FROM WHERE ; määrittää ne sarakkeet, joiden halutaan näkyvän kyselyn vastauksessa sisältää

Lisätiedot

811312A Tietorakenteet ja algoritmit Kertausta kurssin alkuosasta

811312A Tietorakenteet ja algoritmit Kertausta kurssin alkuosasta 811312A Tietorakenteet ja algoritmit 2016-2017 Kertausta kurssin alkuosasta II Algoritmien analyysi: oikeellisuus Algoritmin täydellinen oikeellisuus = Algoritmi päättyy ja tuottaa määritellyn tuloksen

Lisätiedot

Tietorakenteet, laskuharjoitus 10, ratkaisuja. 1. (a) Seuraava algoritmi tutkii, onko jokin luku taulukossa monta kertaa:

Tietorakenteet, laskuharjoitus 10, ratkaisuja. 1. (a) Seuraava algoritmi tutkii, onko jokin luku taulukossa monta kertaa: Tietorakenteet, laskuharjoitus 10, ratkaisuja 1. (a) Seuraava algoritmi tutkii, onko jokin luku taulukossa monta kertaa: SamaLuku(T ) 2 for i = 1 to T.length 1 3 if T [i] = = T [i + 1] 4 return True 5

Lisätiedot

UpdateIT 2010: Editorin käyttöohje

UpdateIT 2010: Editorin käyttöohje UpdateIT 2010: Editorin käyttöohje Käyttäjätuki: Suomen Golfpiste Oy Esterinportti 1 00240 HELSINKI Puhelin: (09) 1566 8800 Fax: (09) 1566 8801 E-mail: gp@golfpiste.com Sisällys Editorin käyttöohje...

Lisätiedot

etunimi, sukunimi ja opiskelijanumero ja näillä

etunimi, sukunimi ja opiskelijanumero ja näillä Sisällys 1. Algoritmi Algoritmin määritelmä. Aiheen pariin johdatteleva esimerkki. ja operaatiot (sijoitus, aritmetiikka ja vertailu). Algoritmista ohjelmaksi. 1.1 1.2 Algoritmin määritelmä Ohjelmointi

Lisätiedot

private TreeMap nimella; private TreeMap numerolla;

private TreeMap<String, Opiskelija> nimella; private TreeMap<String, Opiskelija> numerolla; Tietorakenteet, laskuharjoitus 7, ratkaisuja 1. Opiskelijarekisteri-luokka saadaan toteutetuksi käyttämällä kahta tasapainotettua binäärihakupuuta. Toisen binäärihakupuun avaimina pidetään opiskelijoiden

Lisätiedot

Harjoitustyö: virtuaalikone

Harjoitustyö: virtuaalikone Harjoitustyö: virtuaalikone Toteuta alla kuvattu virtuaalikone yksinkertaiselle olio-orientoituneelle skriptauskielelle. Paketissa on testaamista varten mukana kaksi lyhyttä ohjelmaa. Ohjeita Noudata ohjelman

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 16.3.2009 T-106.1208 Ohjelmoinnin perusteet Y 16.3.2009 1 / 40 Kertausta: tiedostosta lukeminen Aluksi käsiteltävä tiedosto pitää avata: tiedostomuuttuja = open("teksti.txt","r")

Lisätiedot

C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. Operaatioiden suoritusjärjestys

C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. Operaatioiden suoritusjärjestys Loogisia operaatioita - esimerkkejä Tänään on lämmin päivä ja perjantai Eilen satoi ja oli keskiviikko tai tänään on tiistai. On perjantai ja kello on yli 13 Ei ole tiistai tai ei sada. Ei pidä paikkaansa,

Lisätiedot

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset 815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 2 vastaukset Harjoituksen aiheena on BNF-merkinnän käyttö ja yhteys rekursiivisesti etenevään jäsentäjään. Tehtävä 1. Mitkä ilmaukset seuraava

Lisätiedot

811312A Tietorakenteet ja algoritmit 2015-2016. V Verkkojen algoritmeja Osa 2 : Kruskalin ja Dijkstran algoritmit

811312A Tietorakenteet ja algoritmit 2015-2016. V Verkkojen algoritmeja Osa 2 : Kruskalin ja Dijkstran algoritmit 811312A Tietorakenteet ja algoritmit 2015-2016 V Verkkojen algoritmeja Osa 2 : Kruskalin ja Dijkstran algoritmit Sisältö 1. Johdanto 2. Leveyshaku 3. Syvyyshaku 4. Kruskalin algoritmi 5. Dijkstran algoritmi

Lisätiedot

Pikalajittelu: valitaan ns. pivot-alkio esim. pivot = oikeanpuoleisin

Pikalajittelu: valitaan ns. pivot-alkio esim. pivot = oikeanpuoleisin Pikalajittelu: valitaan ns. pivot-alkio esim. pivot = oikeanpuoleisin jaetaan muut alkiot kahteen ryhmään: L: alkiot, jotka eivät suurempia kuin pivot G : alkiot, jotka suurempia kuin pivot 6 1 4 3 7 2

Lisätiedot

A274101 TIETORAKENTEET JA ALGORITMIT

A274101 TIETORAKENTEET JA ALGORITMIT A274101 TIETORAKENTEET JA ALGORITMIT PUURAKENTEET, BINÄÄRIPUU, TASAPAINOTETUT PUUT MIKÄ ON PUUTIETORAKENNE? Esim. Viereinen kuva esittää erästä puuta. Tietojenkäsittelytieteessä puut kasvavat alaspäin.

Lisätiedot

LAUSEKKEET JA NIIDEN MUUNTAMINEN

LAUSEKKEET JA NIIDEN MUUNTAMINEN LAUSEKKEET JA NIIDEN MUUNTAMINEN 1 LUKULAUSEKKEITA Ratkaise seuraava tehtävä: Retkeilijät ajoivat kahden tunnin ajan polkupyörällä maantietä pitkin 16 km/h nopeudella, ja sitten vielä kävelivät metsäpolkua

Lisätiedot

A ja B pelaavat sarjan pelejä. Sarjan voittaja on se, joka ensin voittaa n peliä.

A ja B pelaavat sarjan pelejä. Sarjan voittaja on se, joka ensin voittaa n peliä. Esimerkki otteluvoiton todennäköisyys A ja B pelaavat sarjan pelejä. Sarjan voittaja on se, joka ensin voittaa n peliä. Yksittäisessä pelissä A voittaa todennäköisyydellä p ja B todennäköisyydellä q =

Lisätiedot

Johdatus lukuteoriaan Harjoitus 2 syksy 2008 Eemeli Blåsten. Ratkaisuehdotelma

Johdatus lukuteoriaan Harjoitus 2 syksy 2008 Eemeli Blåsten. Ratkaisuehdotelma Johdatus lukuteoriaan Harjoitus 2 syksy 2008 Eemeli Blåsten Ratkaisuehdotelma Tehtävä 1 1. Etsi lukujen 4655 ja 12075 suurin yhteinen tekijä ja lausu se kyseisten lukujen lineaarikombinaationa ilman laskimen

Lisätiedot

Graafit ja verkot. Joukko solmuja ja joukko järjestämättömiä solmupareja. eli haaroja. Joukko solmuja ja joukko järjestettyjä solmupareja eli kaaria

Graafit ja verkot. Joukko solmuja ja joukko järjestämättömiä solmupareja. eli haaroja. Joukko solmuja ja joukko järjestettyjä solmupareja eli kaaria Graafit ja verkot Suuntamaton graafi: eli haaroja Joukko solmuja ja joukko järjestämättömiä solmupareja Suunnattu graafi: Joukko solmuja ja joukko järjestettyjä solmupareja eli kaaria Haaran päätesolmut:

Lisätiedot

HYVÄKSILUETTUJEN SUORITUSTEN REKISTERÖIMINEN

HYVÄKSILUETTUJEN SUORITUSTEN REKISTERÖIMINEN 1 HYVÄKSILUETTUJEN SUORITUSTEN REKISTERÖIMINEN Valitse Opintojen rekisteröinti -valikosta Hyväksilukeminen. Voit valita Näytettävät opinnot -osiosta, mitkä opiskelijan suorituksista näkyvät aktiivisina

Lisätiedot

Merkitse yhtä puuta kirjaimella x ja kirjoita yhtälöksi. Mikä tulee vastaukseksi? 3x + 2x = 5x + =

Merkitse yhtä puuta kirjaimella x ja kirjoita yhtälöksi. Mikä tulee vastaukseksi? 3x + 2x = 5x + = Mikä X? Esimerkki: Merkitse yhtä puuta kirjaimella ja kirjoita yhtälöksi. Mikä tulee vastaukseksi? 3 + 2 = 5 + = 5 + = 1. Merkitse yhtä päärynää kirjaimella ja kirjoita yhtälöksi? Mikä tulee vastaukseksi?

Lisätiedot

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset 815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 6 Vastaukset Harjoituksen aiheena on funktionaalinen ohjelmointi Scheme- ja Haskell-kielillä. Voit suorittaa ohjelmat osoitteessa https://ideone.com/

Lisätiedot

Excel 2010 ja QlikView. Mihin ja milloin pivot:ia voi käyttää

Excel 2010 ja QlikView. Mihin ja milloin pivot:ia voi käyttää Excel 2010 ja QlikView 6.11.2012 Markku Könkkölä J Y / IT -palvelut Mihin ja milloin pivot:ia voi käyttää Datan pitää olla listamuotoinen ts. otsikkorivi ja sen alla tietorivit ilman tyhjiä välejä. Jokaisella

Lisätiedot

ABHELSINKI UNIVERSITY OF TECHNOLOGY

ABHELSINKI UNIVERSITY OF TECHNOLOGY Satunnaismuuttujat ja todennäköisyysjakaumat Mitä tänään? Jos satunnaisilmiötä halutaan mallintaa matemaattisesti, on ilmiön tulosvaihtoehdot kuvattava numeerisessa muodossa. Tämä tapahtuu liittämällä

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 17.2.2010 T-106.1208 Ohjelmoinnin perusteet Y 17.2.2010 1 / 41 Sanakirja Monissa sovelluksissa on tallennettava rakenteeseen avain arvo-pareja. Myöhemmin rakenteesta

Lisätiedot

Datatähti 2000: alkukilpailun ohjelmointitehtävä

Datatähti 2000: alkukilpailun ohjelmointitehtävä Datatähti 2000: alkukilpailun ohjelmointitehtävä 1 Lyhyt tehtävän kuvaus Tehtävänä on etsiä puurakenteen esiintymiä kirjaintaulukosta. Ohjelmasi saa syötteenä kirjaintaulukon ja puun, jonka jokaisessa

Lisätiedot

Ohjelmointi 1 Taulukot ja merkkijonot

Ohjelmointi 1 Taulukot ja merkkijonot Ohjelmointi 1 Taulukot ja merkkijonot Jussi Pohjolainen TAMK Tieto- ja viestintäteknologia Johdanto taulukkoon Jos ohjelmassa käytössä ainoastaan perinteisiä (yksinkertaisia) muuttujia, ohjelmien teko

Lisätiedot

Asko Ikävalko, k0201291 22.2.2004 TP02S-D. Ohjelmointi (C-kieli) Projektityö. Työn valvoja: Olli Hämäläinen

Asko Ikävalko, k0201291 22.2.2004 TP02S-D. Ohjelmointi (C-kieli) Projektityö. Työn valvoja: Olli Hämäläinen Asko Ikävalko, k0201291 22.2.2004 TP02S-D Ohjelmointi (C-kieli) Projektityö Työn valvoja: Olli Hämäläinen Asko Ikävalko LOPPURAPORTTI 1(11) Ratkaisun kuvaus Käytetyt tiedostot Tietuerakenteet Onnistuin

Lisätiedot

Sähköpostilla tulevien hinnastojen tallentaminen

Sähköpostilla tulevien hinnastojen tallentaminen Sivu 1/5 Sähköpostilla tulevien hinnastojen tallentaminen Yleistä Sähköposti on nykyään erittäin suosittu tapa viestiä sähköisesti. Tämä johtuu useistakin hyvistä puolista. Esim. sama viesti voidaan lähettää

Lisätiedot

Algoritmit 1. Luento 2 Ke Timo Männikkö

Algoritmit 1. Luento 2 Ke Timo Männikkö Algoritmit 1 Luento 2 Ke 11.1.2017 Timo Männikkö Luento 2 Algoritmin esitys Algoritmien analysointi Suoritusaika Asymptoottinen kertaluokka Peruskertaluokkia NP-täydelliset ongelmat Algoritmit 1 Kevät

Lisätiedot

1 Määrittelyjä ja aputuloksia

1 Määrittelyjä ja aputuloksia 1 Määrittelyjä ja aputuloksia 1.1 Supremum ja infimum Aluksi kerrataan pienimmän ylärajan (supremum) ja suurimman alarajan (infimum) perusominaisuuksia ja esitetään muutamia myöhemmissä todistuksissa tarvittavia

Lisätiedot

Sekalaiset tehtävät, 11. syyskuuta 2005, sivu 1 / 13. Tehtäviä

Sekalaiset tehtävät, 11. syyskuuta 2005, sivu 1 / 13. Tehtäviä Sekalaiset tehtävät, 11. syyskuuta 005, sivu 1 / 13 Tehtäviä Tehtävä 1. Johda toiseen asteen yhtälön ax + bx + c = 0, a 0 ratkaisukaava. Tehtävä. Määrittele joukon A R pienin yläraja sup A ja suurin alaraja

Lisätiedot

Alkuarvot ja tyyppimuunnokset (1/5) Alkuarvot ja tyyppimuunnokset (2/5) Alkuarvot ja tyyppimuunnokset (3/5)

Alkuarvot ja tyyppimuunnokset (1/5) Alkuarvot ja tyyppimuunnokset (2/5) Alkuarvot ja tyyppimuunnokset (3/5) Alkuarvot ja tyyppimuunnokset (1/5) Aiemmin olemme jo antaneet muuttujille alkuarvoja, esimerkiksi: int luku = 123; Alkuarvon on oltava muuttujan tietotyypin mukainen, esimerkiksi int-muuttujilla kokonaisluku,

Lisätiedot

Matematiikan tukikurssi

Matematiikan tukikurssi Matematiikan tukikurssi Kurssikerta 1 1 Matemaattisesta päättelystä Matemaattisen analyysin kurssin (kuten minkä tahansa matematiikan kurssin) seuraamista helpottaa huomattavasti, jos opiskelija ymmärtää

Lisätiedot

Käyttäjän käsikirja. LIB 500 ja LIB 510 v.4.0.2. 8.2. Releasettelutyökalu. 8.2.1. Yleistä. ,NNXQDMRNDLOPRLWWDDHWWlNRKGHRQSlLYLWHWWlYl

Käyttäjän käsikirja. LIB 500 ja LIB 510 v.4.0.2. 8.2. Releasettelutyökalu. 8.2.1. Yleistä. ,NNXQDMRNDLOPRLWWDDHWWlNRKGHRQSlLYLWHWWlYl 1MRS751368-RUM Käyttäjän käsikirja 8.1. Releyksikön valitseminen Releyksiköt esitetään asemakuvassa painikkeina. 8 $VHPDNXYDMRVVDQlN\\UHOH\NVLNN Jos kohteita tarvitsee päivittää, avataan ikkuna (Kuva 8.1.-2)

Lisätiedot

D B. Harvat hakemistot. Harvat hakemistot

D B. Harvat hakemistot. Harvat hakemistot Harvassa hakemistossa on ei ole hakemistomerkintöjä jokaista tietuetta kohden vaan yksi merkintä jotain isompaa kokonaisuutta esimerkiksi sivua tai sivujoukkoa (esim. saman uran sivut) kohti Harvan hakemiston

Lisätiedot

4.6 Kurssin palauttaminen

4.6 Kurssin palauttaminen 4.6 Kurssin palauttaminen Yleistä kurssin palauttamisesta Kurssipohjan tulee olla luotuna Moodleen ennen kuin sen päälle voi palauttaa varmuuskopion. Yleensä palauttaminen kannattaa tehdä siten, että entisen

Lisätiedot

KAISTANLEVEYDEN JA TEHON KÄYTÖN KANNALTA OPTIMAALINEN MODULAATIO TRELLISKOODATTU MODULAATIO (TCM)

KAISTANLEVEYDEN JA TEHON KÄYTÖN KANNALTA OPTIMAALINEN MODULAATIO TRELLISKOODATTU MODULAATIO (TCM) 1 KAISTANLEVEYDEN JA TEHON KÄYTÖN KANNALTA OPTIMAALINEN MODULAATIO TRELLISKOODATTU MODULAATIO (TCM) CPM & TCM-PERIAATTEET 2 Tehon ja kaistanleveyden säästöihin pyritään, mutta yleensä ne ovat ristiriitaisia

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 4.3.2009 T-106.1208 Ohjelmoinnin perusteet Y 4.3.2009 1 / 35 Tiedostot Tiedostojen käsittelyä tarvitaan esimerkiksi seuraavissa tilanteissa: Ohjelman käsittelemiä

Lisätiedot

Suvi Junes Tietohallinto / Opetusteknologiapalvelut 2012

Suvi Junes Tietohallinto / Opetusteknologiapalvelut 2012 Tiedostot Uudet ominaisuudet: - Ei Tiedostot-kohtaa alueen sisällä, vaan tiedostonvalitsin, jolla tiedostot tuodaan alueelle siihen kohtaan missä ne näytetään - Firefox-selaimella voi työpöydältä raahata

Lisätiedot

Tietorakenteet, laskuharjoitus 3, ratkaisuja

Tietorakenteet, laskuharjoitus 3, ratkaisuja Tietorakenteet, laskuharjoitus 3, ratkaisuja 1. (a) Toistolauseen runko-osassa tehdään yksi laskuoperaatio, runko on siis vakioaikainen. Jos syöte on n, suoritetaan runko n kertaa, eli aikavaativuus kokonaisuudessaan

Lisätiedot

Yleistä. Nyt käsitellään vain taulukko (array), joka on saman tyyppisten muuttujien eli alkioiden (element) kokoelma.

Yleistä. Nyt käsitellään vain taulukko (array), joka on saman tyyppisten muuttujien eli alkioiden (element) kokoelma. 2. Taulukot 2.1 Sisältö Yleistä. Esittely ja luominen. Alkioiden käsittely. Kaksiulotteinen taulukko. Taulukko operaation parametrina. Taulukko ja HelloWorld-ohjelma. Taulukko paluuarvona. 2.2 Yleistä

Lisätiedot

Vaihtoehtoinen tapa määritellä funktioita f : N R on

Vaihtoehtoinen tapa määritellä funktioita f : N R on Rekursio Funktio f : N R määritellään yleensä antamalla lauseke funktion arvolle f (n). Vaihtoehtoinen tapa määritellä funktioita f : N R on käyttää rekursiota: 1 (Alkuarvot) Ilmoitetaan funktion arvot

Lisätiedot

Algoritmit 1. Luento 4 Ke Timo Männikkö

Algoritmit 1. Luento 4 Ke Timo Männikkö Algoritmit 1 Luento 4 Ke 18.1.2017 Timo Männikkö Luento 4 Tietorakenteet Pino Pinon toteutus Jono Jonon toteutus Lista Listaoperaatiot Algoritmit 1 Kevät 2017 Luento 4 Ke 18.1.2017 2/29 Pino Pino, stack,

Lisätiedot