811312A Tietorakenteet ja algoritmit, , Harjoitus 3, Ratkaisu

Samankaltaiset tiedostot
811312A Tietorakenteet ja algoritmit Kertausta kurssin alkuosasta

4 Tehokkuus ja algoritmien suunnittelu

811312A Tietorakenteet ja algoritmit Kertausta kurssin alkuosasta

811312A Tietorakenteet ja algoritmit I Johdanto

f(n) = Ω(g(n)) jos ja vain jos g(n) = O(f(n))

811312A Tietorakenteet ja algoritmit, , Harjoitus 4, Ratkaisu

811312A Tietorakenteet ja algoritmit , Harjoitus 2 ratkaisu

Algoritmit 1. Luento 1 Ti Timo Männikkö

A TIETORAKENTEET JA ALGORITMIT

58131 Tietorakenteet ja algoritmit (syksy 2015)

811312A Tietorakenteet ja algoritmit III Lajittelualgoritmeista

Algoritmit 1. Luento 3 Ti Timo Männikkö

811312A Tietorakenteet ja algoritmit, , Harjoitus 7, ratkaisu

Algoritmit 2. Luento 2 To Timo Männikkö

Algoritmit 1. Luento 2 Ke Timo Männikkö

Algoritmit 1. Luento 10 Ke Timo Männikkö

Algoritmit 2. Luento 2 Ke Timo Männikkö

1 Erilaisia tapoja järjestää

Algoritmit 1. Luento 11 Ti Timo Männikkö

Tietorakenteet ja algoritmit - syksy

Tietorakenteet ja algoritmit Johdanto Lauri Malmi / Ari Korhonen

811312A Tietorakenteet ja algoritmit, , Harjoitus 2, Ratkaisu

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

Tietorakenteet, laskuharjoitus 2,

Algoritmit 2. Luento 14 Ke Timo Männikkö

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

ALGORITMIT 1 DEMOVASTAUKSET KEVÄT 2012

Algoritmit 2. Luento 1 Ti Timo Männikkö

9 Erilaisia tapoja järjestää

Algoritmit 1. Demot Timo Männikkö

A TIETORAKENTEET JA ALGORITMIT

Algoritmit 1. Demot Timo Männikkö

Algoritmit 2. Luento 13 Ti Timo Männikkö

1.4 Funktioiden kertaluokat

Tietorakenteet, laskuharjoitus 3, ratkaisuja

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

Algoritmit 2. Luento 7 Ti Timo Männikkö

811120P Diskreetit rakenteet

useampi ns. avain (tai vertailuavain) esim. opiskelijaa kuvaavassa alkiossa vaikkapa opintopistemäärä tai opiskelijanumero

Esimerkkejä vaativuusluokista

Tutkimusmenetelmät-kurssi, s-2004

5 Kertaluokkamerkinnät

Nopea kertolasku, Karatsuban algoritmi

Algoritmit 2. Luento 3 Ti Timo Männikkö

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

Scifest-loppuraportti Jani Hovi kortin temppu

811120P Diskreetit rakenteet

Sovellettu todennäköisyyslaskenta B

811312A Tietorakenteet ja algoritmit II Algoritmien analyysi

Algoritmit 1. Demot Timo Männikkö

811120P Diskreetit rakenteet

Tarkennamme geneeristä painamiskorotusalgoritmia

Esimerkkejä polynomisista ja ei-polynomisista ongelmista

Kirjoita oma versio funktioista strcpy ja strcat, jotka saavat parametrinaan kaksi merkkiosoitinta.

TOD.NÄK JA TILASTOT, MAA10 Kombinaatio, k-kombinaatio

Zeon PDF Driver Trial

CUDA. Moniydinohjelmointi Mikko Honkonen

TAMPEREEN TEKNILLINEN YLIOPISTO

Algoritmit 2. Luento 3 Ti Timo Männikkö

Toinen harjoitustyö. ASCII-grafiikkaa

TAMPEREEN TEKNILLINEN YLIOPISTO Digitaali- ja tietokonetekniikan laitos. Harjoitustyö 4: Cache, osa 2

Algoritmit 1. Luento 10 Ke Timo Männikkö

Yhtälöryhmä matriisimuodossa. MS-A0007 Matriisilaskenta. Tarkastellaan esimerkkinä lineaarista yhtälöparia. 2x1 x 2 = 1 x 1 + x 2 = 5.

dx=2&uilang=fi&lang=fi&lvv=2015

811312A Tietorakenteet ja algoritmit, VI Algoritmien suunnitteluparadigmoja

Toinen harjoitustyö. ASCII-grafiikkaa 2017

811312A Tietorakenteet ja algoritmit, , Harjoitus 3, Ratkaisu

Algoritmit 2. Demot Timo Männikkö

MS-A0004/MS-A0006 Matriisilaskenta Laskuharjoitus 6 / vko 42

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset

Tietorakenteet ja algoritmit syksy Laskuharjoitus 1

811312A Tietorakenteet ja algoritmit, , Harjoitus 6, Ratkaisu

811312A Tietorakenteet ja algoritmit II Perustietorakenteet

Osa 1: Todennäköisyys ja sen laskusäännöt. Klassinen todennäköisyys ja kombinatoriikka

Ohjelmoinnin perusteet, syksy 2006

3 Lajittelualgoritmeista

811312A Tietorakenteet ja algoritmit , Harjoitus 1 ratkaisu

815338A Ohjelmointikielten periaatteet Harjoitus 7 Vastaukset

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset

Algoritmit 2. Demot Timo Männikkö

Algoritmit 2. Luento 13 Ti Timo Männikkö

1 + b t (i, j). Olkoon b t (i, j) todennäköisyys, että B t (i, j) = 1. Siis operaation access(j) odotusarvoinen kustannus ajanhetkellä t olisi.

7.4 Sormenjälkitekniikka

11. Javan toistorakenteet 11.1

811312A Tietorakenteet ja algoritmit, , Harjoitus 5, Ratkaisu

Ohjelmointi 1 / 2009 syksy Tentti / 18.12

Harjoitus 3 (viikko 39)

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

Numeeriset menetelmät

Matriisit ovat matlabin perustietotyyppejä. Yksinkertaisimmillaan voimme esitellä ja tallentaa 1x1 vektorin seuraavasti: >> a = 9.81 a = 9.

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

A-Osio. Ei saa käyttää laskinta, maksimissaan tunti aikaa. Valitse seuraavista kolmesta tehtävästä kaksi, joihin vastaat:

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

Todennäköisyyslaskenta I, kesä 2017 Helsingin yliopisto/avoin Yliopisto Harjoitus 1, ratkaisuehdotukset

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

8. Lajittelu, joukot ja valinta

Kirjoita ohjelma jossa luetaan kokonaislukuja taulukkoon (saat itse päättää taulun koon, kunhan koko on vähintään 10)

Algoritmianalyysin perusteet

Lyhyt, kevät 2016 Osa A

Tietorakenteet, laskuharjoitus 7, ratkaisuja

Transkriptio:

811312A Tietorakenteet ja algoritmit, 2018-2019, Harjoitus 3, Ratkaisu Harjoituksessa käsitellään algoritmien aikakompleksisuutta. Tehtävä 3.1 Kuvitteelliset algoritmit A ja B lajittelevat syötteenään saamat lukutaulukot. Algoritmi A käyttää 32 nlg(n) operaatiota ja algoritmi B käyttää 3 n 2 operaatiota, kun taulukon koko on n. Arvioi, minkä kokoisten taulukoiden lajitteluun kannattaa käyttää algoritmia A ja minkä kokoisten taulukoiden lajitteluun kannattaa käyttää algoritmia B. Ratkaisu. Algoritmin A suoritusaika kasvaa hitaammin kuin algoritmin B, koska lg(n) kasvaa hitaammin kuin n. Näin ollen algoritmi A pääsee lopulta voitolle, kun edetään riittävän suuriin n:n arvoihin. Etsitään sellainen taulukon koon arvo n, jossa algoritmi A ohittaa B:n suoritusnopeudessa. Kurssin merkinnöissä lg tarkoittaa 2-kantaista logaritmia, joten lg(2 k )= k. Merkitään operaatioiden määriä taulukoituna, kun n saa arvoikseen luvun 2 potensseja. k n=2 k A: 32*n*lg(n) B: 3*n 2 = 3*n*n ----------------------------------------------------------------- 4 16 32*16*4 = 2048 3*16*16 = 768 5 32 32*32*5 = 5120 3*32*32 = 3072 6 64 32*64*6 = 12288 3*64*64 = 12288 7 128 32*128*7= 28672 3*128*128 = 49152 jne. Kun n = 2 6 = 64, algoritmit suorittavat yhtä monta operaatiota. Tätä pienemmille taulukoille kannattaa käyttää algoritmia B ja suuremmille algoritmia A. Riittävän suurilla aineiston koon arvoilla n kompleksisuusluokan (nlg(n)) algoritmi tulee nopeammaksi kuin luokan (n 2 ) algoritmi, olivatpa vakiokertoimet mitä tahansa. Tehtävä 3.2 Lataa koneellesi (linkki alempana) ohjelmatiedosto h3_t2.cpp. Käännä ohjelma ja suorita se (voi tehdä luokassa esimerkiksi CodeBlocksilla tai kääntämällä komentoriviltä). Komentoriviltä käännetään antamalla syöte g++ h3_t2.cpp o t2.exe (Windowsissa) tai g++ h3_t2.cpp o t2 (Linuxissa). Ohjelmassa voidaan valita suoritukseen jokin kolmesta algoritmista (A, B ja C) halutulla syötteen koolla. Tee ohjelman avulla seuraavaa: a) Taulukoi algoritmin A suoritukseen kuluneita aikoja, kun syötteen koko vaihtelee välillä 500 20 000. Pyri arvaamaan mikä on suoritusaika, kun syötteen koko on 50 000. Tarkista arvauksesi suorittamalla ohjelma. b) Taulukoi algoritmin B suoritukseen kuluneita aikoja, kun syötteen koko vaihtelee välillä 25 200. Pyri arvaamaan mikä on suoritusaika, kun syötteen koko on 400. Tarkista arvauksesi suorittamalla ohjelma.

c) Taulukoi algoritmin C suoritukseen kuluneita aikoja, kun syötteen koko vaihtelee välillä 100 000 5 000 000. Pyri arvaamaan mikä on suoritusaika, kun syötteen koko on 80 000 000. Tarkista arvauksesi suorittamalla ohjelma. Arvioi vielä, mikä olisi algoritmien A ja B suoritusaika, kun syötteen koko on 1000 000. Ratkaisu. HUOM! Tässä tehtävässä ei kannata käyttää kääntäjän optimointiasetusta, koska algoritmit toistavat samaa operaatiota tietyn kaavan mukaan. Näin ollen kääntäjä saattaa optimoida koodia siten, että tulokset muuttuvat. HUOM2! Joissakin järjestelmissä C-ohjelmien suoritusajat eivät näy millisekunteina. Näin ollen ohjelman koodissa olisi syytä jakaa aika vielä vakiolla CLOCKS_PER_SEC, jolloin aika saadaan sekunneissa. Alla taulukoituina algoritmien suoritusaikoja kurssin vastuuhenkilön tietokoneella. Algoritmi A: Syötteen 500 1000 2000 5000 10000 20000 koko Aika (ms) 143 289 587 1508 2984 5954 Algoritmi B: Syötteen koko 25 50 100 200 Aika (ms) 110 422 1641 6594 Algoritmi C: Syötteen koko 100000 400000 1600000 5000000 Aika (ms) 218 454 922 1828 Algoritmi A:n suoritusaika näyttää kasvavan lineaarisesti: kun syötteen koko kaksinkertaistuu, myös suoritusaika kaksinkertaistuu ja kun syöte viisinkertaistuu, suoritusaika viisinkertaistuu. (Tällöin algoritmin suoritusaika on luokkaa (n), kun syötteen koko on n.) Näin ollen voidaan arvioida algoritmin suoritusajaksi syötteen koolla 50000 viisi kertaa suoritusaika syötteen koolla 10000, ts. 5*2984 = n. 14900 ms. Kun algoritmi suoritettiin, saatiin ajaksi 14938 ms, mikä vastaa hyvin arviota. Jos syötteen koko kasvatettaisiin 1000000:aan, niin suoritusaika satakertaistuisi verrattuna aikaan syötteen koolla 10000, joten voitaisiin olettaa suorituksen kestävän noin 100*2984 ms = n. 298 s = n. 5 min. Tämän voisi kärsivällinen testaaja vielä tarkistaa. Algoritmi B:n suoritusaika näyttää sen sijaan nelinkertaistuvan, kun syötteen koko kaksinkertaistuu. Näin ollen voidaan arvioida algoritmin suoritusajaksi syötteen koolla 400 neljä kertaa suoritusaika syötteen koolla 200, ts. 4*6594 = n. 26400 ms. Kun algoritmi suoritettiin, saatiin ajaksi 26563 ms, mikä vastaa hyvin arviota. Tällainen algoritmi on neliöllinen, ts. algoritmin suoritusaika on luokkaa ( n 2 ), kun syötteen koko

on n. Jos syötteen koko kasvatettaisiin 1000000:aan, niin suoritusajan suhde suoritusaikaan syötteen koolla 100 olisi (10000) 2, koska 1000000/100 = 10000. Siten voitaisiin olettaa suorituksen kestävän noin (10000) 2 *1641 ms = 164 100 000 s = n. 5.2 vuotta. Tätä ei liene enää tarkoituksenmukaista verifioida. Algoritmi C:n suoritusaika näyttää puolestaan kaksinkertaistuvan, kun syötteen koko nelinkertaistuu. Näin ollen voidaan arvioida algoritmin suoritusajaksi syötteen koolla 80 000 000 neljä kertaa suoritusaika syötteen koolla 5 000 000, ts. 4*1828 = n. 7300 ms, koska 80000000/5000000 = 16. Kun algoritmi suoritettiin, saatiin ajaksi 7391 ms, mikä vastaa hyvin arviota. Tässä tapauksessa algoritmin suoritus kasvaa kuten n, kun syötteen koko on n. (Algoritmin suoritusaika on siis luokkaa ( n), kun syötteen koko on n.) Tehtävä 3.3 Seuraava lisäyslajittelu on hyvä pienten taulukoiden lajittelualgoritmi. Algoritmin oikeellisuus on perusteltu luennoilla. Määritä (ja perustele) algoritmin kompleksisuusluokka. Riittää tarkastella ainoastaan huonointa tapausta. Syöte: Taulukko A[0,..,n-1], n >= 1 Tuloste: Taulukon luvut järjestyksessä A[0] <= <= A[n-1] LISAYS(A) 1. for j = 1 to n-1 2. k = A[j] 3. i = j-1 4. while i>=0 && A[i]>k 5. A[i+1] = A[i] 6. i = i-1 7. A[i+1] = k 8. return Ratkaisu. Rivejä 1-3 suoritetaan n-1 kertaa, samoin riviä 7. Jos taulukko on käänteisessä järjestyksessä (huonoin tapaus), while-silmukan rivejä 5 ja 6 joudutaan suorittamaan jokaisella kierroksella j kertaa eli yhteensä 1+2+ + (n-1) = n(n-1)/2 kertaa. Riviä 4 suoritetaan joka kierroksella yhden kerran enemmän kuin sen sisällä olevia rivejä, joten huonoimmassa tapauksessa riviä 4 suoritetaan 2+3+ + (n-1) + n = n(n-1)/2 + n-1 kertaa. Siten suoritettavia rivejä tulee pahimmassa tapauksessa 4(n-1) + 2n(n-1)/2 + n(n-1)/2 + n-1 = 4n -4 +n 2 n + 1 +n 2 /2 - n/2 + n -1 = 3n 2 /2 + 7n/2-5. Huomataan, että lisäyslajittelun kompleksisuusluokka pahimmassa tapauksessa on 2 ( n ), sillä suurilla n:n arvoilla vaikuttavin termi on 3n 2 /2. Voidaan myös osoittaa, että keskimääräinen tapaus on samaa luokkaa.

Ohjelmointitehtävä Tehtävä 3.4. Ohjelmissa tarvitaan usein erilaisten objektien joukkojen satunnaista järjestämistä. Tällaista algoritmia sanotaan satunnaisen permutaation tuottamiseksi. Tarkastele seuraavaa algoritmia, jolla voidaan tuottaa lukujen 1,, n satunnaisen järjestyksen sisältävä kokonaislukutaulukko A[0,..,n-1]. Syöte: Luku n >= 1. Taulukko A[0,..,n-1]. Tulostus: Taulukossa A luvut 1..n satunnaisessa järjestyksessä. RANDPERM(n,A) 1. for i = 0 to n-1 // Taulukon alustus järjestykseen 1,2,..,n 2. A[i] = i+1 3. for i = 0 to n-1 4. x = satunnaisluku väliltä 0..i 5. vaihda A[i] ja A[x] 6. return Ohjelmoi algoritmi (joko C- tai Python-kielellä) ja mittaa suoritukseen kuluvaa aikaa kasvattaen taulukon kokoa. Minkä kokoisilla taulukoilla on käytännöllistä suorittaa algoritmia? Mikä on algoritmin aikakompleksisuusluokka, kun syötteen koon mitta on taulukon koko? Sovelletaan em. mainittua algoritmia. Korttipakassa on 52 korttia, jotka jakaantuvat neljään maahan (hertta, ruutu, risti, pata), joissa kaikissa on 13 korttia numeroituina 1,...,13. Pokerissa jaetaan kaikille pelaajille aluksi viisi korttia. Halutaan tietää, mikä on pelaajan todennäköisyys saada jaossa väri, eli kaikki kortit samaa maata. Tätä voidaan arvioida simuloimalla: Mallinna pakan kortteja luvuilla 1,...,52, tuota suuri määrä lukujen 1,,52 permutaatioita ja laske, kuinka monessa näistä ensimmäiset viisi lukua vastaavat saman maan kortteja. Tämän lukumäärän suhde tuotettujen permutaatioiden lukumäärään arvioi haluttua todennäköisyyttä. (Laskettu todennäköisyys on n. 0.00198) Ratkaisu. Esimerkkiratkaisut on linkitetty alle. Ohjelman valikosta voidaan valita, mitataanko satunnaispermutaation tuottamisaikaa vai simuloidaanko värin saamisen todennäköisyyttä. Permutaatioalgoritmi on selvästi aikakompleksisuudeltaan lineaarinen (luokkaa Θ(n), kun taulukon koko on n), joten suoritusaikojen pitäisi kasvaa suorassa suhteessa syötteen kokoon. Testitietokoneella saatiin satunnaispermutaation tuottamisen Pythontoteutukselle seuraavat ajat (sekunneissa) vaihtelevan kokoisilla taulukoilla: Taulukon koko 100 000 400 000 800 000 1 000 000 Aika (s) 0.24 0.98 1.99 2.45 Taulukosta nähdään, että Python-ohjelmaa voidaan kohtuudella käyttää tuottamaan vielä miljoonan alkion permutaatioita, ellei sen tarvitse tapahtua reaaliaikaisesti. C-ohjelmat ovat käännettyinä yleisesti nopeampia kuin Python-ohjelmat. C-kielinen toteutus suoriutui seuraavasti: Taulukon koko 1 000 000 5 000 000 10 000 000 20 000 000 Aika (s) 0.069 0.53 1.16 2.57 Huomataan, että C-ohjelma tuottaa noin 20 kertaa pitemmän permutaation kuin Python vastaavassa ajassa.

Kun arvioidaan simuloimalla värin todennäköisyyttä, havaitaan että ohjelman tuottama todennäköisyys on hyvin lähellä teoreettisesti laskettua todennäköisyyttä, kun jakojen lukumäärä lähestyy 100 000:a. C-ohjelmalla voidaan samassa ajassa tuottaa lähes 50-kertainen määrä jakoja kuin Python-ohjelmalla.