58131 Tietorakenteet ja algoritmit. Kevät 2016 Jyrki Kivinen

Samankaltaiset tiedostot
Tietorakenteet ja algoritmit syksy Laskuharjoitus 1

Tietorakenteet, laskuharjoitus 1,

58131 Tietorakenteet ja algoritmit. Kevät 2015 Patrik Floréen ja Jyrki Kivinen

Tietorakenteet (syksy 2013)

Diskreetin matematiikan perusteet Laskuharjoitus 1 / vko 8

Jokaisen parittoman kokonaisluvun toinen potenssi on pariton.

Tietorakenteet ja algoritmit - syksy

Todistusmenetelmiä Miksi pitää todistaa?

Tietorakenteet ja algoritmit Johdanto Lauri Malmi / Ari Korhonen

Johdatus matemaattiseen päättelyyn

58131 Tietorakenteet ja algoritmit (syksy 2015)

Johdatus diskreettiin matematiikkaan Harjoitus 5, Ratkaise rekursioyhtälö

Johdatus matemaattiseen päättelyyn

4.3. Matemaattinen induktio

Matematiikan johdantokurssi, syksy 2016 Harjoitus 11, ratkaisuista

TIE Tietorakenteet ja algoritmit 1. TIE Tietorakenteet ja algoritmit

Diskreetin matematiikan perusteet Laskuharjoitus 2 / vko 9

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

Johdatus matematiikkaan

Johdatus matemaattiseen päättelyyn (5 op)

Yhtäpitävyys. Aikaisemmin osoitettiin, että n on parillinen (oletus) n 2 on parillinen (väite).

811312A Tietorakenteet ja algoritmit Kertausta kurssin alkuosasta

811120P Diskreetit rakenteet

Johdatus matemaattiseen päättelyyn

Esitetään tehtävälle kaksi hieman erilaista ratkaisua. Ratkaisutapa 1. Lähdetään sieventämään epäyhtälön vasenta puolta:

Diskreetin Matematiikan Paja Ratkaisuhahmotelmia viikko 1. ( ) Jeremias Berg

MS-A0402 Diskreetin matematiikan perusteet Esimerkkejä, todistuksia ym., osa I

Vastaoletuksen muodostaminen

MS-A0402 Diskreetin matematiikan perusteet Esimerkkejä ym., osa I

MS-A0402 Diskreetin matematiikan perusteet Esimerkkejä, todistuksia ym., osa I

MS-A0402 Diskreetin matematiikan perusteet Esimerkkejä ym., osa I

Esimerkkejä polynomisista ja ei-polynomisista ongelmista

MS-A0402 Diskreetin matematiikan perusteet

Vastaus 1. Lasketaan joukkojen alkiot, ja todetaan, että niitä on 3 molemmissa.

Matematiikassa väitelauseet ovat usein muotoa: jos P on totta, niin Q on totta.

Miten perustella, että joukossa A = {a, b, c} on yhtä monta alkiota kuin joukossa B = {d, e, f }?

Tietorakenteet ja algoritmit

Approbatur 3, demo 1, ratkaisut A sanoo: Vähintään yksi meistä on retku. Tehtävänä on päätellä, mitä tyyppiä A ja B ovat.

2017 = = = = = = 26 1

Reaalifunktioista 1 / 17. Reaalifunktioista

Algoritmit 1. Luento 1 Ti Timo Männikkö

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

Ohjelmoinnin perusteet Y Python

58131 Tietorakenteet

Algoritmit 1. Luento 3 Ti Timo Männikkö

Johdatus matematiikkaan

Ratkaisu. Ensimmäinen kuten P Q, toinen kuten P Q. Kolmas kuten P (Q R):

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.

Nopea kertolasku, Karatsuban algoritmi

-Matematiikka on aksiomaattinen järjestelmä. -uusi tieto voidaan perustella edellisten tietojen avulla, tätä kutsutaan todistamiseksi

JOHDATUS LUKUTEORIAAN (syksy 2017) HARJOITUS 3, MALLIRATKAISUT

1. Esitä rekursiivinen määritelmä lukujonolle

Todistamisessa on tärkeää erottaa tapaukset, kun sääntö pätee joillakin tai kun sääntö pätee kaikilla. Esim. On olemassa reaaliluku x, jolle x = 5.

Algoritmit 1. Luento 13 Ti Timo Männikkö

ITKP102 Ohjelmointi 1 (6 op)

2.1. Tehtävänä on osoittaa induktiolla, että kaikille n N pätee n = 1 n(n + 1). (1)

Rekursiolause. Laskennan teorian opintopiiri. Sebastian Björkqvist. 23. helmikuuta Tiivistelmä

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

Tehtäväsarja I Seuraavissa tehtävissä harjoitellaan erilaisia todistustekniikoita. Luentokalvoista 11, sekä voi olla apua.

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

811312A Tietorakenteet ja algoritmit Kertausta kurssin alkuosasta

1. Logiikan ja joukko-opin alkeet

A TIETORAKENTEET JA ALGORITMIT

Diskreetin Matematiikan Paja Tehtäviä viikolle 2. ( ) Jeremias Berg

1 sup- ja inf-esimerkkejä

Lisää kvanttoreista ja päättelyä sekä predikaattilogiikan totuustaulukot 1. Negaation siirto kvanttorin ohi

Luku 6. Dynaaminen ohjelmointi. 6.1 Funktion muisti

(iv) Ratkaisu 1. Sovelletaan Eukleideen algoritmia osoittajaan ja nimittäjään. (i) 7 = , 7 6 = = =

A TIETORAKENTEET JA ALGORITMIT

b) Määritä myös seuraavat joukot ja anna kussakin tapauksessa lyhyt sanallinen perustelu.

Algoritmi on periaatteellisella tasolla seuraava:

Algoritmit 2. Luento 14 Ke Timo Männikkö

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

Analyysi III. Jari Taskinen. 28. syyskuuta Luku 1

1 sup- ja inf-esimerkkejä

Matematiikan tukikurssi

Kaikki kurssin laskuharjoitukset pidetään Exactumin salissa C123. Malliratkaisut tulevat nettiin kurssisivulle.

811120P Diskreetit rakenteet

missä on myös käytetty monisteen kaavaa 12. Pistä perustelut kohdilleen!

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset

Matematiikan peruskurssi 2

missä on myös käytetty monisteen kaavaa 12. Pistä perustelut kohdilleen!

Injektio. Funktiota sanotaan injektioksi, mikäli lähtöjoukon eri alkiot kuvautuvat maalijoukon eri alkioille. Esim.

Tietorakenteet, laskuharjoitus 3, ratkaisuja

1 Lukujen jaollisuudesta

(2n 1) = n 2

Tee konseptiin pisteytysruudukko! Muista kirjata nimesi ja ryhmäsi. Lue ohjeet huolellisesti!

Tietotekniikan valintakoe

Johdatus matematiikkaan

802328A LUKUTEORIAN PERUSTEET OSA III BASICS OF NUMBER THEORY PART III. Tapani Matala-aho MATEMATIIKKA/LUTK/OULUN YLIOPISTO

Matematiikan tukikurssi, kurssikerta 5

Algoritmit 1. Luento 11 Ti Timo Männikkö

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

3. Kirjoita seuraavat joukot luettelemalla niiden alkiot, jos mahdollista. Onko jokin joukoista tyhjä joukko?

Insinöörimatematiikka A

1 Peruslaskuvalmiudet

ITKP102 Ohjelmointi 1 (6 op)

Kannan vektorit siis virittävät aliavaruuden, ja lisäksi kanta on vapaa. Lauseesta 7.6 saadaan seuraava hyvin käyttökelpoinen tulos:

Algoritmit 1. Luento 2 Ke Timo Männikkö

Algoritmit 2. Luento 13 Ti Timo Männikkö

Transkriptio:

58131 Tietorakenteet ja algoritmit Kevät 2016 Jyrki Kivinen 1

Sisällys 1. Johdanto ja kertausta: tietoa kurssista, matematiikan kertausta, rekursio 2. Johdanto tietorakenteisiin: algoritmien oikeellisuus, vaativuus 3. Järjestäminen 4. Perustietorakenteita: pino, jono ja lista, niiden toteutus ja käyttäminen 5. Hajautus: toinen tehokas tapa suurten tietomäärien organisoimiseen 6. Hakupuut: eräs tehokas tapa suurten tietomäärien organisoimiseen 7. Keko: monien algoritmien käyttämä hyödyllinen aputietorakenne, mm. kekojärjestäminen 8. Verkot: tallettaminen, perusalgoritmit, polunetsintä, virittävät puut 9. Algoritminsuunnittelumenetelmiä ja kertausta 2

1. Johdanto ja kertausta Kurssin asema opetusohjelmassa Tietojenkäsittelytieteen aineopintokurssi, 8 10 op, pääaineopiskelijoille pakollinen Lisäopintopisteitä (1 tai 2 op) saa runsaasta laskuharjoitus- ja ohjelmointitehtävien ratkaisemisesta Esitietoina Johdatus yliopistomatematiikkaan (ennen: Johdatus diskreettiin matematiikkaan) ja Ohjelmoinnin jatkokurssi Jatkokurssi Design and Analysis of Algorithms (5 op, syventävät, pakollinen algoritmien, data-analytiikan ja koneoppimisen linjalla, valinnainen muille) Tällä kurssilla opittavat tekniikat ja ajattelutavat ovat tarpeen kurssilla Laskennan mallit (8 op, pääaineopiskelijoille pakollinen aineopintokurssi) 3

Esitietovaatimuksisista Ohjelmointitaito Pääpaino on yleisillä periaatteilla, jotka esitetään käyttämällä luonnollista kieltä, kuvia, pseudokoodia, Java-ohjelmia jne. Yleiset periaatteet ovat riippumattomia ohjelmointikielestä, mutta on tärkeätä pystyä toteuttamaan algoritmit eri kielillä (tällä kurssilla Javalla) Koska tarkoituksena on oppia tietorakenteita ja perusalgoritmeja, kurssilla ei saa käyttää näiden valmiita Java-kirjastojen luokkia ellei erikseen pyydetä; toisaalta tarkoitus on keskittyä itse algoritmeihin, joten ohjelmissa ei tarvitse varautua virhetilanteisiin, jotka ovat olennaisia oikeissa ohjelmissa Java-toteutusta harjoitellaan laskuharjoituksissa ja erikseen Tira-harjoitustyössä Matematiikka Kurssilla tarvitaan vain vähän varsinaisia matemattisia tietoja (teoreemoja yms.). Diskreetit perusrakenteet kuten verkot (eli graafit) tulevat käyttöön, ja jonkin verran tarvitaan joukko-oppia ja laskutaitoa. Oleellisempaa kuitenkin on, että tietorakenteiden käsittely vaatii samantyyppistä ajattelua kuin (diskreetti) matematiikka 4

Lähdemateriaali Tämä luentomateriaali on uudistettu painos edellisvuosien kalvoista (tekijöinä mm. Patrik Floréen, Matti Luukkainen ja Matti Nykänen) Suurin osa käsiteltävistä asioista perustuu kirjaan T. H. Cormen, C. E. Leiserson, R. L. Rivest, C. Stein: Introduction to Algorithms. 3rd ed. MIT Press, 2009. Myös kirjan toinen painos on käyttökelpoinen Cormenin kirja kattaa suurimman osan kurssilla käsiteltävistä asioista ja onkin suositeltavin teos, jos olet aikeissa ostaa jonkun kirjan Suurin ero Cormenin painosten 2 ja 3 välillä on pseudokoodin esitysmuodossa. Tässä monisteessa käytetään kolmannen painoksen pythonmaista pseudokoodia 5

Kurssilla käsiteltävistä asioista Cormenissa ei ole AVL-puita, joihin hyvä lähde on M. A. Weiss: Data Structures and Algorithm Analysis in Java, 2nd ed., Addison-Wesley, 2007 Muita lähteitä on mm. A. Levitin: Introduction to The Design and Analysis of Algorithms, Addison-Wesley, 2003 J. Kleinberg, E. Tardos: Algorithm Design, Pearson Addison-Wesley, 2006 A. Aho, J. Hopcroft, J. Ullman : Data Structures and Algorithms, Addison-Wesley, 1983 Tässä mainittujen ohella aihepiiristä löytyy runsaat määrät kirjallisuutta ja vaihtelevatasoista materiaalia internetistä, erityisesti koska aihe on tietojenkäsittelytieteen perusasiaa ja siten globaalisti alan yliopistolaitosten kurssivalikoimassa 6

Miksi pakollinen kurssi Tietorakenteet ja algoritmit? Monet tietorakenteet on helppo toteuttaa Javan valmiiden tietorakennetoteutusten avulla. Esim. seuraavassa luvussa esitettävän puhelinluettelon toteuttamiseen Javassa on valmiina luokka TreeMap Miksi siis vaivautua opiskelemaan tietorakenteita 8 10 op:n verran? Vaikka tietorakennetoteutuksia on olemassa, ei niitä välttämättä osaa hyödyntää tehokkaasti ilman taustatietämystä niiden toimintaperiaatteista Esim. kannattaako valita puhelinluettelon toteutukseen Arraylist, HashMap, TreeMap vai jokin muu Javan kokoelmakehyksestä löytyvä tietorakennetoteutus Kaikiin ongelmiin ei löydy suoraan valmista tietorakennetta tai algoritmia ainakaan kielten standardikirjastojen joukosta Esim. seuraavassa luvussa esitettävä kaupunkien välisten lyhimpien reittien tehokas etsiminen ei onnistu Javan valmiiden mekanismien avulla Tarvitaan siis yleiskäsitys erilaisista tietorakenteista ja algoritmeista, jotta vastaantulevia ongelmia pystyy jäsentämään siinä määrin, että ratkaisun tekeminen onnistuu tai lisäinformaation löytyminen helpottuu 7

Voisi myös kuvitella, että tietokoneiden jatkuva nopeutuminen vähentää edistyneiden tietorakenteiden ja algoritmien merkitystä Kuten lyhimpien polkujen esimerkistä sivulla 32 34 voidaan havaita, pienikin ongelma typerästi ratkaistuna on niin vaikea, ettei nopeinkaan kone siihen pysty Vaikka koneet nopeutuvat, käsiteltävät datamäärät kasvavat suhteessa jopa enemmän Koko ajan halutaan ratkaista yhä vaikeampia ongelmia (tekoäly, grafiikka,... ) Paradoksaalisesti laitetehojen parantuminen saattaa jopa tehdä algoritmin tehokkuudesta tärkeämpää: algoritmien tehokkuuserot näkyvät yleensä selvästi vasta suurilla syötteillä, ja tehokkaat koneet mahdollistavat yhä suurempien syötteiden käsittelemisen 8

Muuttuva ympäristö tuo myös uusia tehokkuushaasteita: moniytimisyyden yleistymisen myötä syntynyt kasvava tarve rinnakkaistaa laskentaa hajautettu laskenta reaaliaikainen laskenta mobiililaitteiden rajoitettu kapasitetti muistihierarkiat jne. Tällä kurssilla keskitytään kuitenkin klassisiin perusasioihin 9

Tietorakenteiden opiskelu on monella tavalla "opettavaista" Perustietorakenteet ovat niin keskeinen osa tietojenkäsittelytiedettä, että ne pitää tuntea pintaa syvemmältä Tietorakenteisiin liittyvät perusalgoritmit ovat opettavaisia esimerkkejä algoritmien suunnittelutekniikoista Tietorakenteita ja algoritmeja analysoidaan täsmällisesti: käytetään matematiikkaa ja samalla myös opitaan matematiikkaa Näistä taidoista hyötyä toisen vuoden kurssilla Laskennan mallit sekä kaikilla Algoritmit, data-analytiikka ja koneoppiminen -linjan kursseilla, joista erityisesti kurssia Design and Analysis of Algorithms voi pitää Tiran "jatkokurssina" Algoritmeihin liittyvästä täsmällisestä argumentoinnista on hyötyä tietysti myös normaalissa ohjelmoinnissa, testaamisessa ym. Teoreettisesta lähestymistavasta huolimatta kurssilla on tarkoitus pitää myös käytäntö mielessä: miten opitut tietorakenteet ja algoritmit voidaan toteuttaa esim. Javalla? mikä ohjelmointikielen tarjoamista valmiista tietorakenne- ja algoritmitoteutuksista kannattaa valita oman ongelman ratkaisuun? 10

Kurssin tavoitteet Yleisemmin voidaan todeta, että kurssilla etsitään vastauksia seuraavanlaisiin kysymyksiin: miten laskennassa tarvittavat tiedot organisoidaan tehokkaasti? miten varmistumme toteutuksen toimivuudesta? miten analysoimme toteutuksen tehokkuutta? millaisia tunnettuja tietorakenteita voimme hyödyntää? Oppimistavoitematriisi (ks. kurssisivu) määrittelee tarkemmin, mikä on oleellisinta kurssilla. Sarake lähestyy oppimistavoitetta määrittelee suunilleen arvosanaan 1 vaadittavan osaamisen tason Sarake saavuttaa oppistavoitteet määrittelee korkeimpiin arvosanoihin vaadittavan oppimisen tason Osa asioista (erityisesti algoritmien ja tietorakenteiden toteuttaminen Javalla) on sen luonteista, että niiden hallinta osoitetaan kokeiden sijasta vain harjoituksissa 11

Matematiikan kertausta: Logiikka Loogisten lausekkeiden totuusarvot määräytyvät seuraavasti (T niin kuin tosi eli true ja F niin kuin epätosi eli false): A B A B A B A B A B T T T T T T T F T F F F F T T F T F F F F F T T Huomaa, että implikaatio A B siis tarkoittaa A B. Esimerkiksi väittämä jos kuu on juusto, niin Suomen valuutta on kruunu on tosi implikaatio 12

Matematiikan kertausta: Todistusmenetelmiä Halutaan todistaa, että (todesta) oletuksesta A seuraa väite B eli A B. Todistamiseen on useita erilaisia tekniikoita. Se, mikä kulloinkin sopii parhaiten, riippuu tilanteesta Deduktiivisessa todistuksessa, jota kutsutaan myös suoraksi todistukseksi, oletetaan A ja näytetään, että tästä seuraa B Esim. Olkoon x N pariton. Väite: x 2 on pariton. Tod.: Jos x N on pariton (oletus), niin x = 2k + 1 jollain k N (parittomuuden määritelmä). Silloin x 2 = 4k 2 + 4k + 1 = 2(2k 2 + 2k) + 1, eli x 2 on pariton. 13

Kontrapositiivisessa todistuksessa näytetään että oletuksesta ei B seuraa ei A, eli että B A Esim. Väite: Jos x > 0 on irrationaaliluku, niin x on irrationaaliluku. Tod.: Osoitetaan, että jos x on rationaaliluku, niin x on rationaaliluku. Siis x = p/q, joillakin p, q Z, q 0, joten x = p 2 ja p 2, q 2 Z, q 2 0. Vastaväitetodistuksessa (reductio ad absurdum) näytetään että oletuksesta A B seuraa ristiriita. Tekniikkaa kutsutaan myös epäsuoraksi todistamiseksi Esim. Väite: Jos a + b = 2, niin a 1 tai b 1. Tod.: Oletetaan, että a + b = 2 ja tehdään vastaväite a < 1 ja b < 1. Tällöin 2 = a + b < 1 + 1 = 2, ristiriita. q 2 14

Miksi vastaväitetodistus toimii? Katsomme mitä tämä loogisesti tarkoittaa Osoitamme vastaväitetodistuksessa, että A B on epätosi. Vertaamme totuusarvotaulukon avulla tätä implikaatioon: A B A B A B T T F T T F T F F T F T F F F T Näemme siis, että A B on epätosi täsmälleen silloin kun A B on tosi Katsomme vielä, miten voidaan osoittaa jotain epätodeksi. Helpoin tapa on esittää tapaus, jossa väite on epätosi Esim. (Epätosi) väite: Kaikki alkuluvut ovat parittomia. Todistetaan epätodeksi: Luku 2 on alkuluku ja on parillinen. Väite ei siis päde. 15

Matematiikan kertausta: Logaritmi Koulumatematiikasta muistetaan, että log a x on sellainen luku z, jolla a z = x. Tässä oletetaan yleensä a > 0, a 1 ja x > 0 Logaritmi log a n siis kertoo, kuinka monta kertaa luku n pitää jakaa a:lla, ennen kuin päästään lukuun 1. Esimerkiksi log 2 8 on 3, koska 8/2/2/2 on 1. Jos lukuun 1 ei päästä tasajaolla, logaritmin loppuosa on desimaaliosa, joka kuvaa viimeistä vaillinaista jakoa. Esimerkiksi log 2 9 on noin 3, 17, koska 9/2/2/2 on 1, 125, eli kolmen jaon jälkeen on vielä hieman matkaa lukuun 1, mutta neljäs täysi jako veisi jo selvästi alle yhden Luonnollinen logaritmi on ln x = log e x, missä kantalukuna on Neperin luku e = lim n (1 + 1/n) n 2, 718 Kaksikantainen logaritmi log 2 n kertoo likimäärin luonnollisen luvun n pituuden bitteinä (tarkemmin: luvun n > 0 pituus bitteinä on log 2 n + 1) Laskusääntöjä: log a (xy) = log a x + log a y log a (x y ) = y log a x log a x = log b x log b a 16

Usein tietorakenteissa esiintyy tilanne, jossa on tiedossa esim. että 4(n + 1) = 2 j+3 ja olisi saatava selville mikä on j:n arvo n:n suhteen. Vakiot voivat olla tietysti mitä vain Aloitetaan ottamalla 2-kantainen logaritmi molemmilta puolilta, tuloksena log 2 (4(n + 1)) = log 2 2 j+3 edellisen sivun laskusääntöjen perusteella vasen puoli yksinkertaistuu seuravasti log 2 (4(n + 1)) = log 2 4 + log 2 (n + 1) = 2 + log 2 (n + 1) ja oikea puoli log 2 2 j+3 = (j + 3) log 2 2 = (j + 3) 1 = j + 3, eli on päästy muotoon 2 + log 2 (n + 1) = j + 3, joten j = log 2 (n + 1) 1 17

Ohjelmointitaitoa: Rekursio Metodi voi tunnetusti sisältää kutsuja muihin metodeihin Jos metodi kutsuu itseään, se on rekursiivinen Rekursion pitää kuitenkin päättyä joskus (eli ei saa esiintyä kehäpäättelyä): tämä perustapaus (eng. base case) ei kutsu metodia ja takaa sen, että rekursio päättyy Tarkastellaan seuraavaa yksinkertaista esimerkkiä: Olkoon x reaaliluku ja n luonnollinen luku. Tiedämme, että { x n 1, kun n = 0 = x x n 1, kun n > 0 Tässä tapaus n = 0 on perustapaus, joka sisältää ratkaisun suoraan Tämän voimme kirjoittaa ohjelmaksi: public static double potenssi(double x, int n) { if (n == 0) return 1.0; return x * potenssi(x,n-1); } 18

Mitä tapahtuu, jos kutsutaan potenssi(2.0,4)? Kaavatasolla tämä siis tarkoittaa että 2 4 = 2 2 3 = 2 (2 2 2 ) = 2 (2 (2 2 1 )) = 2 (2 (2 (2 2 0 ))) = 2 (2 (2 (2 1))) = 2 (2 (2 2)) = 2 (2 4) = 2 8 = 16 Huomaa, miten rekursio ensin laajenee kunnes päästään tasolle n = 0 ja sitten se kelautuu takaisin kun saadaan laskettua arvot yksi kerrallaan Ohjelmalla on ns. ajonaikainen pino (eng. run-time stack). Pino-tietorakenteeseen tullaan myöhemmin kurssilla. Tässä vaiheessa riittää ymmärtää, että kyse on asioiden laittamisesta muistiin myöhempää käyttöä varten Ajonaikaiseen pinoon laitetaan tietue, joka kertoo parametrien arvot ja mihin kohtaan ohjelmaa palataan kun ollaan valmiit (paluuosoite on koodin joku rivi) Tämä kutsutaan aktivaatiotietueeksi (eng. activation record). Enemmän näistä asioista kurssilla Tietokoneen toiminta 19

Ajonaikainen pino on Javassa osa Javan virtuaalikonetta (Java Virtual Machine, JVM), joka on konekielinen ohjelma, joka suorittaa Java-ohjelman tavukoodia (eng. byte code) Java varaa ajonaikaiselle pinolle tietyn koon, ja jos tämä ylittyy tulee virheilmoitus StackOverflowError Kun aktivaatiotietueet aiheutuvat rekursiivisesta metodista, puhumme rekursiopinosta (tältä osalta ajonaikaista pinoa) Kutsu potenssi(2.0,4) luo aktivaatiotietueen, jossa on parametrit 2.0 ja 4 sekä paluuosoitteeksi mistä kutsu tuli 20

Koska n ei ole 0, suoritetaan rivi return x * potenssi(x,n-1); Mutta tämä sisältää kutsun potenssi(2.0,3), eli nyt laitetaan pinoon parametrit 2.0 ja 3 ja paluosoitteeksi tämä potenssi(2.0,4):n return-rivi, josta kutsu potenssi(2.0,3):een tuli Seuraavaksi potenssi(2.0,2) laittaa pinoon parametrit 2.0 ja 2 ja paluuosoitteeksi potenssi(2.0,3):n return-rivi Seuraavaksi potenssi(2.0,1) laittaa pinoon parametrit 2.0 ja 1 ja paluuosoitteeksi potenssi(2.0,2):n return-rivi Seuraavaksi potenssi(2.0,0) laittaa pinoon parametrit 2.0 ja 0 ja paluuosoitteeksi potenssi(2.0,1):n return-rivi Pinon sisältö on siis seuraava: 2.0 0 2.0 1 2.0 2 2.0 3 2.0 4 21

Nyt ohjelma palauttaa arvon 1.0 eikä kutsu enää itseään, eli poistetaan pinosta tietue, jossa on 2.0 ja 0 ja paluuosoitteena potenssi(2.0,1):n return-rivi ja siirrytään sille riville Suoritetaan potenssi(2.0,1):n return-rivin lasku 2.0 * 1.0 = 2.0 ja poistetaan pinosta tietue, jossa on 2.0 ja 1 ja paluuosoitteena potenssi(2.0,2):n return-rivi ja siirrytään sille riville Suoritetaan potenssi(2.0,2):n return-rivin lasku 2.0 * 2.0 = 4.0 ja poistetaan pinosta tietue, jossa on 2.0 ja 2 ja paluuosoitteena potenssi(2.0,3):n return-rivi ja siirrytään sille riville Suoritetaan potenssi(2.0,3):n return-rivin lasku 2.0 * 4.0 = 8.0 ja poistetaan pinosta tietue, jossa on 2.0 ja 3 ja paluuosoitteena potenssi(2.0,4):n return-rivi ja siirrytään sille riville Suoritetaan potenssi(2.0,4):n return-rivin lasku 2.0 * 8.0 = 16.0 ja poistetaan pinosta tietue, jossa on 2.0 ja 4 ja paluuosoittena paikka mistä metodi kutsuttiin 22

Huomautus: potenssia ei kannata toteuttaa näin, esimerkki oli valittu jotta se olisi helppo selittää. Parempi toteutus käyttää iteraatiota: public static double potenssi(double x, int n) { double result = 1; for (int j = 1; j <= n; j++) result *= x; return result; } Tämä toteutus vie paljon vähemmän tilaa (ja on nopeampi), koska ei tarvita rekursiopinoa! Hyvät ja huonot puolet: Rekursiivinen ohjelma on yleensä helpompi ymmärtää ja ohjelmoida, koodi on lyhyempää. Toisaalta rekursiivinen ohjelma on yleensä hitaampi ja vie enemmän muistia 23

Huom: Periaatteessa jokainen rekursio voidaan muuttaa iteraatioksi Tulemme kurssin aikana näkemään algoritmeja, joita on helppoja esittää rekursiivisesti, mutta vaikeampia koodata iteratiivisiksi ohjelmiksi Muita esimerkkejä: Kertoman määritelmä on n! = { 1 kun n = 0 n (n 1)! kun n > 0 Binomikerroin ( n n! = k) k!(n k)! on usein järkevää laskea käyttämällä palautuskaavaa ( { n 1 = ) ( kun k = 0 tai k = n k) + n 1 ) kun 1 k n 1 ( n 1 k 1 k 24

Katsotaan vielä esimerkki muunlaisesta rekursiosta kuin jonkin numeerisen funktion laskemisesta Tehtävänä on tulostaa jonkin n-alkioisen perusjoukon kaikki k-alkioiset osajoukot. Yksinkertaisuuden vuoksi oletetaan, että perusjoukko on { 0,..., n 1 } Miten tehtävän voi ratkaista n-alkioisella perusjoukolla, jos osaamme jo ratkaista sen (n 1)-alkioisella? Joukon { 0,..., n 1 } kaikki k-alkioiset osajoukot (kun k > 0) voidaan luetella seuraavasti: Luettele joukon { 1,..., n 1 } kaikki (k 1)-alkioiset osajoukot siten, että niiden eteen on liitetty alkio 0 Luettele joukon { 1,..., n 1 } kaikki k-alkioiset osajoukot Jälkimmäinen luettelo jää tyhjäksi tapauksessa k = n 25

Saamme siis n-alkioisen ongelman suunnilleen palautetuksi (n 1)-alkioiseen Rekursion toteuttaminen vaatii kuitenkin hieman lisäinformaatiota: mitkä alkiot on jo valittu joukon alkuun mikä on pienin jäljellä oleva alkio Kerätään seuraavaksi tulostettava osajoukko taulukkoon A alkio kerrallaan Määritellään rekursiivinen algoritmi tulostajoukot(p, q), joka tulostaa kaikki sellaiset k-alkioiset osajoukot, joissa pienimmät p alkiota ovat A[1],..., A[p] loput k p alkiota valitaan joukosta { q,..., n } Kutsu tulostajoukot(0,0) tuottaa nyt halutun tuloksen 26

Algoritmi on seuraava: tulostajoukot(p, q) 1 if p < k 2 A[p + 1] = q 3 tulostajoukot(p + 1, q + 1) 4 if k p < n q 5 tulostajoukot(p, q + 1) 6 else 7 tulosta joukko { A[1],..., A[k] } n ja k oletetaan määritellyksi jossain muualla rivin 4 ehtotestin tarkoitus on estää alkion q jättäminen pois, jos jäljellä on enää täsmälleen tarvittava määrä alkioita 27