Tietorakenteet ja algoritmit Kertaus Ari Korhonen 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 1
Presemosta: 12. Kertaus» Mitkä tekijät, miten ja miksi vaiku1avat algoritmien nopeuteen» Rekursiohistoriapuut ja yleistä verkoista» luentotehtävän 1, 2 ja 3 kysymykset» Rekursioyhtälöiden ratkaiseminen» Onko olemassa suomenkielistä sanastoa? 17. ja 24.11.2015 Tietorakenteet ja algoritmit - syksy 2015 2
Suoritusaikaan vaiku1avia tekijöitä Vakiotekijöitä (käytännössä) SuoriEmen nopeus ja tyyppi, ohjelmoinfkieli (tulka1ava, käänne1ävä), kääntäjä, jne. Suurempi merkitys on valitulla!etorakenteella (esim. haku järjestetystä vs. järjestämä1ömästä taulukosta) valitulla algoritmilla (esim. lisäysjärjestäminen vs. lomitusjärjestäminen) muisfn määrällä (voidaanko laskenta tehdä keskusmuisfssa vs. ulkoisessa muisfssa) 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 3
Rekursiohistoriapuut ja rekursioyhtälöiden ratkaiseminen Rekursio Rekursion neljä kultaista sääntöä Rekursiohistoriapuu, rekursiopuu Rekursioyhtälöiden ratkaiseminen 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 4
REKURSIO Rekursiivinen ohjelma Kutsuu itseään Rekursiivinen rakenne Rakenne sisältyy itseensä Rekursiivinen funktio On määritelty itsensä avulla Esim. Fibonacci-luvut: X(i) = X(i-1) + X(i-2), X(0) = X(1) = 1 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 5
Rekursio ei voi jatkua loputtomiin Täytyy löytyä päätösehto jonka toteutuminen lopettaa rekursion Esim. Kertoma: Rekursio: N! = N(N-1)! Päätösehto: 0! = 1 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 6
Rekursion neljä kultaista sääntöä: 1. Perustapaukset (ratkaistavissa ilman rekursiota) 2. Edistyminen (liikutaan perustapausta kohti) 3. Oletus (kaikki rekursiiviset kutsut toimivat) 4. Vältä turhaa työtä (jokainen tapaus ratkaistaan vain kerran) 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 7
Esim. Kertoma rekursiivisena: int factorial(int n) /* n: askeltaja */ { if (n==0) return 1; else return factorial(n-1)*n; } Esim. Kertoma ei-rekursiivisena: int factorial(int n) /* n: kiintoarvo */ { int i,fact; fact = 1; /* fact: kokooja */ for (i=2; i<=n; i++) /* i: askeltaja */ fact = fact*i; return fact; } 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 8
Lähde: Ohjelmointi 1 (Scala MOOC, luku 11) 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 9
Esim. Fibonacci-luvut: int fibonacci(int n) { if (n<=1) return 1; else return fibonacci(n-1)+fibonacci(n-2); } F5 F6 F4 {Rikkoo neljättä sääntöä} F4 F3 F3 F2 Parempi toteuttaa eirekursiivisena (koostamalla) Mutta: voitaisiin muuntaa lineaarisessa ajassa toimivaksi esim. taulukoinnilla! F1 F0 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 10 F2 F3 F2 F2 F1 F2 F1 F1 F0 F1 F0 F1 F1 F0 F1 F0
Lähde: Ohjelmointi 1 (Scala MOOC, luku 11) 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 11
Rekursiohistoriapuu Puurakenne, jossa solmu jokaista rekursiokutsua kohti Solmut aktivoituvat ns. esijärjestyksessä (ks. puiden läpikäynti) Ensimmäistä kutsua vastaa puun juuri Pinokehys aktiivinen, kunnes kaikki alipuut on käyty läpi Pinokehys poistuu, kun rekursio palaa solmusta Esim. Fibonaccin luvut: int fibonacci(int n) { if (n<=1) return 1; else return fibonacci(n-1)+fibonacci(n-2); } 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 12
https://youtu.be/azfhbetdbn8 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 13
1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 14
Rekursiohistoriapuu Puurakenne, jossa solmu jokaista rekursiokutsua kohti Solmut aktivoituvat ns. esijärjestyksessä (ks. puiden läpikäynti) Ensimmäistä kutsua vastaa puun juuri Pinokehys aktiivinen, kunnes kaikki alipuut on käyty läpi Pinokehys poistuu, kun rekursio palaa solmusta Esim. Fibonaccin luvut: int fibonacci(int n) { if (n<=1) return 1; else return fibonacci(n-1)+fibonacci(n-2); } 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 15
Rekursiohistoriapuu Esim. hanoi(3, 1, 2, 3) void hanoi(int N, int mista, int minne, int via) { if (N==1) printf( Siirrä rengas tapista %d tappiin %d kiitos\n, mista, minne); else { hanoi(n-1, mista, via, minne); hanoi(1, mista, minne, via); // printf hanoi(n-1, via, minne, mista); } } h(3,1,2,3) h(2,1,3,2) h(1,1,2,3) h(2,3,2,1) h(1,1,2,3) h(1,1,3,2) h(1,2,3,1) h(1,3,1,2) h(1,3,2,1) h(1,1,2,3) 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 16
Rekursioyhtälöt Edellä olisi yhtä hyvin voitu merkitä vrt. s 1 = 1, s N = 2 N - 1 S(1) = 1, S(2) = 3, S(3) = 7 ja S(N) = 2 N 1 tai T(1) = 1, T(N) = 2 N 1 Algoritmianalyysissä useimmiten algoritmin aikakompleksisuu1a merkitään T(N):llä Lisäksi haetaan suuruusluokkaa, eli esim. T(N) = O(2 N ) 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 17
5.9 Rekursioyhtälöt Mentaalisen mallin muodostuminen (muna-kana-ongelma) 1. Rekursiohistoriapuut, laskennan etenemisen sisäistäminen 2. Laskennan vaativuuden erottaminen itse laskennen lopputuloksesta 3. Valikoitu arvaus laskennan vaativuudelle 4. Yhteys induktiotodistukseen 5. Rekursioyhtälö mentaalisen mallin ulkoistamisen välineenä Rekursioyhtälöiden ratkaisumenetelmiä (todistus) Aritmeettiset ja geometriset sarjakehitelmät Parametrien muunnokset Lausekkeen manipulointi Näiden yhdistely Master Theorem (Cormen) Induktiotodistus (e-book) 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 18
Esimerkki: luentotehtävä T(n) = 2T(n/2) + 1, T(1) = 1 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 19
Esimerkki: luentotehtävä T(n) = 2T(n/2) + 1, T(1) = 1 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 20
Esim 1. Linkitetyn listan läpikäynti silmukassa, poista joka kierroksella yksi alkio (ks. aritmeettinen sarja): T(N) = T(N-1) + N, T(1) =1 N T(N) = k = N (N + 1) / 2 k=1 T(N) on noin N 2 / 2 = O(N 2 ) T(N-1) = T((N-1)-1) + (N-1) = T(N-2) + N - 1 T(N-2) = T((N-2)-1) + (N-2) = T(N-3) + N - 2 T(N-k) = T((N-k)-1) + (N-k) = T(N-k-1) + N - k 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 21
Esim 2. Binäärihaku, puolita aineisto vakioajassa: T(N) = T(N/2) + 1, T(1) =1 N = 2 k, k = log 2 N (parametrin muunnos) T(2 k ) = T(2 k-1 ) + 1 = T(2 k-2 ) + 1 + 1 = T(2 0 ) + k = k +1 T(N) = O(k) = O(log N) Esim 3. Quick select, puolita aineisto lineaarisessa ajassa (geometrinen sarja): T(N) = T(N/2) + N, T(1) = 1 T(N) = N + N/2 + N/4 + N/8 +... = 2N = O(N) 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 22
Esim 4. Hajoita ja hallitse : Jaa aineisto kahteen osaan lineaarisessa ajassa, käsittele molemmat puolet rekursiivisesti T(N) = 2T(N/2) + N, T(1) = 1 N = 2 k, k = log 2 N T(2 k ) = 2T(2 k-1 ) + 2 k <=> T(2 k ) / 2 k = T(2 k-1 ) / 2 k-1 + 1 <=> T(2 k-1 ) / 2 k-1 = T(2 k-2 ) / 2 k-2 + 1 <=> T(2 k-2 ) / 2 k-2 = T(2 k-3 ) / 2 k-3 + 1... <=> T(2 2 ) / 2 2 = T(2 1 ) / 2 1 + 1 <=> T(2 1 ) / 2 1 = T(2 0 ) / 2 0 + 1 Lasketaan yhteen (teleskooppi) T(2 k ) / 2 k = k T(N) = T(2 k ) = k 2 k = N log N = O(N log N) 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 23
Esim 5. Potenssiinkorotus: Jos laskettaisiin x n = x*x*x*...*x, n-1 kertolaskua => O(n) Mutta voidaan laskea esim. x 9 = (x 2 ) 4 x = ((x 2 ) 2 ) 2 x (vain 4 kertolaskua 8:n sijaan!) integer pow(int x, int n){ switch (n) { case 0: return 1; break; case 1: return x; break; default: if (n&1) return pow(x*x, n/2)*x; else return pow(x*x, n/2); } } T(n) = T(n/2) + 1, T(1) = T(0) = 1 T(n) = O(log n) (Ratkaisu: vrt. Esim. kohta 2 edellä) 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 24
1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 25
1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 26
1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 27
Yleistä verkoista Kurssilla tarkastellut algoritmit DFS, BFS Prim, Kruskal (minimaalinen virityspuu) Dijkstra (lyhimmin poluin viri1ävä puu) Sovelluksia (palautus) verkon yhtenevyyden tutkiminen leikkaussolmujen etsintä lyhin reie kahden pisteen välillä teksfn oikean reunan esteeenen tasaus 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 28
Onko olemassa suomenkielistä sanastoa? Ks. Ohjelmoin! 1 - Syksy 2015 h1ps://greengoblin.cs.hut.fi/o1_s2015/ course/yleista/sanasto.html 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 29
Tietorakenteet ja algoritmit Tenttiinlukuohje 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 30
Tentin pakollinen osuus 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 31
Tentin pakollinen osuus 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 32
Tentin pakollinen osuus 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 33
Tenttitehtäviä (28.8.2003) Määrittele lyhyesti seuraavat käsitteet. Anna jokaisesta kohdasta myös esimerkki. (oikea määritelmä 1p, esimerkki 1p) a) Pakka (deque) b) Prioriteettijono c) Hajautusfunktio d) Abstrakti tietotyyppi 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 34
Tenttitehtäviä Joudut valitsemaan algoritmin tehtävään, jossa tulee järjestäa anne1u aineisto. Mita asioita (kriteereita ) huomioit tehdessäsi valintaa? Lue ensin koko tehtävänanto. a) Valitse kolme (3) keskeista kriteeria joiden valossa tarkastelet Flanne1a. Perustele miksi tai miten valitsemasi kriteerit lii1yvät järjestämisongelmaan. b) Nimea jokaisen kriteerin kohdalla erikseen ainakin yksi algoritmi, joka täy1äa ko. kriteerin ja yksi joka ei täyta (algoritmien toimintaperiaa1eita ei tarvitse seli1äa ). c) Nimea algoritmi, joka täy1äa kaikki kriteereistäsi. Nimea myös jokin algoritmi, joka ei täyta ainakaan kahta kriteereistäsi. 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 35
Tenttitehtäviä a) Esitä jonkin algoritmin toimintaperiaate, jonka toiminnan kannalta keskeisenä tietorakenteena on prioriteettijono (esim. Huffman-koodaus, prioriteettijonon soveltaminen järjestämisongelmaan tai Dijkstran algoritmi). Esitä algoritmi riittävällä tarkkuudella, jotta prior.jonon käyttötarkoitus selviää. b) Analysoi valitsemasi sovelluksen suoritusaika kahdella eri prioriteettijonon toteutuksella, jotka ovat i) prioriteetin mukaan järjestetty linkitetty lista ja ii) binäärikeko. 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 36
Keskeiset aihepiirit Perustietorakenteet (pino, jono) Algoritmianalyysi Järjestämismenetelmät Prioriteettijonot Hakurakenteet Hakupuut Hajautus Verkkoalgoritmit 1.12.2015 Tietorakenteet ja algoritmit - syksy 2015 37