811312A Tietorakenteet ja algoritmit, 2014-2015, Harjoitus 7, ratkaisu



Samankaltaiset tiedostot
811312A Tietorakenteet ja algoritmit, VI Algoritmien suunnitteluparadigmoja

811312A Tietorakenteet ja algoritmit , Harjoitus 2 ratkaisu

811312A Tietorakenteet ja algoritmit Kertausta kurssin alkuosasta

811312A Tietorakenteet ja algoritmit Kertausta kurssin alkuosasta

811312A Tietorakenteet ja algoritmit, , Harjoitus 5, Ratkaisu

Algoritmit 2. Luento 2 To Timo Männikkö

Algoritmit 1. Luento 12 Ti Timo Männikkö

811312A Tietorakenteet ja algoritmit III Lajittelualgoritmeista

Algoritmit 2. Luento 9 Ti Timo Männikkö

Algoritmit 1. Luento 12 Ke Timo Männikkö

811312A Tietorakenteet ja algoritmit V Hash-taulukot ja binääriset etsintäpuut

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

Hakupuut. tässä luvussa tarkastelemme puita tiedon tallennusrakenteina

Tietorakenteet, laskuharjoitus 7, ratkaisuja

Luku 8. Aluekyselyt. 8.1 Summataulukko

Algoritmit 2. Luento 2 Ke Timo Männikkö

811312A Tietorakenteet ja algoritmit, , Harjoitus 5, Ratkaisu

Tietorakenteet ja algoritmit - syksy

Algoritmit 2. Luento 7 Ti Timo Männikkö

58131 Tietorakenteet ja algoritmit (kevät 2014) Uusinta- ja erilliskoe, , vastauksia

4. Joukkojen käsittely

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

Tietorakenteet ja algoritmit Johdanto Lauri Malmi / Ari Korhonen

Algoritmit 2. Luento 6 To Timo Männikkö

Algoritmit 2. Luento 10 To Timo Männikkö

Algoritmit 1. Luento 13 Ti Timo Männikkö

811312A Tietorakenteet ja algoritmit, , Harjoitus 3, Ratkaisu

4 Tehokkuus ja algoritmien suunnittelu

Ohjelmoinnin peruskurssi Y1

Algoritmit 2. Luento 3 Ti Timo Männikkö

Algoritmit 2. Demot Timo Männikkö

Luku 6. Dynaaminen ohjelmointi. 6.1 Funktion muisti

Datatähti 2019 loppu

Algoritmit 1. Luento 13 Ma Timo Männikkö

Algoritmit 2. Luento 5 Ti Timo Männikkö

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

Tietorakenteet ja algoritmit

3. Hakupuut. B-puu on hakupuun laji, joka sopii mm. tietokantasovelluksiin, joissa rakenne on talletettu kiintolevylle eikä keskusmuistiin.

58131 Tietorakenteet ja algoritmit (syksy 2015) Toinen välikoe, malliratkaisut

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.

Algoritmit 2. Luento 3 Ti Timo Männikkö

811312A Tietorakenteet ja algoritmit V Verkkojen algoritmeja Osa 2 : Kruskalin ja Dijkstran algoritmit

Algoritmit 2. Luento 6 Ke Timo Männikkö

Algoritmit 2. Luento 13 Ti Timo Männikkö

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

(a) L on listan tunnussolmu, joten se ei voi olla null. Algoritmi lisäämiselle loppuun:

Algoritmit 2. Luento 4 To Timo Männikkö

811120P Diskreetit rakenteet

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

58131 Tietorakenteet ja algoritmit (kevät 2016) Ensimmäinen välikoe, malliratkaisut

Algoritmit 1. Luento 10 Ke Timo Männikkö

Algoritmit 1. Luento 8 Ke Timo Männikkö

Algoritmit 1. Luento 1 Ti Timo Männikkö

58131 Tietorakenteet ja algoritmit (syksy 2015)

Ohjelmoinnin perusteet Y Python

Koe ma 1.3 klo salissa A111, koeaika kuten tavallista 2h 30min

1.1 Tavallinen binäärihakupuu

Algoritmit 2. Demot Timo Männikkö

Algoritmit 2. Luento 13 Ti Timo Männikkö

Algoritmit 2. Luento 4 Ke Timo Männikkö

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

Algoritmit 1. Luento 7 Ti Timo Männikkö

Algoritmit 2. Luento 5 Ti Timo Männikkö

7.4 Sormenjälkitekniikka

Harjoitus 6 ( )

58131 Tietorakenteet Erilliskoe , ratkaisuja (Jyrki Kivinen)

Algoritmit 1. Demot Timo Männikkö

5. Hash-taulut ja binääriset etsintäpuut

Algoritmit 2. Luento 12 To Timo Männikkö

Algoritmit 1. Luento 11 Ti Timo Männikkö

10. Painotetut graafit

Koodausteoria, Kesä 2014

lähtokohta: kahden O(h) korkuisen keon yhdistäminen uudella juurella vie O(h) operaatiota vrt. RemoveMinElem() keossa

Datatähti 2000: alkukilpailun ohjelmointitehtävä

Miten käydä läpi puun alkiot (traversal)?

58131 Tietorakenteet (kevät 2009) Harjoitus 11, ratkaisuja (Topi Musto)

Uolevin reitti. Kuvaus. Syöte (stdin) Tuloste (stdout) Esimerkki 1. Esimerkki 2

Johdatus graafiteoriaan

Algoritmit 1. Luento 5 Ti Timo Männikkö

Lisää segmenttipuusta

1. Osoita, että joukon X osajoukoille A ja B on voimassa toinen ns. de Morganin laki (A B) = A B.

Algoritmit 2. Luento 9 Ti Timo Männikkö

Tehtävän V.1 ratkaisuehdotus Tietorakenteet, syksy 2003

ALGORITMIT 1 DEMOVASTAUKSET KEVÄT 2012

Ohjelmoinnin perusteet Y Python

811312A Tietorakenteet ja algoritmit I Johdanto

811312A Tietorakenteet ja algoritmit, , Harjoitus 4, Ratkaisu

Matematiikan johdantokurssi, syksy 2016 Harjoitus 11, ratkaisuista

Kerta 2. Kerta 2 Kerta 3 Kerta 4 Kerta Toteuta Pythonilla seuraava ohjelma:

Ohjelmoinnin perusteet Y Python

Algoritmien suunnittelu ja analyysi (kevät 2004) 1. välikoe, ratkaisuja

Lineaarinen optimointitehtävä

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset

Johdatus diskreettiin matematiikkaan Harjoitus 5, Ratkaise rekursioyhtälö

Algoritmit 1. Luento 10 Ke Timo Männikkö

TAMPEREEN TEKNILLINEN YLIOPISTO

Algoritmit 2. Luento 14 Ke Timo Männikkö

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

Matriisiteoria Harjoitus 1, kevät Olkoon. cos α sin α A(α) = . sin α cos α. Osoita, että A(α + β) = A(α)A(β). Mikä matriisi A(α)A( α) on?

Transkriptio:

832A Tietorakenteet ja algoritmit, 204-205, Harjoitus 7, ratkaisu Hajota ja hallitse-menetelmä: Tehtävä 7.. Muodosta hajota ja hallitse-menetelmää käyttäen algoritmi TULOSTA_PUU_LASKEVA, joka tulostaa binäärisen etsintäpuun kaikki avainkentät vähenevässä järjestyksessä. Algoritmi saa parametrinaan osoittimen puun juureen. Algoritmin pitäisi olla kompleksisuudeltaan lineaarinen puun solmujen lukumäärän n suhteen ( ( n) ). Osoita myös, että näin on! Ratkaisu. Olkoon puun juuren osoitin T. Määritellään algoritmi seuraavasti TULOSTA_PUU_LASKEVA(T). if T!=NIL 2. TULOSTA_PUU_LASKEVA(T.right) 3. tulosta (T.key) 4. TULOSTA_LASKEVA(T.left) 5. return Tässä siis hajotetaan puu vasempaan ja oikeaan alipuuhun, jotka käsitellään samalla algoritmilla erikseen. Jos puussa ei ole solmuja, tehdään vain yksi vertailu. Jos puussa on yksi solmu, on selvää että algoritmi vie vakioajan, jota merkitään kirjaimella a. Olkoon T(n) aika, jonka algoritmi vie, kun puussa on n solmua. Oletetaan, että puussa on N solmua (N >) ja että on olemassa sellainen vakio c, että T( n) c n aina, kun 0 < n < N. Lisäksi voidaan luonnollisesti olettaa, että c a. Jos puun vasemmassa alipuussa on k solmua, niin oikeassa alipuussa on N--k solmua. Siten Jos Jos k 0, T( N) a T( N ) a c ( N ) ( a c) c N c N k, T( N) a T( k) T( N k ) a c k c ( N k ) ( a c) c N c N Siis T( n) c n kaikilla luvun n arvoilla. Tietenkin jokainen solmu käsitellään, minkä vuoksi T n) n T( n) ( n. joten ) Tehtävä 7.2. Hae lukujoukon {7,2,3,8,,9,5,23,8,33,6,35,9,2,42} mediaani luennoissa esitetyllä hajota ja hallitse-tyyppisellä algoritmilla. Voit olettaa yksinkertaisuuden vuoksi, että ositusalgoritmi valitsee satunnaisesti sarana-alkioksi aina käsiteltävän välin ensimmäisen alkion. (, Ratkaisu. Luennoissa esitetty algoritmi ETSI hakee taulukon järjestyksessä k:nnen luvun ja se on seuraava: ETSI(A,p,q,k). x = OSITA(A,p,q) 2. if x == k 3. return A[x] 4. else if x > k 5. return ETSI(A,p,x-,k) 6. else 7. return ETSI(A,x+,q,k) OSITA(A,p,r). valitse x = A[m] satunnaisesti osasta A[p,..,r] 2. vaihda A[m] ja A[r] 3. i = p- 4. for j = p to r- 5. if A[j] == x 6. vaihda A[j] ja A[r] 7. if A[j] <= x 8. i = i+ 9. vaihda A[i] ja A[j] 0. vaihda A[i+] ja A[r]. return i+

Alla on esimerkkiajo algoritmista annetulle taulukolle. Lukuja on 5, joten etsitään järjestyksessä kahdeksatta. Taulukon indeksit alkavat nollasta, joten haetaan alkiota, joka tulee paikalle 7. Aluksi ositetaan koko taulukko satunnaisesti valitun alkion suhteen. Tämän oikea paikka taulukossa on 5, joten haetaan oikealta puolelta. Sitten sarana-alkioksi sattuu 8, joka puolestaan tulee paikalle 9. Näin ollen haetaan indeksien 6 ja 8 väliltä. Tältä väliltä sattuu vielä saranaksi alkio 2, minkä jälkeen löydetään kahdeksas alkio, joka on 5. Tulostuksesta nähdään käsiteltävä taulukon osa, sarana-alkio ja taulukon osa osituksen jälkeen. CALLING PARTITION(0,4) ARRAY BEFORE: 7 2 3 8 9 5 23 8 33 6 35 9 2 42 PIVOT: ARRAY AFTER: 7 2 3 8 9 5 23 8 33 6 35 9 2 42 RETURNING 5 CALLING PARTITION(6,4) ARRAY BEFORE: 5 23 8 33 6 35 9 2 42 PIVOT: 8 ARRAY AFTER: 5 6 2 8 23 35 9 42 33 RETURNING 9 CALLING PARTITION(6,8) ARRAY BEFORE: 5 6 2 PIVOT: 2 ARRAY AFTER: 2 6 5 RETURNING 6 CALLING PARTITION(7,8) ARRAY BEFORE: 6 5 PIVOT: 5 ARRAY AFTER: 5 6 RETURNING 7 THE 8. ELEMENT IS 5 Dynaaminen taulukointi: Tehtävä 7.3. Shakkilaudan vasemmassa yläkulmassa on nappula, joka voi siirtyä sijaintiruudustaan ainoastaan oikealle tai alas seuraavaan ruutuun. Kuinka monella tavalla nappula voi siirtyä 4*4-laudalla oikeaan alakulmaan? Ratkaise ongelma käyttämällä dynaamista taulukointia. Esimerkki: 2*2-laudalla on kaksi erilaista reittiä: ja 3*3-laudalla reittejä on 6 erilaista (kokeile!). Huomaa, että tiettyyn ruutuun johtavien reittien lukumäärä riippuu sen naapuriruutuihin johtavien reittien lukumäärästä. Osaatko yleistää ratkaisuasi n*n-laudalle? Ratkaisu. Merkitään laudan ruutuja koordinaattipareilla (i,j), missä i on sarakenumero ja j vaakarivin numero. Molemmat luvut voivat saada arvoja..4. Ongelmamme osaongelmiksi tulevat luonnollisesti reittien määrän laskemiset laudan eri ruutuihin. Merkitään reittien lukumäärää ruutuun (i,j) luvulla A(i,j). Huomataan, että nämä arvot voidaan tallettaa kaksiulotteiseen taulukkoon A[..4,..4]. Tutkitaan seuraavaksi, miten reittien lukumäärä voidaan laskea. Laudan yläreunan ja vasemman reunan ruutuihin voi päästä ainoastaan yhdellä tavalla, koska nappula liikkuu ainoastaan alas ja oikealle. Näin ollen A(i,) = A(,j) = kaikilla arvoilla i ja j.

Laudan ruutuun (i,j) voi päästä vain ruuduista (i-,j) ja (i,j-). Jos reittejä ruutuun (i-,j) on A(i-,j) kappaletta ja ruutuun (i,j-) niitä on A(i,j-) kappaletta, reittejä ruutuun (i,j) on A(i-,j)+ A(i,j-) kappaletta. Siis A(i,j) = A(i-,j)+ A(i,j-). Koska A(i,) = A(,j) =, niin kaikki arvot voidaan laskea ja täyttää taulukkoon. Näin löydettiin sopiva rekursio ratkaisulle. Ratkaisussa kannattaa käyttää dynaamista taulukointia eli varata taulukko ja laskea arvot siihen alhaalta lähtien: Alkutilanne: Lasketaan taulukoimalla A(2,2) = A(,2)+A(2,) = + = 2 A(3,2) = A(2,2)+A(3,) =2+=3 jne, jolloin lopulta saadaan taulukko 2 3 4 3 6 0 4 0 20 Siis reittejä on 20 erilaista.

Algoritmi yleistyy helposti n*n laudalle. Tässä tapauksessa täytetään vain n*n-taulukko. Algoritmi on seuraava: Syöte: Luku n>= Tulostus: Palauttaa tehtävässä kuvatun nappulan reittien lukumäärän n*nlaudalla vasemmasta yläkulmasta oikeaan alakulmaan. REITIT(n). varaa n*n-taulukko A[..n,..n] // Täytetään reunat ykkösillä 2. for i= to n do 3. A[i,] = 4. A[,i] = // Täytetään taulukko alhaalta ylös 5. for i= 2 to n do 6. for j=2 to n do 7. A[i,j] = A[i-,j]+A[i,j-] 8. return A[n,n] // Reittien lukumäärä taulukon viimeisessä paikassa Koska algoritmissa täytetään jokainen taulukon alkio täsmälleen kerran vakioaikaisella operaatiolla, 2 algoritmin kompleksisuusluokka on ( n ). Tehtävä 7.4. Olkoon A positiivisia kokonaislukuja sisältävä n*n-taulukko, jonka jokainen vaakarivi ja pystyrivi on kasvavassa järjestyksessä (ts. A, i A 2, i... A n, i ja A i, A i,2... A i, n i,..., n aina, kun ). Suunnittele algoritmi etsimään luku x taulukosta, kun syötteenä annetaan taulukko A ja etsittävä luku. Algoritmi palauttaa luvun esiintymispaikan taulukossa tai arvon NIL, ellei luku esiinny. Algoritmin tulee olla luvun n suhteen lineaariaikainen (luokkaa ( n) ). Ratkaisu. Yksi mahdollisuus olisi toteuttaa algoritmi käyttämällä hajota ja halllitse -tekniikkaa. Voitaisiin esimerkiksi valita taulukon keskimmäinen alkio (A[n/2,n/2]) ja päätellä sen ja luvun x suuruusjärjestyksestä, missä osassa taulukkoa x esiintyy. Sen jälkeen voitaisiin rekursiivisesti hakea lukua x taulukon osista. Näin ei saada kuitenkaan rajattua kerralla pois kuin neljäsosa taulukosta. Esimerkiksi, jos x < A[n/2,n/2], x ei voi esiintyä paikassa A[i,j], missä i>n/2 ja j>n/2. Rekursiivisesta algoritmista tulee melko tehoton. Kannattaakin lähteä liikkeelle taulukon vasemmasta alakulmasta (A[,n]) ja verrata lukuun x. Nyt saadaan, ellei x löydy tästä paikasta, suljettua pois joko ensimmäinen pystyrivi (jos x>a[,n]) tai alin vaakarivi (jos x<a[,n]). Ensimmäisessä tapauksessa voidaan siis seuraavaksi tutkia paikka A[2,n] ja toisessa tapauksessa A[,n-]. Näin etenemällä löydetään x tai viimeistään 2n askeleen kuluttua päädytään taulukon reunalle ja voidaan todeta, että x ei esiinny taulukossa. Siis algoritmi on lineaariaikainen luvun n suhteen. Alla on algoritmi tarkemmin:

Syöte: Kokonaislukutaulukko A[..n,..n], n>= ja haettava luku x. Taulukossa A on A[,i] <= A[2,i]... <= A[n,i] ja A[i,] <= A[i,2]... <= A[i,n] aina, kun i=,...,n Tulostus: Palauttaa luvun x paikan taulukossa A tai arvon NIL, ellei x esiinny siinä. ETSI_LUKU(A,x). cur_x = 2. cur_y = n 3. while cur_x <= n && cur_y >= 4. if x == A[cur_x,cur_y] 5. return [cur_x,cur_y] // Luku löytyi 6. else if x > A[cur_x,cur_y] 7. cur_x = cur_x+ 8. else 9. cur_y = cur_y- 0. return NIL // Luku ei ollut taulukossa Ahneet algoritmit: Tehtävä 7.5 Tietokoneen kovalevyn tallennuskapasiteetti on D megatavua ja sille halutaan tallentaa tiedostot P, P 2,, P n. Tiedoston P i koko on s i megatavua. Huomataan, että kaikki tiedostot eivät mahdu levylle, koska s + s 2 + + s n > D. Tarkastele seuraavien ahneiden algoritmien oikeellisuutta: a) Halutaan tallentaa mahdollisimman monta tiedostoa. Valitaan strategiaksi tallentaa tiedostoja pienimmästä suurimpaan kokojärjestyksessä, kunnes levylle ei mahdu enää tiedostoja. b) Halutaan käyttää mahdollisimman suuri osa levyn tallennustilasta. Tällä kerralla tallennetaan tiedostoja suurimmasta pienimpään, kunnes mikään tiedosto ei enää mahdu levylle. Jos algoritmi on mielestäsi oikea, osoita se. Jos algoritmi ei ole oikea, keksi vastaesimerkki. Ratkaisu. a) Oletetaan, että tiedostot ovat kokojärjestyksessä s s 2 s n Tällöin on etsittävä mahdollisimman monen luvun joukko niin, että lukujen summa on korkeintaan D. Ahneella menetelmällä saatu ratkaisu on täten (s, s 2,, s k) jollakin arvolla k ja s + s 2 + + s k+ > D. Olkoon nyt (s i, s i2,, s im) ratkaisu, jossa luvut ovat kokojärjestyksessä ja jossa on enemmän lukuja kuin ahneella menetelmällä saadussa ratkaisussa. Tällöin s im on kooltaan vähintään yhtä suuri kuin s k. Lisäksi jokin ahneen menetelmän luvuista s j puuttuu uudesta ratkaisusta, muutenhan ahne menetelmä voisi laajentaa ratkaisua. Uudessa ratkaisussa voidaan siten korvata s im luvulla s j. Etenemällä näin huomataan, että uuden ratkaisun lukuja voidaan korvata ahneen menetelmän luvuilla kunnes kaikki luvut (s, s 2,, s k) esiintyvät siinä. Mutta näiden lisäksi ei muita lukuja voi esiintyä. Siten kohdan a algoritmi on korrekti. b) Tällä kertaa annettu ahne ratkaisu on virheellinen. Olkoot tiedostojen koot megatavuissa 2,D-2 ja D-. Annetulla algoritmilla valittaisiin ensin suurin tiedosto, minkä jälkeen muita tiedostoja ei enää mahdu. Tallennustilaa jää megatavu käyttämättä. Sen sijaan valitsemalla kaksi pienempää tiedostoa saadaan levytila täyteen. Tehtävä 7.6 Määritä optimaalinen Huffmanin koodi seuraavalle aakkosten a, b, c, d, e, f frekvenssijonolle: a:34, b:2, c:22, d:8, e:9, f:5 (yhteensä 34+2+22+8+9+5 = 00 merkkiä). Kuinka monta bittiä säästyy verrattuna siihen, että jokainen aakkonen esitetään kolmella bitillä? Ratkaisu. Muodostetaan ensin juuresta koostuvat puut ja lajitellaan ne. Tämän jälkeen yhdistetään aina kaksi juuriarvoltaan pienintä puuta uudeksi puuksi, jonka juuriarvo on yhdistettyjen puiden juuriarvojen summa. Lopulta päädytään yhteen puuhun, joka esittää valmista koodia:

VAIHE I VAIHE II VAIHE III b:2 d:8 c:22 a:34 b:2 4 d:8 c:22 a:34 d:8 c:22 26 a:34 b:2 4 VAIHE IV 26 a:34 40 b:2 4 d:8 c:22 VAIHE V 40 d:8 c:22 60 26 a:34 b:2 4 VAIHE VI: Valmis koodi 00 40 d:8 c:22 60 26 a:34 b:2 4 Siis saatiin koodi: Merkki a b c d e f Koodi 00 0 00 00 Lasketaan, paljonko tilaa säästyy verrattuna kolmen bitin pakkaukseen: Merkki a b c d e f Prosenttiosuus 34 2 22 8 9 5 Jos tiedostossa olisi 00 merkkiä, kuluisi 34*2+2*3+2*22+2*8+4*9+4*5 = 68+36+44+36+36+20 = 240 bittiä. Kolmella bitillä koodaaminen veisi 300 bittiä. Näin ollen Huffmanin koodi vie tilaa 80% kolmen bitin koodauksen tallennustilasta. Säästö on 20%.