Tietorakenteet ja algoritmit II

Koko: px
Aloita esitys sivulta:

Download "Tietorakenteet ja algoritmit II"

Transkriptio

1 1 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 1(279) Tietorakenteet ja algoritmit II Simo Juvaste Itä-Suomen yliopisto Tietojenkäsittelytiede :47

2 Sisällysluettelo (kalvot ) Luku 1: Kertausta algoritmiikasta ja aikavaativuudesta Kertausta algoritmien ja tietorakenteiden käsitteistä Suorituksen vaativuus Rekursiivisten algoritmien aikavaativuus Aikavaativuuden rajojen todistaminen Kokeellinen aikavaativuuden määrääminen Abstraktit tietotyypit (*) Kertaus abstrakteihin tietotyyppeihin (*) Lista (*) Puu (*) Hakupuut (*) Joukot (*) 100 Luku 2: Suunnatut verkot Käsitteitä Suunnattu verkko abstraktina tietotyyppinä Lyhimmät polut Verkon läpikäynti Muita verkko-ongelmia Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 2(279)

3 Luku 3: Suuntaamattomat verkot Määritelmiä Pienin virittävä (kattava) puu Suuntaamattoman verkon läpikäynti Leikkaussolmut ja 2-yhtenäiset komponentit Verkon kaksijakoisuus, sovitus 184 Luku 4: Algoritmistrategioita Ahne eteneminen Hajoita-ja-hallitse Dynaaminen ratkaiseminen (ohjelmointi) Tasoitettu aikavaativuus Haun rajoittaminen Satunnaistetut algoritmit Kantalukulajittelu Merkkijonon haku 208 Luku 5: Ulkoisen muistin käsittely Tiedostokäsittely Onko keskusmuisti ulkoista muistia? Ulkoinen lajittelu Tiedosto kokoelmana (*) B-puu Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 3(279)

4 Luku 6: Abstraktien tietotyyppien toteuttaminen (kertausta ja pari täydennystä TRAI:een) (*) Kotelointi ja parametrointi Verkot 268 Kirjallisuutta Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 4(279)

5 Luku 1 5 Kertausta algoritmiikasta ja aikavaativuudesta Kertausta algoritmiikasta ja aikavaativuudesta Kurssin tavoite ja sisältö Kerrata ja jatkaa TRAI:n asioita. Kerrata perustietorakenteet (lista, puu, joukko). Oppia abtrakti tietotyyppi verkko ja sen käyttö. Syventää aikavaativuusosaamista. Rekursiiviset algorimit. Ongelman aikavaativuus. Massamuistin käytön aikavaativuus. Oppia valitsemaan kuhunkin tarkoitukseen sopivin tietorakenne. Oppia käyttämään valittua tietorakennetta oikein! Oppia suunnittelemaan ja toteuttamaan algoritmeja. Käymme läpi algoritmistrategioita. Käymme läpi erilaisia algoritmeja ja niiden toteutuksia. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 5(279)

6 Miksi tietorakenne? 6 Kertausta algoritmiikasta ja aikavaativuudesta Tietoa on helpompi ja tehokkaampi käsitellä sovelluksen vaatimalla tavalla kun se tallennetaan sopivaan tietorakenteeseen. Tiedolla on helpompi mallintaa reaalimaailmaa kun sen rakenne vastaa reaalimaailmaa. Käsittelytehokkuuden ja reaalimaailman yhdistäminen vaatii joskus eri tietorakenteiden yhteiskäyttöä. Ohjelmasta tulee selkeämpi ( virheettömämpi, siirrettävämpi, ymmärrettävämpi, muutettavampi). Järjestelmän suunnittelijankin on hyvä ymmärtää miten tieto järjestelmässä tallennetaan. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 6(279)

7 Miksi tehokkuus on (vieläkin) tärkeää? 7 Kertausta algoritmiikasta ja aikavaativuudesta Vaikka nykyiset tietokoneet ovat tuhansia kertoja aiempia tehokkaampia, ovat toisaalta syötteet kasvaneet (uusia ongelmia, lisää tarkkuutta) ja ohjelmia kirjoitetaan yhä enemmän muille alustoille kuin perinteisille tietokoneille. Korkeamman tason ohjelmointikielet ja käyttöliittyvät vievät tehoa. Akkukäyttöisellä laitteella jokainen säästetty kellojakso merkitsee paitsi käyttömukavuutta, myös pidempää käyttöaikaa: Säädettävä suoritusteho (ja kääntäen sähkönkulutus)! Virransäästötilaan päästään nopeammin. Huipputehoa tarvitaan harvemmin. Yhteiskäyttöisillä tietokoneilla (palvelimilla) kaikki ajansäästö on lisäaikaa muille käyttäjille (palvelin voi palvella useampaa käyttäjää). O(n) tai O(nlogn) on usein huomattavasti parempi kuin O(n 2 ). O(logn) tai O(1) on usein huomattavasti parempi kuin O(n). O(nlogn) ja O(nloglogn) ovat useimmiten jokseenkin tasavertaisia. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 7(279)

8 1.1 Kertausta algoritmien ja tietorakenteiden käsitteistä 8 Kertausta algoritmiikasta ja aikavaativuudesta Algoritmi on toimintaohjeisto (käskyjono) joka ratkaisee annetun ongelman äärellisessä ajassa. Yleensä deterministisesti. Mieluiten tehokkaasti (kohtuullisessa ajassa, kohtuullisella laitteistolla. Mieluiten kohtuullisella ohjelmointityöllä. Tehokkuuden tasapainotus aikavaativuuden ja ohjelmointityön kesken on myös osattava! Tällä kurssilla opetellaan algoritmien suunnittelumenetelmiä, esimerkkialgoritmeja, kykyä lukea valmiita algoritmikuvauksia ja valmiiden algoritmien toteuttamista. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 8(279)

9 Kertausta algoritmiikasta ja aikavaativuudesta Annettu ongelma? Toivottavasti riittävän tarkasti määritelty. Tällä kurssilla keskitytään pienehköihin, erillisiin ongelmiin. Tärkeää olisi oppia näkemään reaalimaailman ongelmasta se/ne yksinkertainen algoritminen ongelma joka voidaan ratkaista tällä kurssilla annettavalla opilla. Esimerkki 1-1: Kokoelmaan lisätään (runsaasti) alkioita joilla on jokin lukuarvo. Alkiota lisättäessä pitäisi saada selville ko. alkion sijoitus lisäyshetkellä. Samoin pitäisi pystyä hakemaan nopeasti esimerkiksi sadas alkio. Minkälaista tietorakennetta kannattaa käyttää? 9 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 9(279)

10 10 Kertausta algoritmiikasta ja aikavaativuudesta Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 10(279) Tietorakenne Toisiinsa kytkettyjä tietoja (muuttujia). Tällä kurssilla käsittelemme erityisesti alkioiden välisiä suhteita ja näiden suhteiden ominaisuuksia. Taulukko-lista-puu-verkko-joukko.

11 1.2 Suorituksen vaativuus 11 Kertausta algoritmiikasta ja aikavaativuudesta Miten suoritusaikaa (aikavaativuutta) mitataan? Absoluuttinen seinäkelloaika? Huono, sillä kaikki vaikuttaa: syöte käytetty laitteisto kuorma välimuistit roskienkeruu mittavälineetkin voivat olla epätarkkoja Huono, sillä vain jo toteutettua algoritmia voidaan tarkastella. Jotain abstraktimpaa kuin sekunti tms. siis tarvitaan. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 11(279)

12 Kertausta algoritmiikasta ja aikavaativuudesta Kellojakso (tai konekielioperaatio) on parempi, mutta edelleen em. asiat vaikuttavat. Edelleen vain jo toteutettua algoritmia voitaisiin tarkastella (järkevästi). Käytetään yksikköä "askel". a = 1; 1 b = 3; 2 for (i = 0; i < 1000; i++) 1 a = a + A[i]; 2 Kuva 1-1: Suoritusaskel. (n.) kaksi askelta (n.) 1000 askelta 12 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 12(279)

13 Kertausta algoritmiikasta ja aikavaativuudesta Suoritusaika suhteutetaan käsiteltävän syötteen kokoon. Siirräntään kuluvaa aikaa ei yleensä oteta huomioon. Syötteen oletetaan yleensä olevan valmiina saatavilla (viiteparametrina). Syötteen koko voi vaihdella eri suorituskerroilla. Lajittelu 1000 askeleessa (tai 0,1 sekunnissa). Hyvä vai huono? 10, 1.000, , alkiota? Esitetään suoritusaika syötteen koon funktiona! for (i = 0; i < n; i++) 1 a = a + A[i]; 2 (n.) n askelta 13 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 13(279)

14 Kertausta algoritmiikasta ja aikavaativuudesta Esimerkki 1-2: Suoritusaikafunktio T(n)=cn 2 + b, missä b ja c ovat vakioita, ilmaisee suoritusajan olevan neliöllinen suhteessa syötteen kokoon. Tämä merkitsee, että syötteen koon kymmenkertaistuessa suoritusaika suurin piirtein satakertaistuu. Aikavaativuus on siis syötteen koon (elementtien määrä tms) funktio. Usein käytämme muuttujaa n kuvaamaan syötteen kokoa. Tämä on kuitenkin aina muistettava mainita aikavaativuutta ilmaistaessa. Joskus myös muita muuttujia tarvitaan, jos n on varattu toiseen tarkoitukseen. Erityisesti, jos kuvattavia syötteitä on useita erikokoisia. 14 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 14(279)

15 Kertausta algoritmiikasta ja aikavaativuudesta Esimerkki 1-3: Esimerkiksi merkkijonon etsinnän toisesta merkkijonosta vaativuus riippuu sekä etsittävästä avaimesta, että läpikäytävästä kohdetekstistä. Kuvataan avaimen pituutta m:llä ja kohdetekstin pituutta n:llä. Erään yksinkertaisen etsintäalgoritmin suoritusaikafunktio on T(n, m) = cnm, missä c on vakio. Kertaluokkana O(nm). Funktion T mittayksikköä ei kiinnitetä. Sanomme sitä askeleeksi. Todellinen yhden askeleen aikavaativuus riippuu mm. askeleessa suoritettavasta toimenpiteestä ja käytettävästä laitteistosta. 15 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 15(279)

16 Suoritusaika ei aina riipu pelkästään syötteen koosta, vaan myös syötteen laadusta. 16 Kertausta algoritmiikasta ja aikavaativuudesta Kun tämä otetaan huomioon, voidaan tarkastelu eriyttää seuraaviin kolmeen tapaukseen: 1) T(n) tarkoittaa pahimman tapauksen suoritusaikaa eli pisintä mahdollista n:n kokoisen syötteen aiheuttamaa suoritusaikaa. 2) T avg (n) tarkoittaa keskimääräistä suoritusaikaa eli kaikkien n:n kokoisten syötteiden aiheuttamien suoritusaikojen keskiarvoa. 3) T best (n) tarkoittaa parhaan tapauksen suoritusaikaa eli lyhintä mahdollista n:n kokoisen syötteen aiheuttamaa suoritusaikaa. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 16(279)

17 Yleensä tarkastellaan aina pahinta tapausta. 17 Kertausta algoritmiikasta ja aikavaativuudesta Paras tapaus ei yleensä ole edes mielenkiintoinen. Esimerkiksi lajittelussa usein paras tapaus on valmiiksi lajiteltu taulukko. Se taas ei juuri kerro lajittelualgoritmista mitään. Keskimääräisen suoritusajan arviointi saattaa puolestaan osoittautua erittäin hankalaksi tehtäväksi, koska kaikki samankokoiset syötteet voidaan vain harvoin olettaa keskenään yhtä todennäköisiksi. Erilaisia syötteitä on yleensä ekponentiaalinen määrä syötteen koon suhteen. Tällä kurssilla sivutaan hieman tasoitettua aikavaativuutta (katso Tasoitettu aikavaativuus sivulla 198). Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 17(279)

18 Kertausta algoritmiikasta ja aikavaativuudesta Suoritusaikafunktioita voidaan vertailla keskenään funktioiden kasvunopeuksia vertailemalla. Vakiokertoimet eivät ole mielenkiintoisia, kone, kääntäjä,... vaikuttaa. Tarkastellaan sensijaan funktioista vain kertaluokkia: Määritelmä 1-4: Kertaluokkamerkinnät O, Ω, Θ ja o 1) T(n) =O(f(n)), jos on olemassa positiiviset vakiot c ja n 0 siten, että T(n) cf(n), kun n n 0. [Lue: T(n) on kertaluokkaa f(n), iso-o, ordo; "rajoittaa ylhäältä"] 2) T(n) =Ω(g(n)), jos on olemassa positiiviset vakiot c ja n 0 siten, että T(n) cg(n), kun n n 0. [omega; "rajoittaa alhaalta"] 3) T(n) =Θ(h(n)), jos T(n)=O(h(n)) ja T(n)=Ω(h(n)). [theta; "rajoittaa ylhäältä ja alhaalta"] 4) T(n) =o(p(n)), jos T(n) =O(p(n)) ja T(n) Θ(p(n)). [pikku-o; "rajoittaa aidosti ylhäältä"] Siis: kunhan valitaan sopiva vakiokerroin c ja annetaan syötteen kasvaa riittävästi, niin sanottu rajoittaminen pätee. 18 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 18(279)

19 Joskus määritellään myös 5) T(n) =ω(p(n)), jos T(n)=Ω(p(n)) ja T(n) Θ(p(n)). [pikku-omega; "rajoittaa aidosti alhaalta"] 19 Kertausta algoritmiikasta ja aikavaativuudesta Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 19(279)

20 Kertausta algoritmiikasta ja aikavaativuudesta Esimerkki 1-5: Olkoon T(n) =5n+2. Silloin T(n) =O(n), mikä nähdään vaikkapa päättelyllä 5n+2 5n+2n = 7n (kun n 1). Eli c = 7 ja n 0 =1. Ylärajan n rinnalle kelpaisivat myös ylärajat n 2, n 3 ja niin edelleen. Samoin T(n)=Ω(n), mikä nähdään esimerkiksi päättelyllä 5n+2 5n (c =5jan 0 = 1). Näinollen funktio n myös alaraja ja itse asiassa T(n)=Θ(n). Esimerkki 1-6: Näytetään, ettei funktio T(n) =5n+2 ole kertaluokkaa n: Jos olisi T(n) = O( n), niin määritelmän 1-4 nojalla olisi olemassa positiiviset vakiot c ja n 0 siten, että 5n+2 c n, kun n n 0. Tällöin olisi myös 5n c n. Tämä epäyhtälö voidaan järjestellä uudelleen: 5n c n 5 n c n ( c 5) 2. Koska c on vakio, on myös (c/5) 2 vakio. Tämä merkitsee, ettei epäyhtälö 5n+2 c n toteudu ainakaan silloin, kun n > max{n 0,(c/5) 2 }, mikä on vastoin oletusta. Törmäsimme ristiriitaan, eli väite on väärä. 20 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 20(279)

21 Kertausta algoritmiikasta ja aikavaativuudesta Aikavaativuuksien luokittelu: Eksponentiaaliset aikavaativuudet esim 2 n, 3 n, 2 n /n, n! Käyttökelpoisia vain hyvin pienille syötteille Polynomiset aikavaativuudet n, n 2, n 5, n 12345, n n, nlogn Käytännössä yleisimpiä tehokkaita.. kohtuullisen tehokkaita n lineaarinen n 2 neliöllinen n alilineaarinen (mutta polynominen) Logaritmiset aikavaativuudet logn, loglogn, jne huom: logn on tällä kurssilla log 2 n kaikki o(n) on alilineaarista aikavaativuutta ei kokonaisissa peräkkäisalgoritmeissa Vakioaikainen: O(1) 21 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 21(279)

22 Suoritusajan laskeminen 22 Kertausta algoritmiikasta ja aikavaativuudesta Annetun algoritmin suoritusajan laskenta voi olla hyvin helppoa tai hyvin vaikeaa. Yleensä riittää osata jossain määrin: sarjojen summien sieventäminen kertaluokkalaskenta auttaa huomattavasti, ei tarvita tarkkoja tuloksia logaritmi- ja eksponenttilaskentaa rekursioyhtälöitä Funktioiden vertailuun riittävät peruslaskutoimitukset (+ / ) ja pari muuta: kaikille vakioille k > 0, b > 0 pätee log k n = o(n b ) (merkintä log k n tarkoittaa (logn) k ) kaikille vakioille a > 1, b > 0 pätee n b = o(a n ) Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 22(279)

23 Kertausta algoritmiikasta ja aikavaativuudesta Kertaluokkalaskennan perussäännöt Olkoon ohjelmanosan P 1 suoritusaika T 1 (n) = O(f(n)) Olkoon ohjelmanosan P 2 suoritusaika T 2 (n) = O(g(n)) Summasääntö T 1 (n) + T 2 (n) = O(max{f(n), g(n)}) Tulkinta: peräkkäisten suoritusten aikavaativuuden kertaluokan määrää osasuorituksista hitaampi. Summasäännön ansiosta voidaan kertaluokkatarkastelussa jättää vähempimerkityksiset termit kokonaan huomiotta. 23 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 23(279)

24 Kertausta algoritmiikasta ja aikavaativuudesta Tulosääntö T 1 (n) T 2 (n) = O(f(n) g(n)) Seuraus: jos T(n) = a f(n), (a on nollaa suurempi vakio), niin T(n)=O(f(n)). Siis: kertaluokkatarkastelussa voidaan positiiviset vakiokertoimet jättää huomiotta. Esimerkki 1-7: Jos T(n)=3n 2 +5n+8, = O(max(3n 2, 5n, 8)) (summasääntö) = O(3n 2 ) (tulosääntö) = O(n 2 ). 24 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 24(279)

25 Kertausta algoritmiikasta ja aikavaativuudesta Aikavaativuuden laskeminen algoritmista Sijoitus-, luku- ja tulostustoiminnot ovat yleensä O(1). poikkeus: suurten rakenteiden käsittely huomaa parametrien tyyppi taulukko arvoparametrina: kopiointi O(n) taulukko viite/muuttujaparametrina: viite O(1) Javassa oliot välitetään viitteinä (paitsi muuttamattomat perusluokat, kuten Integer ja String) Lausekkeen arvottaminen O(1) Paitsi tietysti, jos esimerkiksi kutsutaan aliohjelmaa! Taulukkoviittaukset O(1) Toimintojono (= peräkkäiset käskyt) Summasäännöllä Ehdolliset toiminnot T(ehdon arvottaminen) + T(valittava osa) [yleensä pahin tapaus] 25 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 25(279)

26 Kertausta algoritmiikasta ja aikavaativuudesta Toisto Tulosäännöllä ( i:s toistokerta) i Usein riittää laskea toistojen lkm T(toistettava osa) [pahin tapaus] Jos pahin tapaus on harvinainen, tilanne on analysoitava tarkemmin (laskettava pahat ja hyvät tapaukset erikseen). for (i = 0; i < n; i++) 1 if (i == n 1) 2 for (j = 0; j < n; j++) // tämä suoritetaan vain kerran, O(n) 3 a = a + 1; 4 else 5 x = x + 1; // tämä vakioaikainen suoritetaan useasti 6 26 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 26(279)

27 27 Kertausta algoritmiikasta ja aikavaativuudesta Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 27(279) Mitään oleellista ei saa jättää huomiotta. while (! etsi_väritys(k)) 1 k = k + 1; 2 aliohjelmakutsut T(parametrien välitys) + T(aliohjelman suoritus) aliohjelma erillisenä lohkona rekursiiviset rekursioyhtälöllä

28 1.3 Rekursiivisten algoritmien aikavaativuus 28 Kertausta algoritmiikasta ja aikavaativuudesta Aliohjelmakutsun aikavaativuus: lasketaan erikseen. T(parametrien välitys) + T(aliohjelman suoritus) aliohjelma erillisenä lohkona Esimerkki 1-8: Kertoma voidaan laskea seuraavalla rekursiivisella algoritmilla: public static int factorial(int n) { 1 if (n <= 1) 2 return 1; 3 else 4 return i * factorial(n 1); 5 } 6 Rivien 1-4 suoritusaika on selvästi O(1) Rivillä 5 kertolasku ja sijoitus ovat O(1), mutta Funktiokutsun arvottaminen vie aikaa! Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 28(279)

29 Merkitköön T(n) koko algoritmin suoritusaikaa syötteellä n 29 Kertausta algoritmiikasta ja aikavaativuudesta T(n)=d, kun n 1 (c, d vakioita) (1-1) T(n)=c+T(n 1), kun n >1. Puretaan äskeistä rekursiokaavaa: T(n)=c+T(n 1) (1-2) T(n 1) = c+t(n 2), ja T(n 2) = c+t(n 3), joten T(n 1) = c+ (c+t(n 3)) = 2c+T(n 3), joten T(n)=c+T(n 1) = c+(2c+t(n 3)) = 3c+T(n 3) Jatkamalla tähän tapaan huomaamme, että T(n)=ic+T(n i), kun i < n (1-3) Asetetaan i = n 1 (mennään rekursiossa pohjalle): T(n)=c(n 1) + T(1) = c(n 1) + d (1-4) T(n) = O(n). Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 29(279)

30 Kertausta algoritmiikasta ja aikavaativuudesta Rekursiokaavojen mahdollisuuksia Rekursiivisia kutsuja voi olla esim. 1, 2,..., logn, n,..., n/2, n kpl. Rekursion syötekoko voi olla esim. n 1, n 2, n/2, logn, n. Rekursion lisäksi työtä voidaan tehdä esim. O(1), O(logn), O( n), O(n), O(n 2 ). Rekursioyhtälö on siis esim. muotoa T(n)=cT(n/d) + O(n a ) tai (1-5) T(n)= n T( n) + O( n). Useimmissa (arkipäiväisissä) tapauksissa yllä käyttämämme purkaminen ja kokoaminen toimii riittävän hyvin. 30 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 30(279)

31 Kertausta algoritmiikasta ja aikavaativuudesta Master theorem Muotoa T(n) = at(n/b) + f(n) (1-6) oleviin rekursioyhtälöihin löytyy valmis ratkaisu helpohkolla säännöstöllä (ns. Master theorem), mutta sitä ei käsitellä tällä kurssilla. Säännöstö löytyy mm. Cormen&al kirjasta ja mahdollisesti esitellään Algoritmien suunnittelu ja analysointi -kurssilla. 31 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 31(279)

32 Esimerkki 1-9: Lomituslajittelun aikavaativuus: 32 Kertausta algoritmiikasta ja aikavaativuudesta Pätee myös monille muille hajoita-ja-hallitse -algoritmeille. T(n) = 2T(n/2) + d, missä d = O(n) (1-7) T(n/2) = 2T(n/4) + d/2 T(n/4) = 2T(n/8) + d/4 T(n/8) = 2T(n/16) + d/8 T(n/4) = 2T(n/8) + d/4 = 2 ( 2T(n/16) + d/8 ) + d/4 = 4T(n/16) + d/4 + d/4 = 4T(n/16) + d/2 T(n/2) = 2T(n/4) + d/2 = 2 ( 4T(n/16) + d/2 ) + d/2 = 8T(n/16) + d + d/2 = 8T(n/16) + 3d/2 T(n) = 2T(n/2) + d = 2 ( 8T(n/16) + 3d/2 ) + d = 16T(n/16) + 3d + d/2 = 16T(n/16) + 4d Rekursioyhtälön tulosta ei ole enää yhtä helppo nähdä, mutta ylläolevasta voidaan päätellä vaiheita olevan logaritminen määrä, ja kullakin tasolla tehtävän lineaarinen määrä työtä, eli yhteensä O(nlogn). Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 32(279)

33 Esimerkki 1-10: Fibonaccin lukujen laskenta määritelmän mukaan 33 Kertausta algoritmiikasta ja aikavaativuudesta public int fib(int n) { // Tehoton ratkaisu!!! 1 if (n < 2) 2 return 1; 3 else 4 return fib(n 1) + fib(n 2); 5 } 6 Rekursiokutsuja on kaksi, muuta työtä on vain vakioaika. Rekursioyhtälö T(n) = T(n 1) + T(n 2) + c, missä c on vakio. Rekursioyhtälöä purettaessa hieman enemmän, nähdään kutsujen määrän noudattavan Fibonaccin lukuja, mutta käsityötä olisi hieman enemmän, eikä tulos olisi niin ilmeinen. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 33(279)

34 Yläraja sensijaan on helppo arvioida yksinkertaistamalla kaavaa: 34 Kertausta algoritmiikasta ja aikavaativuudesta T(n 2) T(n 1) (miksi?) T(n) 2T(n 1) + c = 2(2T(n 2) + c) + c = 2(2(2T(n 3) + c) + c) + c = 2 i T(n i) + c(2 i 1) = O(2 n ). (1-8) Mutta onko tämä yläraja-arviointi liian väljä? Arviointi kertautuu joka kierroksella! Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 34(279)

35 Kertausta algoritmiikasta ja aikavaativuudesta Vastaavasti voidaan todistaa alaraja arvioimalla termiä T(n 2) alaspäin 1 verrattuna -- T(n 1):een: 2 1 T(n 2) -- T(n 1) ("arvaus") (1-9) 2 1 T(n 3) + T(n 4) + c -- (T(n 2) + T(n 3) + c) T(n 3) + T(n 4) + -- c -- T(n 2) T(n 3) + T(n 4) + -- c -- (T(n 3) + T(n 4) + c) T(n 4) -- c 2 2 T(n 4) c, mikä varmasti pitää paikkansa kunhan n kasvaa riittävän suureksi. 35 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 35(279)

36 Kertausta algoritmiikasta ja aikavaativuudesta 1 Näin ollen alarajatarkastelussa T(n 2) voidaan korvata -- T(n 1):lla: T(n) -- T(n 1) + c = -- ( 3 T(n 2) + c) + c (1-10) = -- ( 3 ( T(n 3) + c) + c) + c = T(n i) + c( 1) i i 3 = Ω( -- ). 2 n 3 Aikavaativuus on siis Ω( -- )jao(2 n ), joka tapauksessa eksponentiaalinen. 2 n Arvatenkin tarkka kantaluku on kultaisen leikkauksen suhdeluku ϕ Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 36(279)

37 Kertausta algoritmiikasta ja aikavaativuudesta Rekursiopuu Jos/kun ylläesitetty rekursioyhtälön purkaminen tuntuu hankalalta, (tätäkin) asiaa voidaan havainnollistaa piirtämällä. Rekursiopuuhun piirretään kullekin tasolle solmu kutakin rekursiokutsua kohti ja solmuun siinä käytetty työ. Kullakin tasolla lasketaan solmujen työt yhteen. Koko työ on kaikkien tasojen töiden summa. Piirtoteknisesti solmuja joudutaan yhdistelemään ja käyttämään " " merkintöjä, mutta työ kuitenkin voidaan puusta summata. Kuvan 1-2 puu lomituslajittelusta havainnollistaa rekursiota yksinkertaisessa tapauksessa. Kuvan 1-3 Fibonaccin funktiolle kuva ei anna aivan yhtä tarkkaa tulosta, mutta näyttää selkeästi aikavaativuuden ekponentiaalisuuden. 37 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 37(279)

38 38 Kertausta algoritmiikasta ja aikavaativuudesta Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 38(279) Työ 1 n T(n): n 2 n/2 T(n/2): n/2 T(n/2): n/2 logn 4 n/4 T(n/4): n/4 T(n/4): n/4 T(n/4): n/4 T(n/4): n/4 n Yhteensä Θ(nlogn) Kuva 1-2: Rekursiopuu yhtälölle T(n) = 2T(n/2) + n.

39 39 Kertausta algoritmiikasta ja aikavaativuudesta Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 39(279) T(n) n T(n 1) T(n 2) T(n 2) T(n 3): T(n 3): T(n 4) Kuva 1-3: Rekursiopuu Fibonaccin funktiolle T(n)=T(n 1)+T(n 2)+c n/2

40 Sanapituuden vaikutus 40 Kertausta algoritmiikasta ja aikavaativuudesta Perusoperaatiot k bittisille luvuille ovat (liki) vakioaikaisia vain jos prosessorimme suorittaa ne rinnakkain k loogisella piirillä. Yleensä prosessorit tukevat sanapituutta 32 tai 64. Mikrokontrollerit yleensä hieman vähemmän. Esimerkki 1-11: Potenssiin korotus suurilla luvuilla: x n Suoraviivainen algoritmi: BigInteger pow(biginteger x, int n) { 1 BigInteger r = new BigInteger("1"); 2 for (int i = 0; i < n; i++) 3 r = r.multiply(x); 4 return r; 5 } 6 Aikavaativuus O(n), vai onko??? Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 40(279)

41 Kertausta algoritmiikasta ja aikavaativuudesta Mikä on BigInteger.multiply():n aikavaativuus??? JavaAPI:n dokumentaatio ei (tässäkään) anna mitään vihjettä! Lähdekoodista nähdään kyseessä olevan koulualgoritmi ("kertolasku alekkain"). Koulualgoritmilla kerrottavat luvut a ja b, lukujen pituudet loga, logb bittiä, yhden kertolaskun aikavaativuus on O(loga logb). pow -funktiossa r:n pituus on (lopussa ja keskimäärin) O(nlogx) bittiä, x:n pituus on logx bittiä. Koko aikavaativuus on siten n O(nlogx) O(logx) = O(n 2 log 2 x), eli O(n 2 ) jos x on pieni vakio. 41 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 41(279)

42 Kertausta algoritmiikasta ja aikavaativuudesta Rekursiivinen hajoita-ja-hallitse -algoritmi: (*) x n = ( xx) n 2 jos n on parillinen x n = xxx ( ) n 2 jos n on pariton BigInteger pow2(biginteger x, int n) { 1 if (n == 0) 2 return new BigInteger("1"); 3 if (n == 1) 4 return x; 5 if (n%2 == 0) // n parillinen 6 return (pow2(x.multiply(x), n/2 ) ); // ( xx) n 2 7 else 8 return (x.multiply(pow2(x.multiply(x), n/2 ))); // xxx ( ) n 2 9 } 10 T(n) = T(n/2) + 2T m (pahin tapaus kun n = 2 k 1) T(n) = T(n/2) + T m (paras tapaus kun n = 2 k ). 42 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 42(279)

43 Kertausta algoritmiikasta ja aikavaativuudesta Mikä on kertolaskun aikavaativuus T m nyt? Logaritminen määrä rekursiotasoja, jokaisella yksi rekursiokutsu, 1-2 multiply() kutsua. Jos kertolasku olisi O(1), aikavaativuus olisi O(logn), jos kertolasku olisi O(n) koko aikavaativuus olisi mukava O(nlogn)??? Kirjoitetaan kukin osa (rekursiokutsu, molemmat kertolaskut) tarkemmin: T(n, x) = T(n/2, x 2 ) + logx n logx + logx logx (1-11) = T(n/2, x 2 ) + logx (nlogx + logx) = T(n/2, x 2 ) + (n + 1)log 2 x Kun rekursiossa edetään, x kasvaa ja n pienenee. Tasolla i on x i = n n i = i Näin ollen koko aikavaativuus on logn T(n, x) = log x 2i 2 n (1-12) i = 0 2 i x 2i ja 43 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 43(279)

44 Kun summan termeistä viimeinen on suurempi kuin muut yhteensä, tarkastelemme vain sitä: 44 Kertausta algoritmiikasta ja aikavaativuudesta T(n, x) 2 x 2 logn log 2 n logn 2 (1-13) = 2( log x n ) 2 n = 2( nlog x) 2 n (1-14) n n = O(n 2 log 2 x) Jos/kun kantaluku x on pienehkö vakio, on aikavaativuus tuttu O(n 2 ). Käytännössä kertolaskuja tulee hieman vähemmän kuin edellisessä suoraviivaisessa algoritmissa, pahin tapaus ei aina toteudu, ja kaavan 1-12 summa ei mene aivan logn:ään asti. Toteutuksesta mitattuna rekursiivinen algoritmi on pienellä kantaluvulla kertaa nopeampi, riippuen potenssista ja alustasta. Suurilla kantaluvuilla ero hieman pienenee. Myös Java API (1.6) käyttää tätä algoritmia. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 44(279)

45 1.4 Aikavaativuuden rajojen todistaminen 45 Kertausta algoritmiikasta ja aikavaativuudesta Hankalassa tapauksessa voi olla helpompaa todeta (todistaa) algorimin tai ongelman aikavaativuudelle erilliset ala- ja ylärajat. Esim. yllä Fibonaccin funktio. Paitsi algoritmeja, voimme analysoida myös ongelmia. Mikä on alaraja annetun ongelman ratkaisemiseen algoritmisesti? Deterministisesti, yleisessä tapauksessa. Päätöspuut Osoitetaan esimerkkinä, ettei vertailuun perustuva lajittelu voi olla nopeampi kuin Ω(nlogn). Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 45(279)

46 Kertausta algoritmiikasta ja aikavaativuudesta Päätöspuu on binääripuu joka kuvaa ratkaisun etsimistä. Juuressa on alkutilanne, ts. kaikki ratkaisut ovat mahdollisia. Kussakin solmussa tehdään yksi vertailu (tai muu operaatio) ja sen mukaan päätös edetä jompaan kumpaan alipuuhun. Alipuun haaroihin on mahdolliset ratkaisut on jaettu kahteen osaan, ts. kullakin päätöksellä mahdollisten ratkaisujen joukko vähenee. Lehtisolmuissa on jäljellä vain yksi ratkaisu. Solmun syvyys kuvaa ko. ratkaisuun päätymiseen vaadittujen vertailujen määrää. Puun korkeus = pahin tapaus. Puun matalin lehtisolmu = paras tapaus. Vertailut ja päätökset riippuvat käytetystä algoritmista. Päätöspuu kuvaa algoritmin toiminnan kaikki mahdolliset haarat. Yksi suoritus on yksi polku juuresta lehtisolmuun. 46 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 46(279)

47 Kertausta algoritmiikasta ja aikavaativuudesta < < < < < < < < < kyllä < < < < < kyllä ei ei < < kyllä < < < < < < < < < < < < < < < < < Kuva 1-4: Upotuslajittelun päätöspuu, n =3,n! =6. Esimerkki 1-12: Kuva 1-4 esittää upotuslajittelun päätöspuun syötteen koolla n = 3. Alussa kaikki kuusi vaihtoehtoa ovat mahdollisia. Ensimmäisen vertailun < jälkeen vaihtoehdot jakautuvat kahtia. Jos vertai- ei < < < < < kyllä < < < < < < < kyllä ei ei < < < < 47 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 47(279)

48 Kertausta algoritmiikasta ja aikavaativuudesta lun tulos oli tosi, jäljelle jäävät vain ne vaihtoehdot, joissa edelsi :tä. Epätoden puolelle jäivät loput. Päätöspuun korkeus yleisen lajittelun tapauksessa: Erilaisia mahdollisia järjestyksiä n! kappaletta Lehtisolmuja päätöspuussa siten (vähintään) n! kpl! Olipa algoritmi mikä tahansa. Haarautumissolmuja (vähintään) n! 1 kpl Solmuja yhteensä (vähintään) 2n! 1 kpl Puun korkeus Ω(log(2n! 1)) = Ω(log(n!)). Käytetään yksinkertaistettua versiota Stirlingin kaavasta: n! (n/e) n (1-15) log(n!) log((n/e) n )=nlogn nloge (1-16) log(n!) = O(nlogn) 48 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 48(279)

49 Kertoman logaritmia voidaan arvioida myös alaspäin: 49 Kertausta algoritmiikasta ja aikavaativuudesta log(n!) (n/2)log(n/2) = (n/2)logn (n/2) (1-17) log(n!) = Ω(nlogn) Optimaalisessa päätöspuussa jokaisen päätöspolun pituus on toisin sanoen Θ(nlogn). Tätä tehokkaampaa vertailuihin perustuvaa lajittelualgorimia ei voi olla olemassa. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 49(279)

50 1.5 Kokeellinen aikavaativuuden määrääminen 50 Kertausta algoritmiikasta ja aikavaativuudesta Joskus analyysin keinot eivät ole mahdollisia/järkeviä/riittävän tarkkoja! Emme osaa analysoida. Emme tiedä tarpeeksi syötteen rakenteesta (tai sen vaikutuksesta). Lähdekoodi (tai sen osa) ei ole käytettävissä (tai ymmärrettävissä). Tarvitsemme tarkempia tuloksia myös vakiokertoimista. Tavoitteet Selvittää aikavaativuuden kertaluokka. Selvittää (likimääräinen) aikavaativuusfunktio prosessoriajalle (sekunneteina tms.) käytettävälle alustalle. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 50(279)

51 Kertausta algoritmiikasta ja aikavaativuudesta Miten Pienehkö ohjelmanosa kerrallaan. Usealla eri syötteen koolla. Vakioitu tai satunnainen syöte, riippuen algoritmista. Usean ajon keskiarvo (jos satunnainen syöte) tai minimi (jos vakiosyöte). Kasvata syötteen kokoa aluksi eksponentiaalisesti (esim 2 tai 10). Kun aika alkaa kasvaa, käytä tarkempia askeleita, erityisesti jos aikavaativuus on suuri (eksponentiaalinen). Kasvata ainakin useisiin sekunteihin (pari kertaluokkaa mittaustarkkuutta suuremmaksi). Jos algoritmi on liian nopea mitattavaksi tarkasti kohtuullisen kokoisilla syötteillä, toista algoritmia useasti. 51 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 51(279)

52 Kertausta algoritmiikasta ja aikavaativuudesta Tarkkaile peräkkäisten syötekokojen ajan suhdetta, esim jos syöte aina kaksinkertaistetaan: jos aika kaksinkertaistuu: lineaarinen jos aika hieman yli kaksinkertaistuu: esim. O(nlogn) (voi olla vaikea erottaa lineaarisesta, vaatii pidemmän jänteen). jos aika nelinkertaistuu: neliöllinen jos aika 8-kertaistuu: kuutiollinen Jos syötteen kasvattaminen yhdellä kasvattaa aikavaativuuden kaksinkertaiseksi: eksponentiaalinen. Tulosten esittäminen käyränä ja vertailufunktioiden piirtäminen auttaa näkemään oleelliset muutokset (kts. alla). Logaritminen asteikko on yleensä parempi. Joissakin mittaustuloksissa esiintyy heittoja, lähinnä välimuistien ja roskienkeruun takia. Kun syöte kasvaa yli välimuistista, aikavaativuus alkiota kohti usein kaksin- kolminkertaistuu (katso Taulukon käsittely peräkkäin/hajasaantina: sivulla 232). 52 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 52(279)

53 Ajan mittaaminen 53 Kertausta algoritmiikasta ja aikavaativuudesta Miten erottaa algoritmin käyttämä aika muiden ohjelmien, käyttöjärjestelmän, roskienkeruun, jne käyttämästä ajasta? Valitettavasti JavaAPI ei suoraan mahdollista prosessin/säikeen ajankäytön mittaamista. C:ssä clock() palauttaa prosessin käyttämän ajan mikrosekunteina. Java-ohjelmaan on mahdollista sisällyttää kutsuja erillisiin mittaohjelmiin, mutta se ei ole siirrettävä tekniikka (verkosta löytyy valmiita HOWTO -ohjeita). Helpommalla pääsee kun käyttää reaaliaikakelloa java.util.date -luokan avulla ja pyrkii minimoimaan siitä aiheutuvat virheet. Date palauttaa ajan millisekunteina. Minimoi muut prosessit. Älä tulosta mittauksen aikana. Aja useaan kertaan samalla syötteellä, ota ajoista minimi. Käytä riittävän suuria syötteitä tai saman operaation toistamista useasti (suoritusaika vähintään 0,1s). Esim. Ajastin.java kurssin www-sivulla. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 53(279)

54 Esimerkki 1-13: String vrt. StringBuffer (StringTest.java) 54 Kertausta algoritmiikasta ja aikavaativuudesta Toteutetaan Vector<Integer>.toString() eri tavoin. java.util.vector<integer>.tostring() (valmis toteutus: AbstractCollection) String: s = s + v.get(i).tostring() + ", "; StringBuffer: sb.append(v.get(i).tostring() + ", ") StringBuilder: sb.append(v.get(i).tostring() + ", ") StringBuilder2: sb.append(v.get(i).tostring); sb.append(", "); StringBuilder3: new StringBuilder(n*12). Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 54(279)

55 55 Kertausta algoritmiikasta ja aikavaativuudesta Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 55(279) 1M M/s n^2 Vector.tStr SBuffer SBuilder SBuilder2 SBuilder3 String + T(ms) M Kuva 1-6: Merkkijonon kokoamisen aikavaativuus, logaritminen x ja y. n

56 56 Kertausta algoritmiikasta ja aikavaativuudesta Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 56(279) M/s n^2 Vector.tStr SBuffer SBuilder SBuilder2 SBuilder3 String M n Kuva 1-7: Merkkijonon kokoamisen aikavaativuus, lineaarinen y. T(ms)

57 Taulukko 1-5: Merkkijonon kokoamisen aikavaativuus (ms) 57 Kertausta algoritmiikasta ja aikavaativuudesta n Vector. tostring String Buffer String Builder String Builder2 String Builder3 String Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 57(279)

58 Taulukko 1-5: Merkkijonon kokoamisen aikavaativuus (ms) 58 Kertausta algoritmiikasta ja aikavaativuudesta n Vector. tostring String Buffer String Builder String Builder String Builder3 String + Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 58(279)

59 1.6 Abstraktit tietotyypit (*) 59 Kertausta algoritmiikasta ja aikavaativuudesta Abstraktit tietotyypit (ATT, ADT (abstract data type)) (joskus abstrakti tietorakenne) ovat malleja tiedon esittämiseksi ja käsittelemiseksi. Abstrakti tietotyyppi määritellään kuvaamalla operaatiot (funktiot, proseduurit, metodit) joilla tietotyypin esittämää tietoa käsitellään. Operaatiot (yms) = abstraktin tietotyypin liittymä. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 59(279)

60 Kertausta algoritmiikasta ja aikavaativuudesta Vaihtoehtoinen havainnollistus ADT on kokoelmien hallinnan apuväline. Ripustetaan elementit ADT:n hallittavaksi. ADT Hyötytieto Looginen järjestys Kuva 1-8: ADT kokoelman ylläpidon apuvälineenä. Keskitytään itse elementteihin ja niiden keskinäisiin suhteisiin! ADT:n valinta määrää talletettujen elementtien loogisen järjestyksen (jos sellaista tarvitaan). Joskus vain osa elementeistä on "näkyvissä" (kun emme muita tarvitse). 60 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 60(279)

61 Kertausta algoritmiikasta ja aikavaativuudesta Esimerkki 1-14: Joukko (abstraktina tietotyyppinä) on kokoelma keskenään samantyyppisiä alkioita, vaikkapa verkon solmuja. Joukkomallille tyypillinen piirre on se, että sama alkio voi sisältyä joukkoon vain yhtenä esiintymänä kerrallaan. Joukkoja käsitellään esimerkiksi muodostamalla kahden joukon yhdiste tai tutkimalla, kuuluuko jokin alkio joukkoon. Joukkotyypin liittymä voi sisältää vaikkapa seuraavankaltaisen osan: // returns union of this set and set B 1 public Set<E> union(set<e> B); 2 // returns whether object x is a member of this set or not 3 public boolean member(<e> x); 4 61 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 61(279)

62 Kertausta algoritmiikasta ja aikavaativuudesta Liittymä antaa ADT:n käyttäjälle kaiken tarpeellisen tiedon tyypin käyttämiseksi: tyypit sallitut operaatiot (metodit) operaatioiden parametrit operaatioiden tuloksen tyypin operaatioiden käyttöä rajoittavat ehdot ADT toteutetaan siten, että liittymässä kuvatut operaatiot toimivat kuvatulla tavalla! Toteutus sisältää operaatioiden ohjelmakoodin ja mallia vastaavan todellisen toteutustietorakenteen määrittelyn. Toteuttamisen helpottamiseksi toteuttaja voi laatia lisää operaatioita omaan käyttöönsä. Nämä operaatiot eivät näy käyttäjälle (kuten ei mikään muukaan toteutukseen liittyvä asia). 62 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 62(279)

63 Määritelmä 1-15: Muuttujan tietotyyppi on kyseisen muuttujan sallittujen arvojen joukko. 63 Kertausta algoritmiikasta ja aikavaativuudesta Määritelmä 1-16: Tietorakenne on kokoelma toisiinsa kytkettyjä muuttujia. Kyseessä on siis ohjelmointikielen rakenne josta bitit voidaan periaatteessa piirtää näkyviin. Joskin Javan tapauksessa bittien täsmällinen piirtäminen vaatisi hieman enemmän paneutumista Javan toteutukseen. Pelkkä kielen dokumentaatio ei riitä. taulukko objektit viittein kytketyt objektit tiedosto Tietorakenne: ohjelmointikielen rakenne (bitit piirrettävissä). Abstrakti tietotyyppi: kokoelma-abstraktio (toteutus tuntematon). Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 63(279)

64 1.7 Kertaus abstrakteihin tietotyyppeihin (*) 64 Kertausta algoritmiikasta ja aikavaativuudesta Aloitetaan yksinkertaisesta, yleiskäyttöisestä kokoelmasta, listasta. Listalla on runsaasti variaatioita. Abstraktin tietotyypin tarkoitus on hallita alkiokokoelmaa niin, että kokoelmaa voidaan käyttää käyttäjälle tarkoituksenmukaisella tavalla tehokkaasti Alkiokokoelmien hallinta ja käyttö edellyttää mahdollisuutta. lisätä kokoelmaan uusi alkio hakea alkioita kokoelmasta poistaa alkioita kokoelmasta muuttaa kokoelman alkioita käydä läpi kokoelman alkioita Aina ei tosin tarvita näitä kaikkia mahdollisuuksia. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 64(279)

65 Mitä kokoelmaan (esim. listaan) talletetaan? 65 Kertausta algoritmiikasta ja aikavaativuudesta Tarkoitus on lisäksi pystyä samalla ADT:llä hallitsemaan erilaisia alkiokokoelmia. Abstraktin tietotyypin tulee olla mahdollisimman riippumaton hallittavien alkioiden tyypistä. Parametroidaan abstrakti tietotyyppi alkioiden tyypillä! Esimerkki 1-17: Listatyypin liittymä alkaa tekstillä: public class List<E> { 1 Tässä E kuvaa alkioiden tyyppiä, jota liittymä ei siis kiinnitä. Muodollinen tyyppiparametri (formal type parameter), kuten muodollinen parametri aliohjelmissa. Listoja luotaessa parametrityyppi sitten kiinnitetään: List<Integer> lukulista = new List<Integer>(); 1 List<List<Integer>> listalista = new List<List<Integer>>(); 2 List<Henkilo> hlolista new List<Henkilo>(); 3 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 65(279)

66 Tehtäessä geneerisiä algoritmeja kokoelmille, voimme rajoittaa tarvittaessa mahdollisten alkioiden tyyppiä: 66 Kertausta algoritmiikasta ja aikavaativuudesta Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 66(279) public boolean vertailuatms(list<? extends Comparable>) 1

67 1.8 Lista (*) 67 Kertausta algoritmiikasta ja aikavaativuudesta Lista abstraktina tietotyyppinä Esimerkki 1-18: Lista voidaan esittää vaikkapa luettelemalla listaan sisältyvät alkiot peräkkäin. Viisialkioinen lista L kuvataan esimerkiksi seuraavalla tavalla: L = a 1, a 2, a 3, a 4, a 5. (1-18) Tyhjä lista esitetään tällöin muodossa L =. (1-19) Listan esitysmuoto valitaan aina tilanteen mukaisesti. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 67(279)

68 Kertausta algoritmiikasta ja aikavaativuudesta Alkioiden peräkkäisyyssuhde. Alkioiden välillä vallitsee yksikäsitteinen edeltäjä-seuraaja -suhde. alkio a 2 edeltää alkiota a 3 alkio a 3 seuraa alkiota a 2 Listan ensimmäisellä alkiolla ei ole edeltäjää. Listan viimeisellä alkiolla ei ole seuraajaa. Käsitellessämme listassa olevia alkioita, meidän on pystyttävä yksilöimään kukin alkio, ja sen sijainti listassa. Asema (listasolmu) Listan i:nnen alkion etäisyys listan alusta on i 1. Jos käytetään tavallista ohjelmointikielen taulukkoa, niin sekä etäisyys alusta, että kunkin alkion sijainti ovat yksikäsitteisiä. Mutta: listaan on voitava mm. lisätä keskelle alkioita, jolloin uuden alkion seuraajien etäisyys alusta muuttuu! Tarvitaan hieman abstraktimpi sijainnin käsite! 68 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 68(279)

69 Kertausta algoritmiikasta ja aikavaativuudesta Kullakin listan alkiolla on oma asemansa (position) listassa. Listan ensimmäiseen käytössä olevaan aseman ja listan viimeisen käytössä olevan aseman jälkeiseen asemaan pystytään viittaamaan. Aseman tyyppi ja käytös alkioita lisättäessä ja poistettaessa riippuu listan toteutustavasta. 69 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 69(279)

70 70 Kertausta algoritmiikasta ja aikavaativuudesta Abstraktin listan operaatiot Määritelmä 1-19: Seuraava luettelo kuvaa tällä kurssilla käytettävän tietorakennekirjaston listaoperaatiot. Asemana käytetään viitettä listasolmuun (ListNode). Elementtityyppinä käytämme geneeristä E:tä. (parametrien tyypit: E x, ListNode p, TraLinkedList L) 1) TraLinkedList<Alkiotyyppi> TraLinkedList<Alkiotyyppi>() Muodostaa tyhjän listan L. Alkiotyyppi voi olla mikä tahansa luokka. 2) ListNode L.first() Palauttaa listan L ensimmäisen alkion aseman. Jos L on tyhjä lista, palauttaa aseman L.EOL. 3) ListNode L.last() Palauttaa listan L viimeisen alkion aseman. Jos L on tyhjä lista, palauttaa aseman L.EOL. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 70(279)

71 Kertausta algoritmiikasta ja aikavaativuudesta 4) void L.insert(p, x) Lisää alkion x listaan L asemaan p (tarkemmin: asemassa p olleen alkion eteen). Jos p = L.EOL, kohdistuu lisäys listan loppuun. Jos taas asemaa p ei listassa L lainkaan ole, on vaikutus määrittelemätön. 5) void L.remove(p) Poistaa listasta L asemassa p olevan alkion. Jos p = L.EOL tai asemaa p ei listassa L lainkaan ole, on vaikutus määrittelemätön. 6) ListNode p.next() Palauttaa asemaa p seuraavan aseman listassa. Jos p on listan viimeisen alkion asema, palauttaa p.next aseman L.EOL ja jos p = L.EOL (tai listassa ei ole asemaa p) on p.next määrittelemätön. 7) ListNode p.previous() Palauttaa asemaa p edeltävän aseman listassa. Jos p on listan ensimmäisen alkion asema (tai listassa ei ole asemaa p), on p.previous määrittelemätön. 8) E p.getelement() Palauttaa asemassa p olevan alkion. Jos p = L.EOL on tulos määrittelemätön. 71 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 71(279)

72 Kertausta algoritmiikasta ja aikavaativuudesta Listan läpikäynti Yleensä lista läpikäydään käyttäen listasolmuja ja alkuehtoista toistoa. Jollei listaa muuteta, eikä tarvita useaa limittäistä toistoa, myös foreach - toisto toimii, kts. alla LinkedList:n yhteydestä. Listaoperaatioiden aikavaativuus first, next, getelement ja listan luonti tulisi aina olla O(1) (vakioaikaisia) jotta läpikäynti olisi tehokasta. insert, remove, previous, last ja EOL on mahdollista (jopa helppoa) tehdä vakioaikaisiksi, joten jos/kun niitä tarvitaan, niin ne on syytä tehdä vakioaikaisiksi. Lähinnä taulukkototeutuksessa osa voi olla O(listan pituus), mutta Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 72(279)

73 Esimerkki 1-20: Esimerkki: listojen samuuden vertailu. Listat ovat samat, jos ne ovat yhtä pitkät ja niissä on samat alkiot samassa järjestyksessä. 73 Kertausta algoritmiikasta ja aikavaativuudesta public boolean comparelists(tralinkedlist L1, TraLinkedList L2) { 1 ListNode p1 = L1.first(); 2 ListNode p2 = L2.first(); 3 while ((p1!= L.EOL) && (p2!= L.EOL)) { 4 if (! p1.getelement().equals(p2.getelement())) 5 return false; 6 p1 = p1.next(); 7 p2 = p2.next(); 8 } 9 if (p1 == L1.EOL && p2 == L2.EOL) 10 return true; 11 else 12 return false; 13 } 14 Aikavaativuus? Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 73(279)

74 Kertausta algoritmiikasta ja aikavaativuudesta java.util.linkedlist Operaatiot kuten Vector:lle, mutta aikavaativuudet erilaiset. Osa Javan vakiokirjastoa, kts. API:n dokumentaatio. Asemaa (listasolmua) ei paljasteta käyttäjälle. Suorat get(index), add(index, element), jne operaatiot ottavat parametrinaan indeksin (järjestysnumeron) listan alusta. Aikavaativuus O( L ) jos joutuvat etsimään indeksin!! Jollei, niin esim. lisäys ja poisto vakioaikaisia. Juuri päinvastoin kuin Vector -luokalla. LinkedList<Integer> L = new LinkedList<Integer>(); 1 for (int i = 0; i < N; i++) // yhteensä O(N) 2 L.add(i, i); // lisäys loppuun O(1) 3 for (int i = 0; i < N; i++) // yhteensä O(N 2 ) 4 L.add(i/2, i); // lisäys keskelle O(N) 5 for (int i = 0; i < N; i++) // yhteensä O(N 2 ) 6... = L.get(i); // indeksin haku O(N) 7 Läpikäynti O(N 2 )??? 74 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 74(279)

75 Tehokkaaseen läpikäyntiin on käytettävä iteraattoria! 75 Kertausta algoritmiikasta ja aikavaativuudesta Iteraattori toimii osoittimena kuten yllä käyttämämme asemamuuttuja, mutta se viittaa alkioiden (listasolmujen) väliin, eikä asemaan (listasolmuun)! Määritelmä 1-21: java.util.listinterator operaatiot (tärkeimmät). 1) ListIterator i = L.listIterator() Luo ja alustaa uuden iteraattorin. 2) boolean i.hasnext() kertoo onko seuraavaa alkiota olemassa vai ei. 3) E i.next() siirtää iteraattoria seuraavaan väliin ja palauttaa yli hyppäämänsä alkion. 4) E i.previous() siirtää iteraattoria edelliseen väliin ja palauttaa yli hyppäämänsä alkion. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 75(279)

76 Kertausta algoritmiikasta ja aikavaativuudesta 5) void i.add(x) lisää elementin x iteraattorin osoittamaan väliin. Uusi elementti ei tule mukaan läpikäyntiin next-operaatioilla, mutta jos seuraavaksi kutsutaan previous-operaatioita, se palauttaa tämän uuden alkion.. 6) void i.remove() poistaa elementin joka viimeksi hypättiin yli next:llä tai previous:lla. Esimerkki 1-22: Listan läpikäynti iteraattorilla ja alkuehtoisella toistolla. LinkedList L; ListIterator i = L.listIterator(); 3 while (i.hasnext()) // yhteensä O(N) 4... = p.next() 5 Kokoelmaa voi muuttaa kesken läpikäynnin vain tämän iteraattorin add/remove -metodeillä. Kaksi sisäkkäistä läpikäyntiä ei saa muuttaa listaa (kuten purge:ssa yllä). Yksinkertaisiin läpikäynteihin tämä on suhteellisen näppärä. 76 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 76(279)

77 Esimerkki 1-23: Alkion x kaikkien esiintymien poisto. 77 Kertausta algoritmiikasta ja aikavaativuudesta ListIterator i = L.listIterator(); 1 while (i.hasnext()) // O(N) 2 if (x.equals(p.next())) 3 i.remove(); 4 foreach -toisto Jos listaa ei aiota muuttaa kesken läpikäynnin, iteraattorikin on turha. Java >=1.5 tukee "tee kaikille alkioille" -toistoa Iterable rajapinnan toteuttaville kokoelmille: for(e x : L) // E on alkiotyyppi, L kokoelma 1 x.foo(); 2 Tämä on toteutettu iteraattorilla. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 77(279)

78 Kertausta algoritmiikasta ja aikavaativuudesta java.util.linkedlist:n huonot puolet Iteraattorit luontuvat vain yksinkertaiseen peräkkäiseen läpikäyntiin. Monimutkaisemmassa tapauksessa joudutaan turvautumaan tehottomampiin indekseihin. Kts esim. purge, TraListMerge.java vrt. JavaListMerge.java. 78 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 78(279)

79 Kertausta algoritmiikasta ja aikavaativuudesta Listan käyttökohteet: Mikä tahansa, missä kokoelmaa käydään lävitse peräkkäisjärjestyksessä. Erityisesti, jos kokoelmalla on jokin järjestys. Erityisesti, jos keskelle kokoelmaan kohdistetaan lisäys- tai poistooperaatioita. (jotka taulukossa ovat raskaita!) Esim: "laske kokoelman alkoiden summa". Peräkkäisrakenne ok Esim: "etsi annetun puhelinnumeron haltijan nimi". peräkkäisrakenne liian hidas etsimiseen lista on huono vaihtoehto 79 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 79(279)

80 Lista on yleiskäyttöinen tietorakenne. 80 Kertausta algoritmiikasta ja aikavaativuudesta Läheskään aina ei tarvita kaikkea listan toiminnallisuutta. Näissä tapauksissa riittää rajoittaa operaatiojoukkoa sopivaksi, yleensä saantipaikan suhteen Hyöty: saadaan huomattavasti yksinkertaisemmat operaatiot. helppolukuisempi ohjelma vähemmän virhemahdollisuuksia helpompi toteuttaa yksikäsitteisempi Listan rajoitettuja muotoja: Pino: lisäys ja poisto päältä Jono: lisäys häntään, poisto keulalta Pakka: lisäys ja poisto päistä Rengas: listan alku ja loppu samaistettu Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 80(279)

81 Taulukko 81 Kertausta algoritmiikasta ja aikavaativuudesta Lista ei tue alkion muuttamista, eikä hakemista suoraan (vakioajassa) sijainnin perusteella. Alkion muuttaminen vaatii poiston ja lisäyksen. Alkioiden käsittely mielivaltaisessa järjestyksessä (hajasaanti) on mahdotonta (tai raskasta). Jos sekä peräkkäiskäsittely, että mielivaltaisessa järjestyksessä käsittely ovat tärkeitä, tarvitaan (abstraktia) taulukkotyyppiä. Taulukon alkiot ovat keskenään peräkkäissuhteessa ( lista). Taulukon alkion asema selviää indeksoimalla (ts. (suhteellinen) etäisyys taulukon alusta). Indeksit ovat kokonaislukutyyppiä (tai lueteltua tyyppiä), niillä voidaan jopa laskea. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 81(279)

82 Kertausta algoritmiikasta ja aikavaativuudesta Taulukon operaatiot kuten listalla: Asemana käytetään indeksiä taulukon alusta. Taulukon luonnissa tosin on syytä antaa taulukon alkumitat. Koska lisääminen on taulukossa raskasta, taulukon peruspäivitysoperaatio onkin indeksiin päälle vienti: A.set(i, x) jotta voisimme viitata taulukon rajoihin, tarvitaan A.first() ja A.last() Operaatioiden set, first, last, getelement ja taulukon luonti aikavaativuus on O(1). next ja previous ovat vain indekseillä laskemista. Jos kuitenkin taulukon luonnissa taulukko alustetaan (kuten Javassa) se vie lineaarisen ajan. Operaatioiden insert(), remove() ja force() aikavaativuus on O(taulukon koko), tai O(taulukon loppuosan pituus). jos lisäystä tai poistoa keskelle/keskeltä tarvitaan, ei taulukko yleensä ole hyvä vaihtoehto. 82 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 82(279)

83 Kertausta algoritmiikasta ja aikavaativuudesta Avoin/kiinteänkokoinen taulukko Avoimessa taulukossa lisäykset/poistot laajentavat/pienentävät taulukkoa yhden alkion verran, force laajentaa tarpeen mukaan Taulukko voi olla avoin joko molemmista päistä tai vain toisesta päästä Kiinteäkokoisessa taulukossa insert ja remove on yleensä jätetty pois Jos em. operaatiot sallitaan kiinteäkokoisessa taulukossa, kyseessä on hylly. Hyllyssä lisäys keskelle tiputtaa alkion laidalta pois, poisto keskeltä lisää tyhjän paikan laidalle. Object[] A1; // täysin avoin 1 Object[1..] A2; // ylhäältä avoin 2 Object[..10] A3; // alhaalta avoin 3 Object[1..10] A4; // kiinteä koko 4 Huomaa first ja last operaatioiden tarpeellisuus. Javassa alhaalta avoin taulukko ei suoraan onnistu. Rajoituksen voi kiertää kuvauksella (map) tai käyttämällä omaa indeksointia, esim: 83 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 83(279) A[abs(i)*2 + ((i < 0)? 1 : 0)] 1

84 Kertausta algoritmiikasta ja aikavaativuudesta java.util.vector Taulukko (jolle on toteutettu myös (tehottomat) listaoperaatiot). Käytössä olevat asemat indeksoitu 0..size() 1. Toteuttaa listan operaatiot taulukon aikavaativuuksin. get(i) vakioaikainen. set(i, x) vakioaikainen. add(x) ja add(i, x) listan loppuun vakioaikainen (samoin remove). add(i, x) keskelle lineaarinen aikavaativuus (samoin remove). V.firstIndex == 0. V.size() kertoo alkioiden määrän. V.add(V.size()+1, x) tai V.set(V.size(), x) antaa ArrayIndexOutOfBoundsException. setsize() asettaa alkioiden määrän eksplisiittisesti, jos koko on enemmän kuin aiemmin, lisätään null:ja. 84 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 84(279)

85 Kertausta algoritmiikasta ja aikavaativuudesta Kapasiteetti vs. alkioiden määrä. Vektorilla on aluksi vakiokapasiteetti, esim 10 alkiota. Tyhjällä vektorilla nämä ovat kaikki laajennusvaraa. Alkukapasiteetti voidaan antaa konstruktorin parametrina. Alkioita lisättäessä voidaan tarvita lisäkapasiteettiä. Tässä uudet Java-versiot ovat parantuneet. Jollei lisäystä ole annettu, kasvatetaan taulukko kaksinkertaiseksi. Keskimääräinen kasvatuksen aikavaativuus on nyt vakio (2). Aiemmin se oli n/c. Toistuvan lisävarauksen välttämiseksi voi käyttää ensurecapacity() operaatiota. 85 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 85(279)

86 1.9 Puu (*) 86 Kertausta algoritmiikasta ja aikavaativuudesta Listan ongelma: Lista on pitkä, joten siitä etsiminen on hidasta. Idea: pistetään "lista puoliksi"! Oikeastihan oikeaa listaa ei niinvain? pistetä puoliksi. Ensin selvitetään kummassa puoliskossa alkio on ja haetaan vain sieltä puolet vähemmän läpikäytävää. Pistetään nämäkin puoliskot puoliksi taas puolet vähemmän läpikäytävää. logn kertaa toistettuna vain nämä logn päätöstä, ei lainkaan selattavaa. Tämä oli siis binäärihaku.? Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 86(279)

87 87 Kertausta algoritmiikasta ja aikavaativuudesta Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 87(279) Miten tämä on toteutettavissa kokoelmana? Haaroitetaan lista: Edeltäjä seuraaja -käsitteen sijaan tulee edeltäjä 2 seuraajaa. Puu antaa kokoelman alkioille hierarkkisen järjestyksen (vrt. listan peräkkäinen järjestys).

88 Kertausta algoritmiikasta ja aikavaativuudesta Puun solmujen järjestykset Solmut voidaan luetella monessa eri "kanonisessa" järjestyksessä. Yleisimmät ovat esi-, sisä-, jälki- ja tasoittainen järjestys (TRAI). Binääripuu Yleisen puun solmulla voi olla mielivaltainen määrä lapsia. Tämä hankaloittaa toteutusta (lista), hahmottamista ja hakemista. Aikavaativuudet O(korkeus veljessarjojen koko). Rajoitetaan lasten määrä enintään/tasan kahteen. Solmulla on/ei ole vasen lapsi. Solmulla on/ei ole oikea lapsi. Jos on vain yksi lapsi se on joko oikea tai vasen (jolloin toinen lapsi on "tyhjä"). Hyödyt: Toteutus suoraviivaista, suora linkki molempiin lapsiin. Eteneminen syvemmälle puussa yhden vertailun perusteella suoraan jompaan kumpaan lapseen. 88 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 88(279)

89 1.10 Hakupuut (*) 89 Kertausta algoritmiikasta ja aikavaativuudesta Miksi sisäjärjestetty binääripuu on niin kätevä? Hakeminen, lisääminen ja poisto : O(puun korkeus) Puun korkeus = O(n) (triviaalisti, ei kiinnosta) Puun korkeus = Ω(logn) Voidaanko varmistaa että puun korkeus = Θ(logn)? Kyllä, AVL-puu (sivu 94), Punamusta puu, jne (ASA)! Hakeminen, lisääminen ja poisto: O(logn) eli varsin nopeaa vaikka syöte olisi kuinka suuri. Esimerkki 1-24: Haku järjestetystä binääripuusta. Ylläpidetään sisäjärjestettyä binääripuuta, ts. kaikki solmun vasemman alipuun alkiot edeltävät solmun alkiota ja kaikki oikean alipuun alkiot seuraavat solmun alkiota. Haku puusta: jollei haettavaa vielä löydetty tästä solmusta, niin jos haettava edeltää tämän solmun alkiota, haetaan vasemmasta alipuusta, muuten haetaan oikeasta alipuusta. [BinPuuEsim.java] Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 89(279)

90 Kertausta algoritmiikasta ja aikavaativuudesta public static boolean inordermember(btree T, Comparable x) { 1 BTreeNode n = T.getRoot(); 2 while (n!= null) { 3 if (x.compareto(n.getelement()) == 0) 4 return true; 5 else if (x.compareto(n.getelement()) < 0) 6 n = n.getleftchild(); 7 else 8 n = n.getrightchild(); 9 } 10 return false; 11 } 12 Aikavaativuus: kullakin tasolla: 2 vertailua ja linkin seuraaminen (O(1)). Yhteensä O(puun korkeus). Puun korkeus voi vaihdella välillä logn.. n, missä n = puun solmujen määrä. 90 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 90(279)

91 Kertausta algoritmiikasta ja aikavaativuudesta Samat alkiot sisältäviä sisäjärjestettyjä binääripuita voi olla erilaisia! Antaa joustavuutta lisäämiseen. Aina voidaan lisätä lehtisolmuksi (ei tarvita mitään uudelleenjärjestelyjä). Esimerkki 1-25: Lisäys sisäjärjestettyyn binääripuuhun s.e. sisäjärjestys säilyy. Suoritetaan etsintä puussa, kunnes törmätään tyhjään solmuun jossa ko. uusi alkio voisi olla. Lisätään alkio ko. tyhjän solmun paikalle. [HT] Esimerkki 1-26: Annetun lähtösolmun seuraaja sisäjärjestyksessä. Jos solmulla on oikea lapsi, seuraaja on ko. oikean lapsen vasemmanpuoleisin jälkeläinen. Muuten, seuraaja on se esivanhempi jonka vasemmassa alipuussa lähtösolmu on. [HT] Esimerkki 1-27: Poisto sisäjärjestetystä binääripuusta. [BinPuuEsim.java] 91 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 91(279)

92 Kertausta algoritmiikasta ja aikavaativuudesta Puun korkeuden rajoittaminen Keskitytään haku, lisäys ja poisto-operaatioihin. Kaikki O(logn) ajassa. Dynaaminen joukon koko. Mielivaltaisen tyyppinen alkio (compareto riittää). Tarvittaessa myös läpikäynti O(n) kokonaisajassa (O(1) keskimäärin), (yksittäinen next on O(logn) ellei tehdä erikoisratkaisuja). Samoin joukko-operaatiot O(n) ajassa. Tasapainottamaton sisäjärjestetty binääripuu ei toimi (O(n) korkeus)! 92 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 92(279)

93 Sisäjärjestetty (jokseenkin) tasapainoinen binääripuu. 93 Kertausta algoritmiikasta ja aikavaativuudesta Hakeminen on helppoa (käsitelty aiemmin). Tasapainon ylläpitäminen vaatii hieman lisää vaivaa, mutta onnistuu edelleen O(logn) ajassa. Täydellisen tasapainon sijaan riittää kohtuullinen tasapaino, kunhan korkeus on O(logn) (esimerkiksi korkeintaan 1,5 tai 2-kertainen). Lähestymistapoja useita, kaikille yhteistä on pienen epätasapainon sietäminen, heti isomman epätasapainon ilmetessä tasapainotetaan. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 93(279)

94 AVL-puu [Adelson-Vel'skij & Landis] 94 Kertausta algoritmiikasta ja aikavaativuudesta Minkään solmun vasemman ja oikean alipuiden korkeusero ei saa olla yhtä suurempi. Solmun tasapaino: Kussakin solmussa pidetään yllä tasapainotietoa: jolloin solmun vasen alipuu on kahta korkeampi kuin oikea alipuu; jolloin vasen alipuu on yhtä korkeampi kuin oikea alipuu; 0 jolloin solmun alipuut ovat yhtä korkeat ( ); + jolloin solmun oikea alipuu on yhtä korkeampi kuin vasen alipuu; ++ jolloin solmun oikea alipuu on kahta korkeampi kuin vasen alipuu. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 94(279)

95 Kertausta algoritmiikasta ja aikavaativuudesta Tasapainot päivitetään alhaalta ylös: Jos solmun tasapaino muuttuu lisäyksessä 0:sta +:ksi tai :si, (jommankumman (muttei matalamman) alipuun korkeus kasvaa) muuttuu myös vanhemman tasapaino sen mukaan onko tämä solmu vasen vai oikea lapsi. Poistettaessa vastaavasti jommankumman alipuun korkeus saattaa vähentyä. Tasapaino on rikkoutunut, jos se on tai Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 95(279)

96 Kertausta algoritmiikasta ja aikavaativuudesta Jos tasapaino lisäyksen tai poiston myötä menetetään, korjataan kyseisen solmun ympäristä. Suoritetaan kierto epätasapainoisen solmun suhteen Kiertoja on kahta erilaista (ja kumpaakin kahteen suuntaan): Jos solmun tasapaino on ja vasemman lapsen tasapaino, suoritetaan kierto oikealle. Jos solmun tasapaino on ja vasemman lapsen tasapaino +, suoritetaan kaksoiskierto oikealle. Jos solmun tasapaino on ++ ja oikean lapsen tasapaino +, suoritetaan kierto vasemmalle. Jos solmun tasapaino on ++ ja oikean lapsen tasapaino, suoritetaan kaksoiskierto vasemmalle. Kierto pysäyttää tasapainovirheen "nousemisen". Muiden kuin kiertoon osallistuvien solmujen tasapainoon ei kosketa. Poisto hankalahkoa mutta onnistuu O(logn) ajassa (kierron vaikutus voi nousta ylöspäin). 96 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 96(279)

97 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 97(279) 97 Kertausta algoritmiikasta ja aikavaativuudesta h h+1 h β A B γ α ++ + h h+1 h β A B γ α h h A C δ α ++ h h 1 γ B β B δ γ C β h A α Kierto vasemmalle Kaksoiskierto vasemmalle

98 Muita vastaavia 98 Kertausta algoritmiikasta ja aikavaativuudesta Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 98(279) Punamusta puu 2-3(-4) puu B-puu Käsitellään tarkemmin myöhemmin kohdassa 5.5 (s. 250).

99 99 Kertausta algoritmiikasta ja aikavaativuudesta Muita puita Paitsi vakioon 2, voidaan lapsien määrä rajoittaa mihin tahansa muuhunkin vakioon. Kätevä on esimerkiksi aakkoston koko: Kussakin puun haarassa on taulukkona lapset (esim) a..ö Varsinainen tieto tallennetaan (osoittimena) syvyydelle avaimen_pituus puussa Hakeminen aina O(avaimen_pituus) Kullakin avaimella on yksikäsitteinen paikka puussa. Jos avaimia on paljon (suhteessa niiden pituuteen), ei lisätilaa mene paljoakaan. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 99(279)

100 1.11 Joukot (*) 100 Kertausta algoritmiikasta ja aikavaativuudesta Listat ja puut olivat melko konkreettisia kokoelmia; niissä yksilöitiin sijainti. Joukko on vielä jonkin verran abstraktimpi. Joukko on vain "musta laatikko" jossa alkiot ovat. Kokoelmana yksi käytetyimpiä: tietokannat (relaatiotietokannoissa relaatio on tai ei ole) solmujen joukko avainsanojen joukko ja tunnusten joukko ohjelmointikielessä jne Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 100(279)

101 Määritelmiä 101 Kertausta algoritmiikasta ja aikavaativuudesta Joukko on kokoelma mielivaltaisen (mutta saman) tyyppisiä alkioita. Alkion tyyppiä ei rajoiteta (kuten ei ole aiemminkaan rajoitettu). Joukon alkiot ovat keskenään eri alkioita. Sama alkio ei siis voi koskaan olla joukossa kahteen kertaan! Samuuden käsitteen tulee olla yksikäsitteinen. Monimutkaisia alkiotyyppejä käsiteltäessä samuusfunktio jää käyttäjän tehtäväksi. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 101(279)

102 Usein kokoelman alkiolle oletetaan lineaarinen järjestys: 102 Kertausta algoritmiikasta ja aikavaativuudesta 1) Jos a ja b ovat joukon S alkioita, vain yksi väittämistä a<b, a==b, tai b<a on tosi. (ts. järjestys on yksiselitteinen) 2) Jos a, b ja c ovat joukon S alkioita siten, että a<bja b<c, niin a<c. (järjestys on transitiivinen). Yksinkertaisille tyypeille on helppo määritellä järjestys. Monimutkaisille tyypeille, esim. joukoille on vaikeampaa. Esimerkiksi kokonaislukujoukkojen joukko: pienin alkio suurin alkio alkioiden keskiarvo summa mediaani alkioiden määrä Järjestys voi olla keinotekoinen jollei itse sovellus sitä tarvitse. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 102(279)

103 103 Kertausta algoritmiikasta ja aikavaativuudesta Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 103(279) Joukko-operaatiot : tyhjä joukko : kuuluu joukkoon : osajoukko : aito osajoukko : yhdiste : leikkaus \ : erotus joukon luonti lisäys poisto alkioiden läpikäynti

104 Kertausta algoritmiikasta ja aikavaativuudesta Määritelmä 1-28: Abstraktin joukkotyypin tavanomaisimmat operaatiot merkityksineen ovat seuraavat: (Set A, B; E x) 1) Set<E> Set() muodostaa tyhjän joukon. 2) Set<E> Set(java.util.Collection<? extends E> C) muodostaa uuden joukon kopioiden siihen kokoelman C alkiot. 3) boolean A.isEmpty() palauttaa arvon true, jos A==, muuten arvon false. 4) boolean A.equals(B) palauttaa arvon true, jos joukkojen A ja B sisällöt ovat samat, muuten arvon false. 5) Set A.union(B) palauttaa joukon A B (yhdiste). 6) Set A.intersection(B) palauttaa joukon A B (leikkaus). 104 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 104(279)

105 Kertausta algoritmiikasta ja aikavaativuudesta 7) Set A.difference(B) palauttaa joukon A \ B (erotus). 8) boolean A.contains(x) palauttaa arvon true, jos x A, muuten arvon false. 9) boolean A.add(x) vie joukkoon A alkion x säilyttäen joukon A muilta osin ennallaan, palauttaa true jos lisäys onnistui. Jos x oli jo joukossa A, lisäystä ei tehdä, ja palauttaa false. 10) boolean A.remove(x) poistaa joukosta A alkion x säilyttäen joukon A muilta osin ennallaan, palauttaa true jos alkio löydettiin ja poistettiin, false jollei alkiota joukosta löydetty. 11) Set A.clone() palauttaa kopion joukosta A. Uusi joukko sisältää samat alkiot kuin A, mutta itse alkioita ei kopioida. 105 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 105(279)

106 Kertausta algoritmiikasta ja aikavaativuudesta 12) E A.first() palauttaa joukon A pienimmän alkion arvon. Operaation tulos on määrittelemätön, jos A == tai jos joukon A alkioille ei ole määritelty lineaarista järjestystä. 13) E A.last() palauttaa joukon A suurimman alkion arvon. Operaation tulos on määrittelemätön, jos A == tai jos joukon A alkioille ei ole määritelty lineaarista järjestystä. Operaatioiden aikavaativuuksiin palataan myöhemmin. Useimpiin joukkosovelluksiin riittää vain osa tässä mainituista operaatioista. 106 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 106(279)

107 Joukon alkioiden läpikäynti 107 Kertausta algoritmiikasta ja aikavaativuudesta Ylläolevat operaatiot eivät tue joukon alkioiden tehokasta läpikäyntiä joukkoa muuttamatta. Aina tätä ei tarvitakkaan, mutta joskus kyllä. Yleensä: "kaikille joukon S alkioille, tee seuraavaa". Algoritmiteksteissä joukon kaikkien alkioiden läpikäynti esitetään yleensä seuraavaan tapaan: for each x in S do toimenpide alkiolle x (1-20) Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 107(279)

108 Kertausta algoritmiikasta ja aikavaativuudesta Javassa (versio 1.5) tämä onnistuu kaikille Collection -rajapinnan toteuttaville kokoelmille (sillä Collection on Iterable -rajapinnan aliluokka, ja itseasiassa foreach vaatii Iterable -luokan). for (x : S) (1-21) toimenpide alkiolle x missä x on muuttuja kokoelman S:n alkiotyyppiä. Tämä on selkeä, mutta ei salli kokoelman muuttamista, eikä mahdollista toistoon vaikuttamista. Vaihtoehtoisesti: ohjelmointikielen oma toistolause (while) sopiva lopetusehto sopiva tapa saada esille ensimmäinen ja seuraavat käsiteltävät alkiot iterointimuuttuja (ja sen tyyppi). 108 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 108(279)

109 Kertausta algoritmiikasta ja aikavaativuudesta Määritelmä 1-29: Joukon läpikäyntioperaatiot (Set S; Iterator i; E x) 14) Iterator<E> S.iterator() Alustaa joukon S läpikäynnin iterointimuuttujaan i. 15) boolean i.hasnext() palauttaa arvon true, jos joukon S läpikäynti i on vielä kesken, ts. next -operaatiolla saataisiin uusi alkio, muuten palauttaa arvon false. 16) E i.next() palauttaa joukon S jonkin läpikäynnissä i vielä käsittelemättömän alkion. Jos joukon S kaikki alkiot on jo käsitelty läpikäynnissä i (eli hasnext olisi palauttanut toden), aiheuttaa ajonaikaisen poikkeuksen. 17) void i.remove() Poistaa kokoelmasta S edellisen next() -operaation antaman alkion. Läpikäytävää joukkoa ei saa muuttua läpikäynnin aikana (paitsi remove -operaatiolla). Läpikäyntimuuttujan arvoa ei tule omatoimisesti muuttaa. Läpikäyntimuuttujalla ei voi laskea. 109 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 109(279)

110 Kertausta algoritmiikasta ja aikavaativuudesta Läpikäyntijärjestyksestä ei yleensä oleteta mitään. Sisäkkäiset läpikäynnit (tai eri joukkojen läpikäynnit) eri iterointimuuttujilla. Määritelmän 1-29 operaatioita käyttäen lause (1-20): import java.util.iterator; Iterator i = S.iterator(); 3 while (i.hasnext()) { 4 Object x = i.next(); // tai joku muu tyyppi 5 toimenpide alkiolle x; 6 } 7 Alkuehtoinen toistolause on ehdoton, sillä myös ensimmäinenkin next voi epäonnistua jos joukko on tyhjä! iterator, hasnext ja next tulee toteuttaa toimimaan O(1) ajassa. 110 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 110(279)

111 Joukkojen erikoistapauksia 111 Kertausta algoritmiikasta ja aikavaativuudesta Sanakirja: vain haku (ja ehkä lisäys, poisto). Relaatio: alkio-toinen_alkio -pari (tai tai useampiosainen monikko). Kuvaus: avain-alkio -pari, avaimella yksiselitteinen kuva. Laukku (monijoukko): usea samanarvoinen alkio. Prioriteettijono: tarkasteltavissa/poistettavissa vain pieniprioriteettiarvoisin ("tärkein") alkio. java.util.set TreeSet: punamusta puu, log aikavaativuudet, avainten järjestyksessä läpikäynti HashSet: hajautustaulu, O(1) keskimääräiset aikavaativuudet, läpikäynti hajautusjärjestyksessä. Java 1.6-: NavigableSet: "lähimpien" alkioiden haku, yms. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 111(279)

112 Luku Suunnatut verkot Suunnatut verkot Lista: alkiolla yksi seuraaja alkiolla yksi edeltäjä Puu: alkiolla yksi edeltäjä (isä) alkiolla monta seuraajaa (lapset) Entä kun tarvitaan monta edeltäjää ja monta seuraajaa? (Suunnattu) verkko. Jollei edeltäjä/seuraaja suunnalla ole merkitystä, niin käytetään suuntaamatonta verkkoa (kts Luku 3 (s. 162)). Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 112(279)

113 113 Suunnatut verkot Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 113(279) Esimerkki 2-1: Tkt:n LuK:n kurssijärjestys (vanha): Ohjelm. TRAI ProsedOhj TRAII DiskrRak OhjTyö TKJ HAJ Parityö LaPe Projektityö JTKT JärjKehitys TiedonH JärjSuunn.

114 Käyttökohteita 114 Suunnatut verkot (Tieto)liikenteen mallinnus. Tietoliikenneverkko, tieverkko, virtapiirit, prosessikaaviot. Reititys, liikennesuunnittelu, virtasuunnittelu. Relaatiokaaviot, luokkakaaviot, olio-suhdekaaviot, käyttötapauskaaviot, organisaatiokaaviot. Hypertekstit, viittaukset. Kemialliset, fysikaaliset, tekniset, biologiset, sosiologiset, taloudelliset verkostot ja niiden suhteet ja vuorovaikutukset. Algoritmit paljolti sovellusalakohtaisia Tässä luvussa joitakin yleisiä, harjoituksissa vähän lisää. Tärkeintä on oppia hallitsemaan verkkoja, ajattelemaan verkkokäsitteillä, jotta oikeita ongelmia voidaan hahmottaa ja ratkaista verkkojen avulla. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 114(279)

115 2.1 Käsitteitä 115 Suunnatut verkot Suunnattu verkko G =(V, E) V on solmujen (vertex, node) joukko. verkon perusalkio E on (suunnattujen) kaarten (edge) joukko (~relaatio) Kahden solmun välinen suhde (naapuruus) Suunnattu kaari merkitään (u, v) tai u v u on lähtösolmu v on päätesolmu Päätesolmu v on lähtösolmun u naapuri, mutta ei päinvastoin, ellei myös (v, u) E. (u, v) (v, u) Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 115(279)

116 Suunnatut verkot V ja E aina äärellisiä G äärellinen. Voi olla V ja E =, mutta jos V =, niin myös E =. Solmulla voi olla mielivaltainen määrä naapureita. Solmu voi olla itsensä naapuri (kaari (u, u), silmukka) Kaaret voivat (tarvittaessa) olla moninkertaisia, eli voi olla useampi samansuuntainen kaari saman solmuparin välillä. Myös useampi silmukka. Näitä voidaan joskus rajoittaa, riippuen sovelluksesta. 116 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 116(279)

117 Suunnatut verkot Määritelmä 2-2: Polku Suunnatun verkon solmujen jono (v 1, v 2,, v n ) on polku (path), jos (v i, v i+1 ) on verkon kaari kaikille i = 1,, n 1. Polun pituus on tällöin n 1 (kaarten määrä). Polku on yksinkertainen, jos v i v j kun i j tai (i = 1 ja j = n) Yksinkertainen polku, jossa v 1 = v n on kehä. Esimerkki 2-3: Nelisolmuinen verkko v 1 v 2 v 3 v 4 V = {v 1, v 2, v 3, v 4 }. E = { (v 1, v 2 ), (v 2, v 2 ), (v 2, v 3 ), (v 3, v 1 ), (v 3, v 4 ) }. Kehät (v 1, v 2, v 3, v 1 ) ja (v 2, v 2 ). Polkuja mm. (v 2, v 2, v 3, v 1, v 2, v 3, v 4 ) ja (v 3, v 1 ). 117 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 117(279)

118 Suunnatut verkot Hyötytieto Sekä solmut, että verkot voidaan varustaa hyötytiedolla (nimiöllä, viittauksella), tarpeen (sovelluksen) mukaan. Lisäksi solmuille ja kaarille voidaan antaa paino (hinta) jonka mukaan tuloksia lasketaan. Esim. (kaaren) etäisyys, aika, hinta, läpäisykapasiteetti, todennäköisyys, virta, jne Esim. (solmun) hinta, asukasluku, tilavuus, lämpötila, aika, jne. Tarvittaessa voidaan myös käyttää merkintöjä mm. jo käsitellyistä solmuista/kaarista. Näitä nimitetään yleensä väreiksi. Käyttämässämme tietorakennekirjastossa "hyötytieto" on merkkijono, paino on reaaliluku ja väri on lueteltu tyyppi (kokonaisluku). Lisäksi on käytössä kokonaislukutyyppinen indeksi jota voidaan käyttää esimerkiksi solmujen numerointiin. Jos/kun sovelluksessa tarvitaan muuta tietoa (yleensä viite), voidaan periyttämällä lisätä jäseniä. 118 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 118(279)

119 119 Suunnatut verkot Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 119(279) Esimerkki 2-4: Äärellinen automaatti (nimiöt kaarissa). b b a a a v 1 v 2 v 3 v 4 Alkutila Lopputila

120 2.2 Suunnattu verkko abstraktina tietotyyppinä 120 Suunnatut verkot Verkko muodostuu solmujen ja kaarten joukoista. Käytetään (sovellettuja) joukko-operaatioita niiden käsittelyyn. Solmut ovat selkeästi joukko. Kaaret ovat itseasiassa relaatio. Mitä operaatioita tarvitaan? verkon luonti lisäys, poisto (solmun ja kaaren erikseen) olemassaolon tutkiminen, nimiön haku (muuttaminen) painojen ja värien asetus ja tutkinta solmun ja kaaren erikseen usein myös läpikäyntejä kaikki solmut kaikki kaaret solmun naapurit (ja solmusta lähtevät kaaret) Kaikkien kaarten joukkoa ei tarvitse toteuttaa erikseen koska kaaret voidaan selvittää naapuruussuhteita (naapurien joukkoja) tarkastelemalla. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 120(279)

121 Suunnatun verkon operaatiot: 121 Suunnatut verkot Määritelmä 2-5: Suunnatun verkon operaatiot: (DiGraph G, Vertex vertex, Edge edge, String label, int color, float weight, int index) 1) DiGraph DiGraph() Luo tyhjän suunnatun verkon. 2) Vertex G.addVertex(label, color, weight, index) Lisää verkkoon G kaarettoman solmun. Operaatio palauttaa solmun (viittauksen) todennäköistä jatkokäyttöä varten. Tietorakennekirjastossa on lisäksi sama operaatio kuormitettu vähemmillä (ja ilman) kaikkia parametreja. 3) Edge vertex.addedge(vertex2, label, color, weight) Lisää verkkoon kaaren solmusta vertex solmuun vertex2. Operaatio palauttaa kaaren (viittauksen) todennäköistä jatkokäyttöä varten. Tietorakennekirjastossa on lisäksi sama operaatio kuormitettu vähemmillä (ja ilman) parametreilla. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 121(279)

122 Suunnatut verkot 4) void G.removeVertex(vertex) Poistaa verkosta G solmun vertex. Samalla poistetaan solmuun mahdollisesti liittyvät kaaret. 5) vertex.removeedge(edge) Poistaa verkosta G solmusta vertex lähtevän kaaren edge. Kaareen liittyviä solmuja ei poisteta. 6) Edge vertex.getedge(vertex2) Palauttaa solmujen vertex ja vertex2 välillä olevan kaaren, tai null jollei kaarta ole. 7) boolean vertex.isadjacent(vertex2) Palauttaa toden, jos solmusta vertex on kaari solmuun vertex2, muuten epätoden. Operaatioiden aikavaativuudet riippuvat toteutuksesta. Usein käytetyllä vieruslistatoteutuksella useimmat operaatiot ovat O(1), jotkut O(naapurien määrä). Esimerkiksi removevertex poistaa myös kaaret, ja getedge ja isadjacent joutuvat tutkimaan koko naapurien listan. 122 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 122(279)

123 Suunnatut verkot Määritelmä 2-6: Verkon väritys-, paino-, nimiö- ja indeksi -operaatiot: 8) (Vertex Edge).(set get)label(string) 9) (Vertex Edge).(set get)weight(float) 10)(Vertex Edge).(set get)color(int) 11)Vertex.(set get)index(int) nämä ovat aikavaativuudeltaan O(1) 123 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 123(279)

124 Läpikäynnit 124 Suunnatut verkot Joukolle esitellyt for each läpikäynnit soveltuvat hyvin verkoille. Koska tarvitaan sekä solmujen, että kaarten läpikäyntiä, läpikäytävä "kokoelma" (Iterable) saadaan erillisellä menetelmällä. Huomaa, että solmuun tulevien kaarten (tai vastaavien solmujen) läpikäyntiä ei ole koska se ei ole loogista. Määritelmä 2-7: Täydennämme siis edellä esitettyä suunnattujen verkkojen operaatioluetteloa läpikäynneillä: 12)Iterable<Vertex> G.vertices() Palauttaa verkon G kaikkien solmujen läpikäynnin. 13)Iterable<Edge> G.edges() Palauttaa verkon G kaikkien kaarien läpikäynnin. 14)Iterable<Vertex> vertex.neighbors() Palauttaa solmun vertex kaikkien naapurisolmujen läpikäynnin. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 124(279)

125 15)Iterable<Edge> vertex.edges() Palauttaa kaikkien solmusta vertex lähtevien kaarien läpikäynnin. 125 Suunnatut verkot Nämä läpikäynnit on toteutettu Iterator-rajapinnan avulla, jota voi käyttää myös suoraan: 16)Iterator<Vertex> G.vertexIterator() Palauttaa kaikki solmut läpikäyvän iteraattorin. 17)Iterator<Edge> G.edgeIterator() Palauttaa kaikki kaaret läpikäyvän iteraattorin. 18)Iterator<Vertex> vertex.neighborsiterator() Palauttaa solmun kaikki naapurisolmut läpikäyvän iteraattorin. 19)Iterator<Edge> vertex.edgeiterator() Palauttaa kaikki solmusta lähtevät kaaret läpikäyvän iteraattorin. Iteraattoreita käytetään normaalisti hasnext(), next() ja remove() -operaatioilla. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 125(279)

126 Lisäksi kaaresta päästään käsiksi sen päihin operaatioilla: 126 Suunnatut verkot 20)Vertex edge.getendpoint() Palauttaa kaaren edge kohdesolmun. 21)Vertex edge.getstartpoint() Palauttaa kaaren edge lähtösolmun. 22)Vertex edge.getendpoint(vertex vertex) Palauttaa kaaren kaaren edge toisen pään (eri kuin vertex). Tämä on hyodyllinen lähinnä seuraavassa luvussa esitettävälle suuntaamattomalle verkolle. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 126(279)

127 Esimerkki 2-8: Solmun v naapurien läpikäynti epämuodollisella algoritminotaatiolla: 127 Suunnatut verkot for each w adjacent to v in G do 1 toimenpide solmulle w; 2 sama läpikäynti kääntäjälle kelpaavana foreach -toistona: for (Vertex w : v.neighbors()) 1 toimenpide solmulle w; 2 tai iteraattoria käyttäen: Iterator<Vertex> i = v.neighboriterator(); 1 while (i.hasnext()) { 2 Vertex w = i.next(); 3 toimenpide solmulle w; 4 } 5 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 127(279)

128 Verkko-ongelmia/algoritmeja 128 Suunnatut verkot Eräs monipuolisimmista algoritmiikan alueista, ongelmia ja algoritmeja on "loputtomasti". Kts. verkkoteorian oppikirjat, algoritmikirjat Polkujen pituudet, olemassaolot, maksimi virta, erilliset polut Verkkojen numerointi, isomorfisuus (vertailu) Verkon yhtenäisyys, vahva yhtenäisyys, (vahvasti)yhtenäiset komponentit, k-yhtenäisyys, leikkauskohdat, jne Syklien/klikkien etsintä poisto muodostaminen Virittävät puut Eulerin-, Hamiltonin, jne läpikäynnit (kauppamatkustaja yms) Verkon täydentäminen halutun ominaisuuden saavuttamiseksi Väritykset Verkon ositukset (klustereiden minimi/tasa-{paino TS välikaaret jne} Verkon piirto/sijoittelu tasoon tilaan pallopinnalle torukselle jne Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 128(279)

129 Suunnatut verkot Topologinen lajittelu k-jakoisuus, sovitukset Peitteet Eri tyyppisillä verkoilla (solmut d-ulottuvuudessa, erilaiset etäisyysmetriikat, negatiivipainoiset, epäyhtenäiset, syklittömät, jne). 129 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 129(279)

130 2.3 Lyhimmät polut 130 Suunnatut verkot Käsitellään painotettuja kaaria. Esim. paikkakuntien tms. välinen etäisyys, hinta, aika, tms. Polun paino = polun kaarten painojen summa. Solmusta a solmuun b voi johtaa todella monta polkua (O( V!). Mikä on edullisin polku? Mikä on sen kustannus? Merkitään n = solmujen lukumäärä V e = kaarten lukumäärä E numeroidaan solmut 0, 1, 2,..., n 1 (aloitussolmu = 0) painofunktio cost( i, j) = kaaren ( i, j) paino, jos kaari, ellei kaarta ( i, j) ole. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 130(279)

131 Suunnatut verkot Dijkstran algoritmi Taulukossa D pidetään yllä aloitussolmusta 0 muihin solmuihin johtavien lyhyimpien polkujen pituuksia (senhetkisen tietämyksen mukaan). Aluksi taulukko alustetaan kaarten painojen mukaisilla arvoilla (ts. suorilla kaarilla tai :llä). Prioriteettijonoon A viedään aluksi kaikki muut kaaret paitsi aloitussolmu. "Prioriteettina" solmulle i käytetään D[i]:n arvoa. Otettaessa uusi solmu w käsittelyyn prioriteettijonosta (rivit 9-12) käydään läpi kaikki jonossa vielä olevat alkiot, ja tarkastetaan, josko niihin pääsisi solmun w kautta suorempaan kuin aiemmin on päästy. Huomaa, että prioriteetit muuttuvat koko ajan (TRAI:ssä esitetty prioriteettijonon toteutus ei aivan riitä). D: Q: Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 131(279)

132 Algoritmi 2-9: Dijkstran algoritmi (kts. tarkempi toteutus: Dijkstra.java, rivillä 3 luotu prioriteettijono vaatii tarkennusta toimiakseen): 132 Suunnatut verkot float[] Dijkstra(DiGraph G) { 1 float[] D = new float[g.size()]; 2 PriorityQueue<Vertex> Q = new PriorityQueue<Vertex>((Comparator)D); 3 D[0] = 0.0; 4 for (int i = 1; i < n 1; i++) { 5 D[i] = cost(0, i); 6 Q.offer(Vertex_i); // prioriteettina D[i] 7 } 8 while (! Q.isEmpty()) { 9 Vertex v = Q.poll(); // lähin jäljelläoleva solmu 10 for (Vertex w : v.neighbors()) 11 D[w] := min(d[w], D[v]+cost(v,w)) 12 } 13 return D; 14 } 15 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 132(279)

133 Suunnatut verkot Dijkstran algoritmi on "ahne" Se valitsee aina senhetkisistä vaihtoehdoista parhaan. Kuitenkin se löytää aina parhaat reitit (jos kaarten painot ovat ei-negatiiviset). Ahnetta algoritmia tarkasteltaessa on huolellisesti varmistuttava kunkin ahneen valinnan optimaalisuudesta, katso Ahne eteneminen sivulla Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 133(279)

134 Suunnatut verkot Dijkstran algoritmin oikeellisuus Muistetaan etteivät kaarten painot ole negatiivisia. Käytetään induktiota. Ensimmäisen solmun valinta on varmasti oikein, sillä se on lähin solmu, eikä muuta kautta voi päästä siihen suorempaan. Ajatellaan tilannetta jossa joukko S solmuja on w jo valittu ja ollaan juuri valitsemassa solmua w. 0 p 2 Voiko w:hen olla suorempi polku jonkin valitsemattoman solmun x kautta (siten, että x ko. p 1 p 3 polun ensimmäinen S:n ulkopuolinen solmu)? S p Ei, sillä jos polku 0 1 x p 3 w olisi lyhyempi kuin polku 0 p 2 w, olisi sen osapolku 0 p 1 x vielä lyhyempi, eli solmu x olisi valittu ennen solmua w. Siis, kun solmu valitaan, ei siihen voi enää löytyä suorempaa reittiä. x 134 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 134(279)

135 Suunnatut verkot Aikavaativuus Rivit 5-8: prioriteettijonon muodostus: O(nlogn) Rivien 11-12: O(n) alkiota prioriteettijonossa, O(logn) / muutos O(nlogn) Rivit 9-13 voivat viedä aikaa jopa O(n 2 logn), paitsi: Prioriteettijonosta riittää käydä läpi vain solmun w naapurit. naapuruussuhteita on koko verkossa e kpl rivien 9-13 aikavaativuus olisi O(nlogn + e), elleivät prioriteetit suorituksen aikana lainkaan muuttuisi. Prioriteetit voivat muuttua jopa jokaista kaarta tarkasteltaessa, joten suoritusaika on tosiasiassa O(nlogn + elogn), eli yleensä O(elogn). Aikavaativuuteen O(nlogn + e) on mahdollista päästä toteuttamalla prioriteettijono esim. niin sanotun Fibonaccin kasan (heap) avulla (keskimäärin vakioaikainen prioriteetin parannus, logaritminen poisto). Kahden solmun välisen lyhyimmän polun etsintä vaatii (pahimmassa tapauksessa) kaikkien solmujen tutkimista, joten työmäärä on sama. D: Q: Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 135(279)

136 Suunnatut verkot Kaikki lyhimmät polut Kaikista solmuista kaikkiin ("välimatkataulukko"). Dijkstra toistuvasti kutsuttuna O(n 3 ) tai O(n 3 logn) jos verkossa on runsaasti kaaria (O(n 2 logn), jos e = O(n)) Seuraavassa huomattavasti suoraviivaisempi Floydin algoritmi: Ylläpidetään matriisia D[i][j] = paino/kustannus solmusta i solmuun j kussakin suorituksen vaiheessa. Aluksi kaarten painot, lopuksi lyhimpien polkujen painot. Otetaan solmut mukaan yksitellen ja tarkistetaan kaikille solmupareille, josko nyt mukaan otetun solmun kautta löytyisi lyhyempi polku. Toimii myös verkolle jossa on negatiivisia kaaripainoja (kunhan ei ole negatiivisia syklipainoja). 136 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 136(279)

137 Suunnatut verkot Dynaaminen ratkaiseminen Dynaamisessa ratkaisemisessa ideana on kunkin osatehtävän ratkaiseminen ja tallentaminen taulukkoon josta sitä käytetään myöhempien osaratkaisujen ratkaisussa apuna (katso Dynaaminen ratkaiseminen (ohjelmointi) sivulla 195). Floydin algoritmi on tyyppiesimerkki dynaamisen ratkaisemisen tehosta. 137 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 137(279)

138 Algoritmi 2-10: Floyd: 138 Suunnatut verkot float[][] Floyd(DiGraph G) { 1 int n = G.size(); 2 float[][] D = new float[n][n]; 3 for (int i = 0; i < n 1; i++) // matriisin alustus 4 for (int j = 1; j < n 1; j++) 5 D[i][j] = cost(i, j); 6 for (int i = 0; i < n 1; i++) 7 D[i][i] = 0.0; 8 for (int k = 0; k < n 1; k++) // solmu k mukaan tarkasteluun 9 for (int i = 0; i < n 1; i++) 10 for (int j = 1; j < n 1; j++) 11 if (D[i][k]+D[k][j] < D[i][j])// onko i k j < i j? 12 D[i][j] = D[i][k] + D[k][j]; 13 return D; 14 } 15 Aikavaativuus selvästi O(n 3 ), vakiokerroin erittäin pieni. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 138(279)

139 Suunnatut verkot Vasta suurilla verkoilla Dijkstran algoritmi on tehokkaampi jos kaaria ei ole paljoa. Polun tallennus kustannuksen ohella: Dijkstra (yksi lähtösolmu): Ylläpidetään taulukkoa, johon lisätään kuhunkiin solmuun johtavan polun edeltäjäsolmu (valittu välisolmu) jos uusi lyhyempi reitti löytyi sisimmällä iteraatiotasolla. Floyd: matriisi (rivi kutakin lähtösolmua kohti). Näistä voidaan rakentaa (kääntää) polku eteenpäin kun pääalgoritmi on valmis. 139 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 139(279)

140 Polkujen olemassaolo 140 Suunnatut verkot Jos polkujen olemassaolon selvittäminen riittää, voidaan Floydin algoritmi muuttaa totuusarvoiseksi, jolloin saadaan "saavutettavuusmatriisi": Jos solmusta i solmuun j ei vielä tunneta polkua, tarkistetaan josko olisi polku i:stä k:hon ja k:sta j:hin. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 140(279)

141 Algoritmi 2-11: Warshall 141 Suunnatut verkot boolean[][] Warshall(boolean[][] G) { 1 int n = G.size(); 2 boolean[][] D = new boolean[n][n]; 3 for (int i = 0; i < n 1; i++) 4 for (int j = 1; j < n 1; j++) 5 D[i][j] = G[i][j]; // isadjacent() 6 for (int i = 0; i < n 1; i++) 7 D[i][i] = true; 8 for (int k = 0; k < n 1; k++) 9 for (int i = 0; i < n 1; i++) 10 for (int j = 1; j < n 1; j++) 11 if (! D[i][j]) 12 D[i][j] = D[i][k] && D[k][j]; 13 return D; 14 } 15 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 141(279)

142 2.4 Verkon läpikäynti 142 Suunnatut verkot Ylläolevat algoritmit käyttivät verkkoa vierusmatriisilla solmujen numerojärjestyksessä. Usein kuitenkin verkkoa "selaillaan solmu-solmulta" ja kaari-kaarelta kuten puitakin. Tutkitaan saavutettavuutta, yhtenäisyyttä, jne. Käytetään kohdassa 2.2 (s. 120) esiteltyjä joukon läpikäyntioperaatioita (foreach). Muistetaan, että läpikäyntioperaatioiden tarjoamasta järjestyksestä ei saa olettaa mitään! Kun läpikäynnin järjestykseen halutaan vaikuttaa, tehdään se itse: Käytetään jotakin puista tuttua läpikäyntiä soveltaen: syvyyshaku (esi- tai jälkijärjestys) leveyssuuntainen haku Koska verkossa saattaa olla paluukaaria jo käsiteltyihin solmuihin (päinvastoin kuin puussa!), niihin pitää varautua: Merkitään jo läpikäydyt solmut läpikäydyiksi ("väreillä"). Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 142(279)

143 Suunnatut verkot Syvyyssuuntainen etsintä/läpikäynti jne. Merkitään kaikki solmut käsittelemättömiksi (valkoisiksi). Valitaan jokin solmu v aloitussolmuksi, käsitellään tämä ja merkitään käsitellyksi (harmaaksi). Kutsutaan rekursiivisesti v:n naapureille mikäli nämä ovat vielä käsittelemättömiä. Jos jäi käsittelemättömiä solmuja, valitaan uusi aloitussolmu. Algoritmi 2-12: Syvyyssuuntaisen läpikäynnin käynnistys: void dfsstart(digraph g) { 1 for (Vertex v : g.vertices()) // kaikki solmut valkoisiksi 2 v.setcolor(digraph.white); 3 for (Vertex v : g.vertices()) // aloitus vielä käymättömistä solm. 4 if (v.getcolor() == DiGraph.WHITE) 5 dfs(v); 6 } Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 143(279)

144 Algoritmi 2-13: Varsinainen rekursiivinen syvyyssuuntainen läpikäynti: 144 Suunnatut verkot void dfs(vertex start) { 1 // toimenpide solmulle start (esijärjestys) 2 start.setcolor(digraph.gray); 3 for (Vertex vertex : start.neighbours()) // vielä käymättömät 4 if (vertex.getcolor() == DiGraph.WHITE) // naapurit 5 dfs(vertex); 6 } 7 Jollei värejä voida käyttää, tai väritystä käyttäviä läpikäyntejä on useita, tarvitaan muunlaista kirjanpitoa jo käsitellyistä solmuista. Tieto käsitellyistä solmuista voidaan pitää taulukossa, mutta on muistettava, ettei Vertex -tyyppi yleensä ole kokonaisluku, vaan viittaus. Joko numeroidaan solmut erikseen ja käytetään omaa läpikäyntiä, tai talletetaan solmut hajautuksella taulukkoon (tai muuhun sopivaan sanakirjan talletusmuotoon). Varsinainen operaatio voidaan välittää dfs():lle aliohjelmaparametrina. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 144(279)

145 Suunnatut verkot Aikavaativuus (n = solmujen määrä, e = kaarten määrä) O(e), kun n e, dfs suoritetaan kerran kullekin solmulle, kukin naapuruussuhde tutkitaan; naapuruussuhteita e kappaletta jos n > e, on varminta ilmaista aikavaativuus muodossa O(n + e). 145 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 145(279)

146 Kaarien luokittelu hauissa 146 Suunnatut verkot 1) puukaaria ovat ne kaaret, jotka johtavat vielä käsittelemättömiin solmuihin, 2) paluukaaria, jotka johtavat solmusta esi-isään (virittävässä puussa), 3) etenemiskaaria, jotka johtavat solmusta jälkeläiseen (virittävässä puussa), tai 4) ristikkäiskaaria, jotka eivät johda esi-isään eivätkä jälkeläiseen (virittävässä puussa). Puukaaret muodostavat virittävän metsän (spanning forest), eli (minimaalisen) joukon suunnattuja puita, jotka sisältävät verkon kaikki solmut. Jos virittävässä metsässä on vain yksi puu, tätä sanotaan virittäväksi puuksi (spanning tree). Virittäviä puita/metsiä voi olla useita erilaisia. Riippuen aloitussolmusta. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 146(279)

147 147 Suunnatut verkot Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 147(279) 2.5 Muita verkko-ongelmia Erilaisia verkkoja: Puu DAG Kehäinen

148 Verkon kehättömyyden selvittäminen Suunnatut verkot Käytetään syvyyssuuntaista hakua, tunnistetaan paluukaaret. 2 Kaksi väriä ei riitä, on erotettava paluukaaret etenemis- ja ristikkäiskaarista. 3 Käytetään kolmea väriä: Aluksi valkoinen. 1 Ensimmäisen kerran kohdattaessa väritetään solmut harmaaksi. dfs-algoritmin päätteeksi väritetään solmu mustaksi. 2 Jos etsinnän aikana on löydetty harmaa solmu, kyseessä on paluukaari. 3 Kyse on hausta, joka ei ole vielä päättynyt, vaan kaari palaa "takaisin ylemmäs dfs-hakupuussa". Kyse on siis kehästä! Kohdattaessa musta solmu, kyseessä on etenemis- tai ristikkäiskaari. 4 4 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 148(279)

149 Osittainen (topologinen) lajittelu 149 Suunnatut verkot Suunnattu kehätön verkko (Directed Acyclic Graph, DAG) sopii osittaisen järjestyksen kuvaamiseen (ja osittaisen lajittelun toteuttamiseen). Relaatio R joukossa S on osittainen järjestys, jos 1) ara on epätosi kaikille a S ja 2) arb & brc arc kaikille a, b, c S (transitiivisuus). Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 149(279)

150 Suunnatut verkot Esimerkki 2-14: Relaatio (aito osajoukko) tuottaa osittaisen järjestyksen joukon S = {1, 2, 3} potenssijoukkoon P(S) ={, {1}, {2}, {3}, {1,2}, {1,3}, {2,3}, {1,2,3}}. Osittaisen järjestämisen algoritmi (*) Rekursiivisesti, tulos listaan [DiGraphEsimerkki.topoSort()]: Käytetään syvyyssuuntaista hakua (jälkijärjestystä). Aina kun syvyysssuuntainen haku päättyy jollekin solmulle, viedään se tuloslistan alkuun. Lopuksi tuloslista sisältää solmut (jossakin) topologisessa järjestyksessä. Perustelu: kulloinkin käsittelyssä olevan solmun v kaikki seuraajat (solmut, joihin on polku) tulevat laitetuksi listaan solmua v aiemmin, joten ne ovat lopullisessa listassa v:n jälkeen. Ilman rekursiota: käytetään syvyyssuuntaista hakua ja apuna pakkaa. Kohdattaessa solmu ensimmäisen kerran, viedään pakan pinnalle dfs-algoritmin päätteeksi solmu pakan pinnalta pohjalle. Etsinnän päätyttyä pakka sisältää pohjalta lukien solmut topologisessa järjestyksessä. 150 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 150(279)

151 Vahvasti yhtenäiset komponentit 151 Suunnatut verkot Suunnatun verkon vahvasti yhtenäinen komponentti on sellainen verkon solmujen maksimaalinen osajoukko, jonka jokaisesta solmusta on polku osajoukon kaikkiin muihin solmuihin. Koko verkko on vahvasti yhtenäinen, jos verkko koostuu yhdestä vahvasti yhtenäisestä komponentista, toisin sanoen jos verkon jokaisesta solmusta on polku verkon kaikkiin muihin solmuihin. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 151(279)

152 Suunnatut verkot Suunnatun verkon vahvasti yhtenäiset komponentit saadaan selville seuraavalla algoritmilla: [DiGraphEsimerkki.vahvastiYhtenaisetKomponentit()] (*) 1) Käydään verkon G solmut läpi syvyyssuuntaisella etsinnällä ja numeroidaan solmut sitä mukaa kun niihin liittyvät rekursiiviset kutsut päättyvät (jälkijärjestys). Haun aloitusjärjestyksellä ei ole väliä. 2) Muodostetaan uusi suunnattu verkko G r kääntämällä G:n jokaisen kaaren suunta päinvastaiseksi Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 152(279)

153 Suunnatut verkot 3) Käydään verkon G r solmut läpi syvyyssuuntaisella etsinnällä aloittaen aina suurinumeroisimmasta jäljellä olevasta solmusta. 1 Naapurien läpikäyntijärjestyksellä ei ole väliä Näin muodostuu virittävä metsä, jonka kukin puu koostuu G:n yhden vahvasti yhtenäisen komponentin solmuista (muttei G:n kaarista). Tarvittaessa kukin alkuperäisiä kaaria käyttävä puu voidaan muodostaa syvyyssuuntaisella aloittaen kunkin komponentin mistä tahansa solmusta. Suuntaamattomat verkot (s. 162) 153 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 153(279)

154 Suunnatut verkot Maksimaalinen virtaus (*) Verkon solmut ovat risteyksiä, verkon kaaret yhteyksiä. Kaarilla on rajallinen (virtaus) kapasiteetti Sähkö/vesi/ilma/henkilö/tavara/ajoneuvo/tieto/tms virta. Tehtävänä etsiä maksimaalinen virtaus (arvo, käytettävät kaaret) annetusta lähdesolmusta s (source) annettuun kohdesolmuun d (destination, sink). Määritellään kaaren jäännöskapasiteetti (residual capacity) virtauksen lisäyspotentiaali. Jäännösverkko koostuu kaarista joilla on jäännöskapasiteettia. s d 154 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 154(279)

155 Suunnatut verkot Virtausta täydentävä polku (laajentava, augmenting path) on jäännösverkossa solmusta s solmuun d kulkeva polku (vrt. kaksijakoisen verkon sovitus, sivu 187). Täydentävän polun kapasiteetti on minimi polun kaarien jäännöskapasiteeteista. Jo löydettyä virtaa täydennetään täydentävällä polulla (kukin kaari polun kapasiteetilla). Jäännösverkossa polun kaarten jäännöskapasiteettia vähennetään löydetyn polun kapasiteetilla. Itse algoritmi toistaa täydentävän polun hakua ja lisäämistä virtaukseen kunnes täydentävää polkua ei enää löydy. Täydentävän polun haku on syvyys/leveyssuuntainen haku jäännösverkossa huomioiden painot (edetään vain kaaria joiden jäännöskapasiteetti on positiivinen). Näin yksinkertaisena ahneena toteutuksena algoritmi ei kuitenkaan aina toimi! Algoritmi saattaa valita (huonon) polun joka estää myöhemmin täydentävän polun löytymisen. 155 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 155(279)

156 Suunnatut verkot Valinnan peruuttamisen mahdollisuus (Ford-Fulkerson) Jäännösverkkoon merkitään kutakin lisättyä virtausta kohti vastaava määrä jäännöskapasiteettia vastakkaiseen suuntaan (eräänlaista virtuaalikapasiteettia). Nyt jokin myöhempi täydentävä polku voi vastakkaiseen suuntaan etenemällä vähentää ko. kaaren kapasiteetin käyttöä, ja löytää uuden täydentävän polun. Syvyyssuuntaisella täydentävän polun haulla aikavaativuudeksi tulee (huonolla tuurilla) (kokonaislukuarvoisilla painoilla) O(E f * ), missä f * on suurin löydetty virtaus (tarkemmin virtauksen ja pienimmän kaaren kapasiteetin suhde). Aikavaativuus voidaan parantaa aikaan O(VE 2 ) kun käytetään täydentävän polun leveyssuuntaista hakua. (Edmonds-Karp -algoritmi). Pyritään löytämään mahdollisimman lyhyt täydentävä polku. Esimerkki 2-15: FordFulkerson.java toimintaesimerkki: Haku voi edetä muutenkin, tässä dfs solmujen numerojärjestyksessä. 156 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 156(279)

157 157 Suunnatut verkot Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 157(279) Kussakin kaaressa on merkittynä virta/jäännöskapasiteetti ennen merkityn polun hakua. Vastakaarien kapasiteetti on merkitty vain tarpeen mukaan. s 0/16 1 0/12 0/20 3 d Polku s d, kapasiteetti 7 0/4 0/7 0/9 0/4 0/10 0/ /14 s 7/9 1 0/12 7/13 3 d Polku s d, kapasiteetti 3 0/4 7/0 0/9 0/11 7/3 0/ /7

158 158 Suunnatut verkot Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 158(279) s 10/6 1 0/12 7/13 3 d 3/1 7/0 10/0 0/9 0/14 0/13 4 Polku s d, kapasiteetti 1 10/4 Polku s-1-3-d, kapasiteetti 5 2 s 11/5 1 1/11 7/13 3 d 4/0 7/0 10/0 1/8 0/14 0/ /3 2

159 Polku s d, kapasiteetti 6. s 16/0 1 6/6 12/8 3 d 159 Suunnatut verkot Huomaa: kaaren 2 1 kapasiteetti 14 (alkuperäinen 4+vastavirta 10). Polku s-2-3-d, kapasiteetti 1 Huomaa: kaarta 2 3 kaarta ei alkuperäisessä verkossa ole, mutta nyt lisätään vastavirtaa, eli vähennetään alkuperäistä virtausta. s 0/13 10/0 2 0/14 1/8 11/3 7/0 16/0 1 12/0 18/2 3 6/7 4/6 2 0/8 1/8 0/1 11/3 4 7/0 4 4/0 4/0 d Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 159(279)

160 Suunnatut verkot Lopullinen maksimaalinen virtaus on täydentä- s 16/0 1 12/0 19/1 3 d vien polkujen kapasiteettien summa. Uutta täydentävää polkua ei enää löydy: 2 11/3 4 Polun haku törmää solmuihin 4 (josta ei pääse mihinkään) ja solmupariin 1&2 joista ei pääse kuin solmuun 4. Kuvaan katkoviivalla merkityn leikkauksen kohdalta ei enää voi lisätä virtausta kohdesolmuun päin. Takaperin tarkastellen ainoa käyttämätön kapasiteetti (1) solmuun d olisi solmusta 3, mutta solmuun 3 ei johda enää lisäkapasiteettia. 7/6 Virtaus on siis maksimaalinen! 4/6 Virtausverkon oikeellisuuden voi tarkistaa laskemalla kunkin solmun sisääntulevan ja ulosmenevän virtauksen, sekä vertaamalla kunkin kaaren virtausta verkon alkuperäiseen kapasiteettiin. 0/8 0/9 7/0 4/0 160 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 160(279)

161 Suunnatut verkot Ford-Fulkerson algoritmia voi myös käyttää maksimaaliseen sovitukseen (vrt. kaksijakoisen verkon sovitus, sivu 187) lisäämällä kaksijakoiseen verkkoon lähdeja kohdesolmut sekä kaaret lähtösolmusta ensimmäiseen joukkoon ja toisesta joukosta kohdesolmuun. Kaikki kaaret ovat kapasiteetiltaan 1. Verkon toteuttaminen: kts. kohta 6.2 (s. 268). s V 1 V 2 d 161 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 161(279)

162 Luku Suuntaamattomat verkot Suuntaamattomat verkot Suuntaamattomassa verkossa kaaren molemmat suunnat ovat aina käytössä. Soveltuu tilanteisiin joissa yhteys on aina symmetrinen. Hieman helpompi hahmottaa ja piirtää. Hieman hankalampi toteuttaa. Pääosa suunnatun verkon algoritmeista soveltuu (jokseenkin) sellaisenaan suuntaamattomallekkin verkolle. Esim. lyhyimmät polut. Kaarta seurattuamme meidän on kuitenkin varmistuttava, ettemme vahingossa palaa samaa kaarta takaisin. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 162(279)

163 3.1 Määritelmiä 163 Suuntaamattomat verkot Kuten suunnattu verkko paitsi: (u, v) = (v, u) Kaarella ei ole suuntaa. Naapuruussuhde on siis aina molemminpuolinen. Kaari (ja siten polku) voidaan kulkea molempiin suuntiin. Solmusta itseensä ei (yleensä) saa olla kaarta (ts. silmukkaa). Solmujen välillä ei (yleensä) saa olla useampaa kuin yksi kaari. Koska kehä ei saa sisältää samaa kaarta kahdesti (ja kaksi edellistä kohtaa ovat voimassa), niin kehässä on vähintään kolme solmua. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 163(279)

164 Suuntaamattomat verkot Suuntaamaton verkko abstraktina tietotyyppinä Kuten suunnattu verkko. Paitsi ei etuliitettä Di, siis luokka Graph. Edge.getStartPoint() ja Edge.getEndPoint() toimivat "satunnaisesti". Eri päät saa Edge.getEndPoint(vertex):llä 164 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 164(279)

165 Aliverkko 165 Suuntaamattomat verkot Verkon G =(V, E) aliverkoksi sanotaan verkkoa G' =(V', E'), missä V' V ja E' sisältää vain sellaisia E:n kaaria, joiden molemmat päätesolmut kuuluvat joukkoon V'. Mikäli E' sisältää kaikki sellaiset E:n kaaret, joiden molemmat päätesolmut kuuluvat joukkoon V', sanotaan verkkoa G' solmujoukon V' indusoimaksi aliverkoksi. Yhtenäisyys, vapaa puu Yhtenäisessä verkossa minkä tahansa kahden solmun välillä on polku. Yhtenäistä kehätöntä verkkoa sanotaan myös vapaaksi puuksi. Vapaassa puussa on n 1 kaarta. Lisättäessä puuhun kaari, muodostuu kehä. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 165(279)

166 3.2 Pienin virittävä (kattava) puu 166 Suuntaamattomat verkot G on yhtenäinen painotettu verkko. Vapaa puu on virittävä puu kun solmut ovat samat kuin G:n solmut ja kaaret (n 1 kpl) ovat G:n kaaria (osajoukko). Virittävä puu muodostaa luonnollisesti edelleen yhtenäisen verkon. Virittävän puun paino on kaarten painojen summa. Pienin virittävä puu on pienipainoisin virittävä puu. "Halvin tapa yhdistää kaikki solmut!" Esim. tietoliikenneverkko, kauppamatkustajan ongelman heuristisen ratkaisun lähtötilanne. (Pienimpiä) virittäviä puita voi olla useita. Vastaavasti virittävä metsä jollei verkko ole yhtenäinen. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 166(279)

167 Suuntaamattomat verkot Primin algoritmi Lähdetään liikkeelle mistä tahansa solmusta (kuvassa 0). Puuhun kytkettäessä solmu väritetään (kuvassa vihreällä) (aluksi aloitussolmu) Kaikki kytketystä solmusta lähtevät kaaret viedään prioriteettijonoon (kuvassa sinisellä). Kullakin kierroksella puuhun kytketään sellainen vielä kytkemätön solmu, johon johtaa pienipainoisin kaari jostakin jo kytketystä solmusta. Tämä kaari otetaan mukaan virittävään puuhun (ja sen toisen pään solmu). Käytännössä otetaan prioriteettijonosta kaaria kunnes saadaan sellainen jonka toisen pään solmu on valkoinen. Toinen pää oli jo väistämättä väritetty. Kun kaikki solmut on kytketty, pienipainoisin virittävä puu on valmis. Väritysten sijaan voidaan käyttää myös joukkoja Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 167(279)

168 Suuntaamattomat verkot Algoritmi 3-1: Primin algoritmi tuottaa yhtenäisen verkon G pienimmän virittävän puun kaarten listan seuraavalla tavalla: LinkedList<Edge> MSTPrim(Graph G) 2 { LinkedList<Edge> mst = new LinkedList<Edge>(); 2 AssignablePriorityQueue<Edge> Q = 3 new AssignablePriorityQueue<Edge>(); 4 int n = G.size(); 5 varita(g, Graph.WHITE); // kaikki valkoisiksi 6 Vertex v = G.firstVertex(); // aloitetaan mistä tahansa solmusta 7 v.setcolor(graph.black); 8 for (Edge e : v.edges()) // lähtösolmun kaaret prioriteettijonoon 9 Q.add(e, e.getweight()); Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 168(279)

169 Suuntaamattomat verkot int i = 1; 11 while (i < n) { // kunnes kaikki solmut otettu mukaan 12 Edge e = Q.poll(); 13 Vertex v1 = e.getstartpoint(); 14 Vertex v2 = e.getendpoint(); 15 if (v1.getcolor()!= Graph.BLACK // kaaren toinen pää 16 v2.getcolor()!= Graph.BLACK) { // valkoinen 17 if (v2.getcolor() == Graph.BLACK) 18 v2 = v1; // vaihdetaan v2 siihen valkoiseen 19 mst.add(e); // kaari listaan 20 v2.setcolor(graph.black); // solmu merk. mukaan otetuksi 21 i++; 22 for (Edge e2 : v2.edges()) // kaaret prioriteettijonoon 23 Q.add(e2.getWeight(), e2); 24 } // if 25 } // while 26 return mst; 27 } Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 169(279)

170 Suuntaamattomat verkot Aloitusvaihtoehtoja Aloitussolmulla ei ole merkitystä, sillä kaikki solmut kuuluvat joka tapauksessa virittävään puuhun. Voitaisiin myös aloittaa vaikkapa pienipainoisimmasta kaaresta (ja viedä molemmat päät suoraan virittävään puuhun). Aikavaativuus Riviltä 12 alkava toisto: kullakin kierroksella viedään virittävään puuhun yksi uusi solmu, joten toistokertoja on kaikkiaan O(n) listaan lisäykset mahdollista tehdä vakioajassa pienimmän valinta prioriteettijonolla prioriteettijono muuttuu (kaaria lisätään ja poistetaan) jatkuvasti, mutta prioriteetit eivät tälläkertaa muutu. Toiston aikana kaikkien solmujen kaaret (eli kaikki kaaret) viedään prioriteettijonoon (enintään) kerran. Samoin prioriteettijonosta poistetaan (jopa) kaikki kaaret. O(e loge), pahimmassa tapauksessa e = O(n 2 ) O(n 2 logn). 170 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 170(279)

171 Suuntaamattomat verkot Vaihtoehtoinen toteutustapa Käytetään prioriteettijonon sijaan kahta taulukkoa. closest[i] sisältää solmun joka on lähimpänä solmua i vielä kytkemättömistä solmuista. lowcost[i] sisältää ko. kaaren kustannuksen. Kussakin vaiheessa käydään lowcost läpi pienimmän etsimiseksi, samalla päivitetään taulukoita. O(n 2 ) 171 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 171(279)

172 Suuntaamattomat verkot Kruskalin algoritmi Primin algoritmi kasvattaa puuta lähtien yhdestä solmusta. Kruskalin algoritmi yhdistelee aluksi täysin kytkemättömiä solmuja komponenteiksi kunnes puu on valmis. Komponentit on kätevä ilmaista solmujoukkojen joukkona. Aluksi on n joukkoa, kussakin yksi solmu. Yhdistetään kaksi joukkoa (valitsemalla pienipainoisin kaikista eri komponenttien välillä olevista kaarista). Toistetaan kunnes kaikki komponentit on yhdistelty. Komponettien hallinta ei ole toistaiseksi esitellyillä abstrakteilla tietotyypeillä kovin tehokasta. Sopivasti toteutus valiten: lajittelu O(eloge) + yhdistely O(eα(e, n)) = O(eloge) Jos/kun kaarten painot helposti lajiteltavissa (kaukalo- tai kantalukulajittelu), vieläkin nopeampi, lähes lineaarinen e:n suhteen Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 172(279)

173 Suuntaamattomat verkot Taas uusi joukkotyypin määrittely, ns. pistevieraat joukot (disjoint set, merge-find set). Vain seuraavat operaatiot: (Set<E> A, Set<E> B, MfSet<Set<E>> M, E x) 1) M.merge(A, B) yhdistää kokoelman M sisältämät joukot A ja B jommaksikummaksi näistä kahdesta joukosta. Yhdiste säilyy kokoelmassa M, mutta se alkuperäisistä joukoista, johon yhdistettä ei muodosteta, lakkaa olemasta. Jos A M, B M tai A B,on operaation tulos määrittelemätön. 2) Set M.find(x) palauttaa kokoelman M sen joukon viittauksen, joka joukko sisältää alkion x. Jos x ei sisälly mihinkään kokoelman M joukkoon tai x sisältyy useampaan kuin yhteen kokoelman M joukkoon, on operaation tulos määrittelemätön. 3) M.add(x) muodostaa kokoelmaan M vain alkion x sisältävän uuden joukon. 4) MfSet MfSet() muodostaa tyhjän kokoelman. 173 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 173(279)

174 Algoritmi 3-2: Kruskalin algoritmi (*): 174 Suuntaamattomat verkot LinkedList<Edge> MSTKruskal(Graph g) { 1 LinkedList<Edge> mst = new LinkedList<Edge>(); 2 AssignablePriorityQueue<Edge> Q = 3 new AssignablePriorityQueue<Edge>(); 4 for (Edge e : g.edges()) // kaikki kaaret prioriteettijonoon 5 Q.add(e, e.getweight()); 6 MfSet<Set<Vertex>> M = new MfSet<Set<Vertex>>; 7 for (Vertex v : g.vertices()) // kaikki solmut joukoiksi 8 M.add(v); 9 int i = g.size(); // joukkojen määrä 10 while (i > 1) { 11 Edge e = Q.poll(); 12 Set s1 = M.find(e.getStartPoint()); 13 Set s2 = M.find(e.getEndPoint()); 14 if (s1!= s2) { // eri osapuut 15 M.merge(s1, s2); 16 i ; 17 mst.add(e); 18 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 174(279)

175 } 19 } 20 return mst; 21 } Suuntaamattomat verkot Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 175(279)

176 3.3 Suuntaamattoman verkon läpikäynti 176 Suuntaamattomat verkot Muuten kuten suunnatun verkon, mutta muistetaan, että samat kaaret voidaan kulkea kahteen suuntaan! Jokainen kaari on itsensä "paluukaari". Yhteys takaisin ei ole kehä, jos se käyttää samaa kaarta eri suuntiin. Syvyyssuuntainen etsintä Aloitetaanpa syvyyssuuntainen etsintä komponentin mistä solmusta tahansa, niin kerralla löydettävien solmujen joukko on aina sama. Saavutettavuus on aina molemminsuuntaista. Yhtenäisyys on yksiselitteinen. Dfs-start -algoritmilla saadaan virittävä puu/metsä. Jos suuntaamaton verkko on yhtenäinen, eikä siinä ole kehää, se on vapaa puu. Huomaa, että virittävää metsää rakennettaessa kohdataan vain puu- tai paluukaaria; ristikkäis- ja etenemiskaaria ei voida erottaa/määritellä. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 176(279)

177 Leveyssuuntainen etsintä: 177 Suuntaamattomat verkot Toimii myös suunnatulle verkolle. Läpikäyntijärjestys 1) aloitussolmu 2) aloitussolmun naapurit 3) aloitussolmun naapurien naapurit 4)... Joka tasolla naapureista vain käsittelemättömät! Toisin sanoen 1) etäisyydellä 0 aloitussolmusta olevat solmut [aloitussolmu] 2) etäisyydellä 1 aloitussolmusta olevat solmut 3) etäisyydellä 2 aloitussolmusta olevat solmut 4) jne Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 177(279)

178 Aivan kuten puussakin tasoittainen läpikäynti juuresta alkaen! 178 Suuntaamattomat verkot Algoritmikin on sama. viedään aloitussolmu jonoon toistetaan kunnes jono on tyhjä otetaan jonosta ensimmäinen, käsitellään ja viedään naapurit jonoon Paitsi, että joudumme tarkkailemaan ristikkäiskaaria haarasta toiseen (kehiä): käytetään väritystä kuten syvyyssuuntaisessakin haussa viedään jonoon vain vielä kohtaamattomat solmut jotta jonoon ei vietäisi samaa solmua kahdesti (kaksi samanmittaista polkua samaan solmuun), väritetään solmut jo jonoon vietäessä. Pohjaväritys tehdään käynnistysaliohjelmassa. Pohjavärityksen sijaan voimme käyttää uutta väriä ja tulkita kaikki muut värit "pohjaväriksi". Algoritmin 3-3 käynnistys kuten syvyyssuuntaisen haun käynnistys 2-12 (s. 143). Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 178(279)

179 Algoritmi 3-3: Leveyssuuntainen läpikäyntialgoritmi: 179 Suuntaamattomat verkot void bfs(vertex start) { // komponentit solmut eivät ole harmaita 1 LinkedQueue<Vertex> vq = new LinkedQueue<Vertex>(); 2 start.setcolor(graph.gray); // merkitään jonoon viedyksi 3 vq.add(start); // aloitussolmu jonoon 4 while (! vq.isempty()) { 5 Vertex v = vq.remove(); 6 // use v 7 for (Vertex w : v.neighbours()) { 8 if (w.getcolor()!= Graph.GRAY) { // käsittelemättömät naapur 9 w.setcolor(graph.gray);// merk. jonoon viedyksi 10 vq.add(w); // jonoon 11 } 12 } } } 13 Algoritmin aikavaativuus O(e) tai O(e + nt use ) Jokaisen solmun kohdalla joudutaan tutkimaan solmun kaikkien naapureiden väri, koko toiston aikana tutkitaan kaikki naapuruussuhteet. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 179(279)

180 3.4 Leikkaussolmut ja 2-yhtenäiset komponentit 180 Suuntaamattomat verkot Leikkaussolmu on solmu, jonka poistaminen (ja samalla sen kaarien poistaminen) hajottaa verkon (tai komponentin) kahteen tai useampaan erilliseen osaan. Kaari, jonka poistaminen jakaa verkon (tai komponentin) erillisiin osiin on silta. Yhtenäinen verkko on 2-yhtenäinen, jos siinä ei ole yhtään leikkaussolmua. Kaikkien solmuparien välillä on ainakin kaksi polkua, jotka eivät leikkaa toisiaan. 2-yhtenäisen verkon mikä tahansa solmu tai kaari voidaan poistaa verkon yhtenäisyyttä rikkomatta. Yleisemmin k-yhtenäisyys: Verkon minkä tahansa kahden solmun välillä on ainakin k polkua, jotka eivät leikkaa toisiaan. Voidaan poistaa k 1 kaarta (tai solmua kaarineen) verkon yhtenäisyyttä rikkomatta. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 180(279)

181 Tyypillinen käyttöesimerkki: Vikasietoinen tietoliikenneverkko/virtapiiri/tms. 181 Suuntaamattomat verkot Algoritmi 3-4: Verkon leikkaussolmut etsitään seuraavalla algoritmilla, joka sopii myös verkon 2-yhtenäisyyden selvittämiseen [GraphEsimerkki.leikkausSolmut()]: (*) Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 181(279)

182 Suuntaamattomat verkot 1) Suoritetaan verkossa syvyyssuuntainen etsintä C 3 D 4 E 6 ja numeroidaan solmut käsittelyjärjestyksessä (esijärjestyksessä). Solmujen numerot talletetaan taulukkoon dfnumber. B 2 A 1 F 5 2) Määrätään jokaiselle solmulle ns. low -arvo seuraavasti: low[ v] = min dfnumber[ v] dfnumber[ z] z joille on paluukaari ( v, z) low[ y] v:n lapsille y dfs-puussa Nämä arvot voidaan määrätä jälkijärjestyksessä, jolloin solmun kaikkien lasten low-arvot tunnetaan solmun omaa low-arvoa määrättäessä. B 2 1 C 3 1 D 4 1 A 1 1 low -arvot F 5 5 E Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 182(279)

183 Suuntaamattomat verkot 3) Leikkaussolmut löytyvät nyt seuraavasti: a)dfs-puun juuri on leikkaussolmu vain, jos ja vain jos sillä on ainakin kaksi lasta. b)v ( dfs-puun juuri) on leikkaussolmu, jos ja vain jos A 1 1 v:llä on dfs-puussa lapsi w, jolle low[w] dfnumber[v]. B 2 F 5 1 Koko algoritmi voidaan itseasiassa toteuttaa yhdellä ainoalla syvyyssuuntaisella läpikäynnillä. Rekursiossa edettä- 1 essä (=esijärjestys) numeroidaan solmut, rekursiosta palattaessa (= jälkijärjestys) lasketaan low-arvot ja tarkastetaan D 4 1 onko solmu leikkaussolmu vai ei. Katso toteutus kurssin www-sivulla. Tämän algoritmin aikavaativuus on O(n + e). Kun e n, on aikavaativuus O(e). C 3 5 E Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 183(279)

184 3.5 Verkon kaksijakoisuus, sovitus 184 Suuntaamattomat verkot Relaatio yhdistää kaksi joukkoa, mutta vain yksisuuntaisesti, entä vastaava symmetrinen tilanne? Määritelmä 3-5: Verkko G = (V, E) on kaksijakoinen, jos V = V 1 V 2, V 1 V 2 = ja E = { (u, v) u V 1, v V 2 (u, v) } Kaksijakoinen verkko koostuu kahdesta solmujoukosta, joiden kummankaan sisällä ei ole kaaria. Määritelmä 3-6: Kaksijakoisen verkon kaarten osajoukko E on sovitus, jos mitkään kaksi E :n kaarta eivät liity samaan solmuun. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 184(279)

185 Suuntaamattomat verkot Esimerkki 3-7: On joukko opettajia ja joukko kursseja (oletetaan aluksi molempia olevan sama määrä). Kukin opettajista on pätevä opettamaan tiettyjä, muttei kaikkia kursseja. Halutaan kiinnittää kullekin kurssille pätevä opettaja, muttei kahta opettajaa samalle kurssille eikä kahta kurssia samalle opettajalle. Ongelma voidaan kuvata verkkona, jonka solmut ositetaan kahdeksi joukoksi: joukko V 1 koostuu opettajista ja joukko V 2 kursseista. Verkon kaari (v, w), v V 1 ja w V 2, ilmaisee opettajan v olevan pätevä opettamaan kurssia w. Opettajien kiinnittäminen eli sovitusongelma ratkaistaan valitsemalla kaaret verkosta mieluusti niin, että jokaiseen solmuun liittyy täsmälleen yksi kaari. 185 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 185(279)

186 Suuntaamattomat verkot Sovitus on täydellinen, jos jokainen kaksijakoisen verkon solmu liittyy toisen komponentin solmuun. Täydellinen sovitus ei aina ole mahdollinen: Osajoukoissa voi olla eri määrä solmuja, eikä aina muutenkaan. Maksimaalinen sovitus on sovitus jossa on suurin mahdollinen määrä kaaria, parhaassa tapauksessa siis täydellinen. Erilaisia sovituksia voi olla O(n!) kappaletta (ainakin). Suoraviivainen sovitusten läpikäynti ei käy! 186 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 186(279)

187 Suuntaamattomat verkot Käytetään ns. laajentavien polkujen tekniikkaa: Olkoon M jokin sovitus verkossa G. Solmu v V on sovitettu, jos M sisältää solmuun v johtavan kaaren. M:n suhteen laajentava polku P: Polku, joka yhdistää kaksi sovittamatonta solmua (polun päät) ja jonka joka toinen kaari sisältyy sovitukseen M (ja joka toinen ei sisälly). Pituus on pariton. Ensimmäinen ja viimeinen kaari eivät kuulu M:ään. Saadaan uusi sovitus M : M' =(M P) \ (M P) Siis lisätään laajentavan polut parittomat kaaret (uudet), poistetaan parilliset (ne, jotka olivat M:ssä ennestään). M on yhtä suurempi kuin M, M on sovitus. 187 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 187(279)

188 Koko algoritmi [toteutus: GraphEsimerkki.maksimaalinenSovitus()]: 188 Suuntaamattomat verkot 1) M :=. 2) Etsi M:n suhteen laajentava polku P ja aseta M := (M P) \ (M P). 3) Toista vaihetta 2, kunnes ei enää löydy laajentavaa polkua, jolloin M on maksimaalinen sovitus. [Todistus tuloksen maksimaalisuudesta sivuutetaan] Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 188(279)

189 Suuntaamattomat verkot Laajentavan polun etsiminen (Leveys)suuntaisella haulla aloittaen sovittamattomista solmuista, edeten vain niihin haaroihin, joissa laajentavan polun ehto täyttyy (joka toinen kaari sovitettu, joka toinen ei) Kts. GraphEsimerkki.maksimaalinenSovitus(). Syvyyssuuntaisella haulla algoritmi toimii myös, mutta aikavaativuus voi olla huono (pahimmassa tapauksessa etsitään ja löydetään tarpeettoman pitkiä polkuja). Painotetussa maksimaalissa sovituksessa (kullakin kaarella on paino/hinta) haetaan täydentävä polku käyttäen lyhyintä polkua. Maksimaalinen sovitus voidaan ratkaista myös maksimaalisen virtauksen hakevalla Ford-Fulkerson -algoritmilla, s Verkon toteuttaminen, kohta 6.2 (s. 268). 189 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 189(279)

190 Luku Algoritmistrategioita Algoritmistrategioita Esimerkkejä, virikkeitä, ajatuksia, tekniikoita. Kerrataan jo nähdyt. Näytetään pari uutta. Vielä yksi lajittelualgoritmi. Merkkijonon hakualgoritmeja esimerkkinä erilaisista lähestymistavoista. Tarkemmin ASA -kurssilla. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 190(279)

191 4.1 Ahne eteneminen 191 Algoritmistrategioita Valitaan aina kussakin vaiheessa parhaimmalta näyttävä vaihtoehto. Käytetään esimerkiksi prioriteettijonoa, tai satunnaista valintaa. Esim. Dijkstran, Primin algoritmit, ahne väritys. On varmistuttava ettei valinta sulje pois muita mahdollisuuksia. Toki voidaan käyttää mahdollisesti väärän tuloksen antavaa ahnetta algoritmia tietoisella riskillä jos tulos on riittävän hyvä ja optimaalisen tuloksen hakeminen olisi liian työlästä (suoritusaika ja/tai ohjelmointityö). Huffman-koodaus. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 191(279)

192 Esimerkki 4-1: Kolikoiden valinta ("vaihtorahaongelma", Java-toteutukset kurssin verkkosivulla): 192 Algoritmistrategioita Käytettävissä tietynkokoisia kolikoita (esim: 1c, 2c, 5c, 10c, 20c, 50c). Mikä on pienin määrä kolikoita jolla annettu summa voidaa rakentaa? Esim. 65c = Ahne algoritmi: Otetaan aina suurin kolikko joka voidaan (korkeintaan jäljellä olevan summan kokoinen). Ym. kolikoilla tulos on aina optimaalinen. Nopea, (suunnilleen O(r/s + s)), missä r on rahamäärä ja s suurin kolikko. Mahdollista vielä vähän viilata. Entä jos kolikot olisivatkin 1c, 2c, 5c, 10c, 40c, 50c)? 80c: , mutta olisi parempi!!! Ahne valinta (50) sulki pois paremman valinnan! Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 192(279)

193 4.2 Hajoita-ja-hallitse 193 Algoritmistrategioita Jaetaan syöte osiin, ratkaistaan pienemmät osatehtävät rekursiivisesti, yhdistetään osatulokset. Rekursio päättyy triviaaliin tapaukseen. Varsinainen työ tehdään yleensä yhdistämisessä (tai jakamisessa). Esim. binäärihaku, pikalajittelu, lomituslajittelu, FFT. Yleensä jako on kahteen (tai useampaan) tasakokoiseen osaan. Mutta jako voi olla myös epätasainen, jopa vain yhden alkion vähentävä. Yhdistämistyö voidaan tehdä joko ennen rekursiojakoa (pikalajittely) tai sen jälkeen (lomituslajittelu). Esimerkki 4-2: Hajoita-ja-hallitse kolikkovalinta: Jaetaan ongelma yhden kolikon ja loppusumman ongelmaksi. Kussakin vaiheessa on yhtä monta tälläistä ositusta kuin erilaisia kolikoita on. Valitaan näistä paras. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 193(279)

194 Algoritmistrategioita int hjhjako(int rahamaara, Iterable<Integer> Kolikot) { 1 if (rahamaara == 0) 2 return 0; 3 int tulos = rahamaara; // yläraja 4 for(integer c : Kolikot) // kolikkojen arvojen läpikäynti 5 if (c <= rahamaara) 6 tulos = min(tulos, 1 + jako(rahamaara c)); 7 return tulos; 8 } 9 Kuten Fibonaccin lukujen määritelmään perustuvassa ratkaisussa, tässäkin tehdään valtavasti moninkertaista työtä. Funktiota kutsutaan useasti samalla parametrilla. Aikavaativuus ekponentiaalinen, 35c = 1min 194 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 194(279)

195 4.3 Dynaaminen ratkaiseminen (ohjelmointi) 195 Algoritmistrategioita Tallennetaan osatehtävien ratkaisut myöhempää käyttöä varten. Erityisesti optimointiongelmiin. Pohjana usein rekursiivinen ongelman määrittely. Jos sama osatehtävä esiintyy usein, tallennetaan sen tulos taulukkoon. Esimerkiksi Floydin algoritmi lyhyimpien polujen hakuun. Osaratkaisujen hyödyntämiseksi tehdään ratkaisu alhaalta ylös. Esimerkki 4-3: Kolikkovalinta dynaamisesti ratkaisten: Hieman samaan tapaan kuin edellinen hajoita-ja-hallitse, mutta lasketaan ensin pienet osaongelmat ja tallennetaan niiden ratkaisut taulukkoon. Suurempaa rahasummaa ratkaistaessa kokeillaan minkä mahdollisen kolikon käyttö antaisi jäännökselle pienimmän kolikkomäärän. Kaikki pienemmät summat on jo ratkaistu valmiiksi, joten tämä on helppoa ja nopeaa. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 195(279)

196 Algoritmistrategioita int dynjako(int rahamaara, Iterable<Integer> Kolikot) { 1 int[] ratkaisut = new int[rahamaara+1]; 2 ratkaisut[0] = 0; 3 for (int i = 1; i <= rahamaara; i++) { 4 int min = i; 5 for (Integer c : Kolikot) 6 if (c <= i && ratkaisut[i c]+1 < min) 7 min = ratkaisut[i c]+1; 8 ratkaisut[i] = min; 9 } 10 return ratkaisut[rahamaara]; 11 } 12 Samalla vaivalla saadaan myös kaikki annettua rahamäärää pienempien tehtävien ratkaisut. Aikavaativuus O(rahamäärä Kolikot ) Kullekin kolikkojoukolle voidaan laskea raja jota suuremmat rahasummat voidaan ratkaista ottamalla rajaa suurempi osuus suurinpina kolikkoina ja ratkaista vain loppusumma yo. algoritmilla. 196 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 196(279)

197 Algoritmistrategioita Ratkaisun (kolikkojoukon) tallentaminen (HT): Paras ensimmänen kolikko kullekin rahasummalle löydetään rivillä 7. Tallennetaan toiseen taulukkoon kunkin rahasumman s kohdalle kolikko k joka ensimmäiseksi annetaan. Seuraava kolikko selviää "rekursiivisesti" saman taulukon kohdasta s k. 197 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 197(279)

198 4.4 Tasoitettu aikavaativuus 198 Algoritmistrategioita Jos (osa)algoritmia kutsutaan peräkkäin useasti (samassa suorituksessa), sen ei tarvitse olla aina nopea. Riittää että se on keskimäärin nopea. Yksittäinen hidas suoritus ei haittaa jos muut ovat nopeita. (O(n) + n O(1))/n = O(1) (O(logn) + logn O(1))/logn = O(1) logn n --- =O(n) i = 02 i Binääripuun läpikäynti sisäjärjestyksessä. Merge-Find -joukon toteutus. Fibonaccin kasa. Jos jostain syystä halutaan jokainen kutsukerta yhtä nopeaksi, voidaan joissain algoritmeissa jakaa harvoin esiintyvä lisätyö usealle eri kutsukerralle. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 198(279)

199 Esimerkki 4-4: Järjestetyn joukon toteuttaminen taulukossa: (*) 199 Algoritmistrategioita Taulukon pääosa järjestetty, taulukon lopussa korkeintaan O(logn) järjestämätöntä alkioita. Lisäys aina taulukon loppuun O(1) ajassa, paitsi, jos lopun järjestämätön osuus kasvaa liian suureksi, jolloin tarvitaan lopun lajittelu (O(lognloglogn)) ja lomitus (O(n)). Lisäys keskimäärin O(n/logn), haku aina O(logn) (binäärihaku alusta + peräkkäishaku lopusta). Jos lisäyksen nopeutta halutaan parantaa (haun kustannuksella), annetaan taulukon lopun järjestämättömän osuuden kasvaa O( np):een, jolloin järjestämiseen ja lomitukseen ei mene juuri enempää aikaa, mutta sitä tarvitaan harvemmin. Lisäys keskimäärin O( n), samoin haku. Läpikäynti järjestyksessä edellyttää lopun järjestämistä ennen varsinaista läpikäyntiä, mutta läpikäynnin aikavaativuus on silti O(n), eli O(1) alkiota kohti. Poisto-operaatiossa vain merkitään alkio poistetuksi, ei siirrellä muita. Tasapainotetun binääripuun aikavaativuuteen ei päästä. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 199(279)

200 4.5 Haun rajoittaminen 200 Algoritmistrategioita Oletetaan tilanne jossa haetaan parasta vaihtoehtoa (lyhyintä polkua, tms.) painotetussa verkossa tai puussa (vakiopainoisilla kaarilla leveyssuuntainen haku riittää). Syvyyssuuntaista hakua voidaan rajoittaa muistamalla paras siihenmennessä löydetty ratkaisu ja katkaisemalla rekursio aina kun ko. taso on saavutettu. Keskeneräisiä hakuja voidaan ylläpitää rekursiossa, jonossa tai prioriteettijonossa, tai muuten muistaa asema haussa ja peruuttaa (backtrack) edelliseen haarautumiskohtaan. Pelin siirron optimointi (tilanteen arvottaminen): haussa haaraudutaan eri siirtoihin, sekä positiivisia, että negatiivisia siirtymiä. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 200(279)

201 4.6 Satunnaistetut algoritmit 201 Algoritmistrategioita Algoritmi voi käyttää satunnaislukugeneraattoria hyväkseen. Kokeilla satunnaisia (osa)ratkaisuja. Jakaa osatehtäviin satunnaisesti. Ottaa satunnaisia näytteitä. Rikkoa (pahaa) säännönmukaisuutta satunnaisuudella. Laskea satunnaisotannan keskiarvoja (tai muita tunnuslukuja). Päätyypit Las Vegas: Aina oikea tulos, aika voi vaihdella, satunnaistuksella esimerkiksi rikotaan säännönmukaisuutta. Pikalajittelu: jakoalkioksi (kolmen tai useamman) satunnaisesti valitun alkio(n (pseudo)mediaani). Monte Carlo: Pieni virhe sallitaan, aika rajallinen. Piin likiarvon laskenta ympyrän sisä/ulkopuolelle osuneiden arvontojen suhteena, likimääräinen integrointi. Satunnainen ratkaisu ja sen paikallinen optimointi. Paras satunnaisista (satunnaistetuista) ratkaisuista. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 201(279)

202 Algoritmistrategioita Geneettiset algoritmit: Tuotetaan aluksi (satunnaisia) ratkaisuja, valitaan näistä parhaat. Risteytetetään ratkaisuja keskenään. Osa toisesesta ratkaisusta ja osa toisesta. Mutatoidaan ratkaisuja. Tehdään (pieniä) satunnaisia muutoksia. Risteytysvaiheen jälkeen valitaan parhaat. Toistetaan prosessia kunnes ratkaisu on riittävän hyvä (tai aika loppuu). Soveltuu vain joillekin ongelmille. Esim. selkäreppuongelma, suoritusjärjestysongelmat. Pystyttävä tehokkaasti arvioimaan ratkaisun hyvyyttä. Pystyttävä risteyttämään/mutatoimaan ratkaisuja niin, että ne ovat edelleen kelvollisia ratkaisuja. Esimerkiksi valittavat alkiot (bitti)vektorissa. Ongelmana voi olla pysähtyminen paikalliseen optimiin. Mutaation aste on kompromissi tehokkuuden ja paikallisiin optimeihin tarttumisen välillä. 202 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 202(279)

203 4.7 Kantalukulajittelu 203 Algoritmistrategioita Kaukalolajittelu Avaimet (tai alkiot) välillä 1..m, missä m kohtuullisen kokoinen. Muodostetaan m kaukaloa (taulukko 1..m), O(m) aika. Jos koko alkio ilmaistaan lukuina 1..m, riittää laskea kuhunkin kaukaloon tulevien määrä taulukon alkiot kokonaislukuja. Jos 1..m on vain avain, ts. talletettava muutakin, taulukon alkiot ovat elementtilistoja. Viedään lajiteltavan kokoelman kukin alkio suoraan oikeaan kaukaloon avaimen perusteella. Kunhan toteutus on tehokas, kukin lisäys onnistuu vakioajassa, ja koko toimenpide O(n) ajassa. Joko ketjutetaan m listaa yhdeksi listaksi (O(m) aika) tai kopioidaan alkiot listoista takaisin alkuperäiseen kokoelmaan (O(m + n) aika). Koko algoritmi O(m + n) aika ja aputila. Huomaa: ei yhtään vertailua! Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 203(279)

204 Algoritmistrategioita Kantalukulajittelu Kantalukulajittelu (radix sort) on yleensä nopein peräkkäislajittelu kun avaimet ovat kohtuullisen lyhyitä ja syöte on suuri. Kaukalolajittelu ei ole hyvä/mahdollinen jos avainten mahdollinen arvoalue on suuri. Avaimena liukulukuja tai pitkiä merkkijonoja. Kaukalolistojen ylläpito ei ole helppoa/kaikkein tehokainta. Tehdään lajittelu vaiheittain avainmenosien mukaan. Jaetaan avaimen pituus sopivan kokoisiin osiin, lajitellaan ensin vähiten merkitsevän osan mukaan, sitten seuraavaksi merkitsevämmän osan mukaan,..., lopuksi merkitsevimmän avaimenosan mukaan Kuva 4-1: Vaiheittainen lajittelu. 204 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 204(279)

205 Algoritmistrategioita Avainten pätkiminen kannattaa tehdä avaimen tyypin mukaan jakojäännösaritmetiikalla tai bittioperaatioilla. Lajittelujen on oltava vakaita (stable), eli keskenään samanarvoisten alkioiden (avaimenosien mukaan) on pysyttävä alkuperäisessä järjestyksessä. Muutetaan kaukalolajittelua vielä siten, ettei kaukaloita varsinaisesti perusteta ja lajitella, vaan syöte käydään kahdesti läpi, ensin lasketaan esiintymät (histogrammi) ja toisella kerralla sijoitetaan alkiot lukumäärätaulukon 0-alkusumman osoittamaan paikkaan. T1: Esiintymiset T2: 345 R: alkusumma 343 R: Kuva 4-2: Kantalukulajittelu histogrammilla Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 205(279)

206 Algoritmistrategioita Alkusummat osoittavat suoraan, mihin kohtaan kunkin "kaukalon" alkiot tulevat. Saman "kaukalon" alkiot pidetään alkuperäisessä järjestyksessä. avain(t1[0]) = 3 T2[R[3]] = T[0]; R[3]++; avain(t1[1]) = 5 T2[R[5]] = T[1]; R[5]++; avain(t1[2]) = 3 T2[R[3]] = T[2]; R[3]++; T2[R[T1[i]]] = T[i]; R[T1[i]]++; tai jopa T2[R[T1[i]]++] = T[i]; Avaimenosan mukaan samat alkiot saadaan suoraan kohdalleen kun kasvatetaan 0-alkusumma -taulukon arvoja sitämukaa kun osoitettu paikka on käytetty. 206 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 206(279)

207 Algoritmistrategioita Jos/kun avaimet eivät ole kokonaislukuja, käytetään yleensä avaimen bittiesitystä r bittiä kerrallaan. Kaukaloita on siten 2 r. Tyypillinen arvo r:lle on 8-20, riippuen syötteestä ja koneen muistiarkkitehtuurista (R-taulukko välimuistiin). Kaukaloita on siis melko runsaasti. Käytettäessä yhtä aputaulukkoa, kannattaa m --- :n olla parillinen. m Aikavaativuus O( --- ( n + 2 r )), missä m on avaimen r pituus (bitteinä). r Välimuisteille haastava (jos r on iso), tehokkaampi jos keskusmuistiin kirjoitus viivästetty (ja nopea). 207 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 207(279)

208 Algoritmistrategioita 4.8 Merkkijonon haku T merkillinen esimerkkimerkkijono Missä kohtaa merkkijono P esiintyy merkkijonossa T? P merkki Merkitään n = T (tekstin pituus), m = P (avaimen pituus), Σ on aakkoston koko. Millä siirtymillä s [0..n m] toteutuu P[i] == T[s+i] i [0..m 1]? Hyvin yksinkertainen ongelma, melkoisesti algoritmeja. Perustapauksessa (liki) yksinkertaisinkin algoritmi on yleensä riittävän nopea, mutta nopeammat ovat opettavaisia (vrt. lajittelu). Haastavampia (hyödyllisempiä) versioita: usea avain, likimääräinen etsintä, säännöllisen lausekkeen etsintä, lähimpänä olevan etsintä, useampi ulottuvuus, skaalattuna, jne. Hahmontunnistus. Esitellään pari tekniikkaa, algoritmien tarkempi toteutus: HT/kirjat. 208 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 208(279)

209 Algoritmistrategioita Naiivi algoritmi Kokeillaan jokaisesta tekstin T kohdasta, josko avain P alkaisi siitä. O(nm) aika (pahin tapaus). P = 00001, T = Satunnaisella syötteellä O(n). (Odotusarvo 2n vertailua binäärisyötteellä). java.lang.string.indexof(string) käyttää tätä. Tehottomuus: Jos/kun joudutaan tekemään useita vertailuja, niiden tulosta voitaisiin ehkä hyödyntää myöhemmin. Usean avaimen haku hidastaa avainten määrän kertoimella. 209 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 209(279)

210 Algoritmistrategioita Rabin-Karp algoritmi Lasketaan avaimen (tai sen alkuosan) sormenjälki (kokonaisluku) hajautusfunktion tapaan (h(p[0..m 1])) Lasketaan sormenjälki kustakin tekstinkohdasta samalla tavalla. Samaan sormenjälkeen törmättäessä tarkastetaan josko todella oli kyse samasta merkkijonosta. Tehokkuuden kannalta on tärkeää pystyä laskemaan nopeasti (vakioajassa) h(t[i+1..i+m]) käyttäen hyväksi edellistä h(t[i..i+m 1]):tä. Tekstin sormenjälkeä lasketaan "liukuvalla ikkunalla" lisäämällä aina sormenjälkeen yksi uusi kirjain ja poistamalla ensimmäisenä lisätty kirjain (FIFO). Oletetaan merkistön olevan numeroita Haettava merkkijono Teksti Sormenjälki lasketaan (esimerkissä helppouden vuoksi) kaavalla i Pi [] mod 13, eli avaimesta 175 mod 13 = 6. i = Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 210(279)

211 Algoritmistrategioita Tekstistä lasketaan kolmen ensimmäisen merkin avain 234, t =( ) mod 13 = 0 (eli avainta ei löydy tältä kohtaa). Seuraavaksi t = (t 2 100) = 345 mod 13 = 7 Ts. vähennetään ensimmäisen merkin vaikutus (luku 2, kerroin nyt 10 2 )jalisätään uusi (5). Samalla mukana jo olevien (3 ja 4) kerroin kasvaa 10:llä. Seuraavaksi t = (t 3 100) = 456 mod 13 = 1 Seuraavaksi t = (t 4 100) = 567 mod 13 = 8 Seuraavaksi t = (t 5 100) = 678 mod 13 = 2 Seuraavaksi t = (t 6 100) = 789 mod 13 = 9 Seuraavaksi t = (t 7 100) = 890 mod 13 = 6 On tarkastettava merkkivertailulla onko todella kyseessä löytö (ei). jne. Oikeasti käytetään niin suurta moduloa kuin koneen laskentatarkkuus antaa myöten (32 bit), 10:llä kertomisen sijaan esim <<= 1, jolloin useampaa merkkiä voidaan pitää mukana. Lisäämisen sijaan XOR. Aikavaativuus O(n + m) (vakiot valittu järkevästi, eikä pahin tapaus). Useaa avainta voidaan hakea kun sormenjäljet ovat hajautustaulussa. 211 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 211(279)

212 Algoritmistrategioita Äärellisellä automaatilla hakeminen Avaimesta muodostetaan (ajassa O(m Σ ) äärellinen automaatti joka a a a b a b c a a a lukee tekstiä. Merkkijonon löytyminen on erityinen lopetustila. Automaatin siirtymät merkitty aakkoston merkeillä. Kustakin tilasta siirtymä kullakin merkillä. Itse haun aikana käydään läpi tekstiä ja kunkin merkin kohdalla tehdään ko. merkkiä vastaava siirtymä tilasta toiseen. Aikavaativuus O(n + m Σ ), myös pahin tapaus. Usean avaimen haku voidaan mahduttaa samaan automaattiin. Kullakin avaimella oma lopputila. Varsinaisen haun aikavaativuus ei muutu lainkaan. 212 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 212(279)

213 Algoritmistrategioita Esimerkiksi avain "ababc" 0 on alkutila, tila 5 merkitsee merkkijonon löytymistä. tila merkki a b c * Kuvassa nimetty vain oleelliset siirtymät, kaikki muut siirtymät (taulukossa *) johtavat alkutilaan, kuvassa merkitty harmaalla katkoviivalla Ohjelmassa automaatti esitetään 2-ulotteisena taulukkona josta kussakin tilassa seuraavana tulevan merkin kohdalta katsotaan mihin tilaan seuraavaksi siirrytään. Tehokkuuden ja yksinkertaisuuden vuoksi myös kaikki siirtymät alkutilaan kannattaa tallettaa. 213 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 213(279)

214 Θ(n) hakeminen on helppoa, onko sitä mahdollista parantaa? 214 Algoritmistrategioita Siis kaikkia tekstin merkkejä ei edes tarkasteltaisi! Boyer-Moore algoritmi Hieman kuten naiivi algoritmi, mutta pyritään ohittamaan enemmän merkkejä kerralla. Kunkin siirtymän tarkastus tehdään avaimen lopusta alkaen. merkillinen_esimer merkki merkki merkki Kun löydetään tekstistä väärä merkki x, voidaan siirtää avainta eteenpäin enemmänkin, riippuen esiintyykö merkki x avaimessa vai ei, ja jos esiintyy, niin missä kohtaa. Jos tekstin merkkiä x ei löydy koko avaimesta, voidaan siirtyä koko avaimen pituus eteenpäin ja jatkaa siitä. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 214(279)

215 Algoritmistrategioita Jos merkki x on avaimessa, siirretään avainta siten, että avaimen merkin x viimeinen esiintymä tulee tekstin merkin x kohdalle ja jatketaan siitä (viimeisen esiintymän taulukko) Jos avaimen lopusta on merkillinen_esimerkikmerkkijono merkki merkki merkki merkki merkki merkki jo jokin merkki löydetty, käytetään myös toista aputaulukkoa (oikean loppuosan taulukko) joka kertoo esiintyykö sama loppuosa avaimessa aiemmin. Käytännössä otetaan kahden mahdollisen siirtymän maksimi. Siirtymätaulukot voidaan rakentaa ennen haun aloittamista ajassa O(m + Σ ), missä Σ on aakkoston koko. Hyvässä (ja keskimääräisessä) tapauksessa itse haku sujuu ajassa O(n/m), pahin tapaus O(n). Käytännössä varsin hyvä hakualgoritmi (ainakin viritettynä) jos teksti, aakkosto ja avain ovat kohtuullisen suuria eikä avaimessa ole toistoa. Jos muistiväylä on pullonkaula, vasta pidemmät hypyt auttavat. 215 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 215(279)

216 Algoritmistrategioita Likimääräinen hakeminen Merkkijonot A ja B ovat eroavat k merkillä jos seuraavia virheitä on korkeintaan k kappaletta: Merkki a i on eri kuin b i. Merkki a i puuttuu merkkijonosta B. Merkki b i puuttuu merkkijonosta A. Esim: jono, pino: k = 2. iso, pino: k = 2. jono, noki: k = 4. Kun tekstistä T haetaan avainta P, etsitään ne osat T:stä joissa eroa on enintään k merkkiä. Jos merkkijono löytyy jostain kohdasta erolla k, se löytyy viereisistä paikoista erolla k+1. Esim. kino, merkkijono. Väärien, puuttuvien ja ylimääräisten yhdistelmä voi olla mikä vain. 216 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 216(279)

217 Algoritmistrategioita Dynaaminen algoritmi likimääräiseen hakemiseen [2]: Rakennetaan matriisi jossa tekstin merkit ovat sarakkeilla, avaimen merkit riveillä. Indeksoidaan avain 1..m ja teksti 1..n. Matriisin alkio (i, j) kertoo pienimmän virheiden määrän avaimen osajonolle 1..i kun sitä verrataan merkkijonoon joka päättyy tekstin merkkiin j. Matriisin rivi 0 alustetaan nolliksi (ei eroja tyhjässä osamerkkijonossa). Matriisin sarake 0 alustetaan indeksillä (kuvaten T:n alusta puuttuvia P:n merkkejä). 217 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 217(279)

218 Algoritmistrategioita merkki T a b c a a a b c a d c a b a b c c a b indeksi P a b a b c Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 218(279)

219 Algoritmistrategioita Matriisin arvot lasketaan riveittäin. merkki T a b c a Kuhunkin soluun lasketaan pienin arvo seuraavista: indeksi Vasemmanpuoleinen solu P D[i][j 1] +1 (tekstissä ylimääräinen merkki). a Ylempi solu D[i 1][j] (avaimessa ylimääräinen b merkki) Joko: +1 a Jos merkit ovat samat: vasemmalla yläpuolella oleva luku D[i 1][j 1] (ei eroa, merkkijono jatkuu). Jos merkit ovat eri: vasemmalla yläpuolella oleva luku D[i 1][j 1] + 1 (ero, mutta merkkijono jatkuu). Matriisin viimeinen rivi näyttää eron ko. tekstin merkkiin (sarakkeelle) loppuvasta osajonosta. Esimerkissä merkkijono abc löytyy merkkijonosta abca erolla 1 loppukohdista 2, 3 ja Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 219(279)

220 Algoritmi 4-5: Likimääräinen haku dynaamisella ohjelmoinnilla: 220 Algoritmistrategioita LinkedList<Integer> likimaarainenhaku(char[] T, char[] P, int k) { 1 int n = T.length; int m = P.length; 2 int[][] D = new int[m+1][n+1]; 3 for (int i = 0; i <= m; i++) 4 D[i][0] = i; // alkusiirtymä 5 for (int i = 0; i <= n; i++) 6 D[0][i] = 0; // tyhjä avain 7 for (int i = 1; i <= m; i++) // rivi kerrallaan 8 for (int j = 1; j <= n; j++) // sarakkeet 9 if (P[i 1] == T[j 1]) // varsinainen vertailu 10 D[i][j] = min(d[i 1][j]+1, D[i][j 1]+1, D[i 1][j 1]); 11 else 12 D[i][j] = min(d[i 1][j]+1, D[i][j 1]+1, D[i 1][j 1]+1); 13 LinkedList<Integer> L = new LinkedList<Integer>(); 14 for (int j = 1; j <= n; j++) 15 if (D[m][j] <= k) // löytö 16 L.add(j 1); // T 0-alkuinen 17 return L; } 18 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 220(279)

221 Algoritmistrategioita Alkukohta voidaan selvittää takaperin vasemmalle ylös. Samaan loppukohtaan voi päättyä useita erilaisia likimääräisiä osumia. Paras osuma etsittäessä ylös/yläviistoon/vasemmalle pieniarvoisin reitti. Aikavaativuus selkeästi O(nm), vakiokerroin pienehkö. Helppo muuttaa parhaan osuman etsinnäksi (HT). On olemassa loppuosapuita käyttävä algoritmi joka suoriutuu tehtävästä O(n(logm + k) ajassa, käytännössä tehokkaampi jos k << m. 221 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 221(279)

222 Luku Ulkoisen muistin käsittely Ulkoisen muistin käsittely Aina ei syöte, aputila ja/tai tulos ole keskusmuistissa! Ei mahdu (erityisesti palvelimet, mobiililaitteet). Ei kannata varastoida keskusmuistiin (jossa se ei ole turvassa). Ei ole keskusmuistissa ennen ohjelman käynnistämistä. Kaikki oikeat ohjelmat tarvitsevat massamuistia! Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 222(279)

223 Ulkoisen muistin käsittely Mitä pitää ottaa huomioon massamuistia käsiteltäessä? Siirräntä on käyttöjärjestelmän asia. Massamuistin käsittelyyn tarkoitettujen rutiinien parametrit ovat kieli/käyttöjärjestelmä-riippuvainen asia. Tiedoston sisältämään tietoon ei voi suoraan viitata. Tieto on ensin haettava keskusmuistiin. Tietoa haetaan lohko kerrallaan (yleensä 0,5-4 kt). Käyttöjärjestelmä hakee kokonaisen lohkon kerrallaan, vaikka pyytäisimme vain yhtä bittiä. Samoin tallentaminen tehdään lohko kerrallaan. Tiedon lukeminen (ja siirtäminen) on hitaampaa kuin keskusmuistissa ( Mt/s vs. 2-20Gt/s, 100 ). Kirjoitus suunnilleen yhtä hidasta. Tiedon paikantaminen on todella hidasta (5-15 ms pelkkään yhden oikean lukukohdan etsimiseen, vrt ns, ). Erillisten massamuistihakujen lukumäärä on usein selvästi merkitsevin tekijä! 223 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 223(279)

224 5.1 Tiedostokäsittely 224 Ulkoisen muistin käsittely Tiedostoja käsitellään lohkoittain Tyypillinen lohkon (levyjakson) koko 512 tavua (0,5-4kt). Tähän mahtuu usein monta tietuetta (riippuen tietueesta). Lohko siirretään keskusmuistiin kokonaisuudessaan. Jos yksikin tietue (tai edes bitti) muutetaan, on muutettu lohko vietävä massamuistiin kokonaan. Jos tiedostolla on muutakin samanaikaista käsittelyä, on varmistettava etteivät muutokset peitä toisiaan. Mielivaltaisen lohkon haku kestää pitkään (vaikka siis tiedämme (levyohjain tietää) tarkan osoitteen pinta:ura:sektori). Lukupään siirtyminen, levyn pyörähdys ms ( kellojaksoa). Peräkkäisiä lohkoja voidaan lukea nopeahkosti. Kunhan välillä ei viivytellä (päästetä levyä pyörähtämään eteenpäin). Lohkon kesto 0,0025-0,010 ms (10000 kellojaksoa, 20 kelloj/tavu). Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 224(279)

225 Ulkoisen muistin käsittely Esimerkki 5-1: Satunnaishaku vs. peräkkäishaku (Hitachi US10K300) Yhteen lohkoon mahtuu 512 tavua, Tietueen koko on 25 tavua, lohkoon mahtuu 20 tietuetta. Keskimääräinen hakuaika 5 ms Lohkon kesto 0,005 ms (100 Mt/s) Satunnaisessa järjestyksessä 5 ms / tietue = 200 tietuetta/s Peräkkäisessä järjestyksessä 0,005 / 20 = 0,25 µs / tietue = tietuetta/s tietuetta (2,5 Mt) : 8 min vs. 0,025 s. Jos välimuistissa pidetään kerralla 100 lohkoa = 2000 tietuetta, haku osuu 5 % todennäköisyydellä jo muistissa olevaan lohkoon, ei paljoa auta... Algoritmin valinta on vielä tärkeämpää kuin keskusmuistin varaisissa algoritmeissa. Syötteet usein suurempia, käsittely suhteellisesti hitaampaa. 225 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 225(279)

226 Esimerkki 5-2: Aikavaativuus tulkittuna ajaksi. 226 Ulkoisen muistin käsittely n n 2 5ms n 2 0,25µs + n 5ms nlogn 0,25µs + logn 5ms 10 0,5 s 50 ms 20 ms s 502 ms 35,2 ms ,4 t 5,25 s 52,5 ms ,8 pv 75 s 105 ms ,6 v 50 min 510 ms v 71 t 5,1 s v 290 pv 60,1 s O(n 2 ) algoritmi, joka viittaa tietoihin satunnaisesti O(n 2 ) algorimi, joka tekee kunkin iteraation peräkkäin, ja O(nlogn) algoritmi, joka tekee iteraation peräkkäin. Haun alussa aina 5 ms, seuraavat peräkkäiset 0,25 µs/tietue. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 226(279)

227 Puskurien käyttö 227 Ulkoisen muistin käsittely Puskuriin luetaan tietoa peräkkäin tiedostosta käsittelyä varten. Vastaavasti puskuriin kerätään tietoa odottamaan tiedostoon kirjoittamista. Jos (kuten yllä) käsitellään vain yhtä tiedostoa kerrallaan, 1-2 puskuria riittää. Jos käsitellään kerrallaan kahta tai useampaa tiedostoa (tai samaa tiedostoa muutamasta kohtaa) vuorotellen, puskurit ovat tärkeitä. Puskuroinnilla vähennetään hakukertojen määrää hakemalla usea tietue kerrallaan. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 227(279)

228 Esimerkki 5-3: Peräkkäiskäsittely, kaksi syötetiedostoa A ja B, yksi tulostiedosto C, käsitellään tiedostoja "samanaikaisesti" (vuorotellen). 228 Ulkoisen muistin käsittely Esimerkiksi C[i] = A[i] + B[i]; tai jotain hyödyllistä O(n) työ. Edelliset oletukset (512 t/lohko, 25 t/tietue, 20 tietuetta/lohko, tietuetta, 25 Mt tiedosto, hakuaika 5 ms, lohkon lukuaika 0,005 ms). ei puskurointia (1 tietue) luetaan 1 kpl A:ta, 1 kpl B:tä, kirjoitetaan 1 kpl C:tä, luetaan 1 kpl A:ta, jne 3 5 ms / 1 tietue = 67 tietuetta/s = 4t. yksi puskuri/tiedosto (1,5 kt): luetaan 20 kpl A:ta, 20 kpl B:tä, kirjoitetaan 20 kpl C:tä, jne 3 (5 ms + 0,005 ms) / 20 tietuetta = 1332 tietuetta/s = 750 s. 10 puskuria/tiedosto (15 kt): luetaan 200 kpl A:ta, 200 kpl B:tä, kirjoitetaan 200 kpl C:tä, jne 3 (5ms+10 0,005 ms) / 200 tietuetta = tietuetta/s = 76 s. 100 puskuria/tiedosto (150 kt): luetaan 2000 kpl A:ta, jne 3 (5ms+100 0,005ms)/2000 = tietuetta/s = 8,3s. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 228(279)

229 Ulkoisen muistin käsittely 1000 puskuria/tiedosto (1,5 Mt): kpl 3 (5 ms ,005 ms) / = tietuetta/s = 1,5 s puskuria/tiedosto (15 Mt): kpl 3 (5ms ,005 ms)/ = tietuetta/s = 0,82s puskuria/tiedosto (150 Mt): (tiedostoa suurempi!) kpl 3 (5 ms ,005 ms) / = tietuetta/s = 0,75 s. Johtopäätös: Kohtuullinen puskurointi on elinehto, kohtuuton syö muistia. 1 haku vastaa 1000 lohkon lukua ( = tietuetta, 0,5Mt). WD Caviar Black 2TB: haku: 9,8ms, luku 150MB/s = 1,47Mt/9,8ms. 229 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 229(279)

230 5.2 Onko keskusmuisti ulkoista muistia? 230 Ulkoisen muistin käsittely Muisti Viive kellojaks. 1. tavun hitaus pätee kaikilla tasoilla. Kaista, Mt/s Tilavuus, tavua Lohko, sanaa rekisterit t 1 1-tason välimuisti kt ~4 2-tason välim. (pros) ,25-12 Mt ~8 3-tason v. (emolevy) Mt ~16 keskusmuisti Gt ~16 kiintolevy(stö) 2-30 M 150 0,1-50Tt ~128 nauha(roboti)t 200 G 50 0,1- Tt ~128 Seuraavat tavut tulevat yleensä tiiviinä purskeena ensimmäisen perässä. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 230(279)

231 Ulkoisen muistin käsittely Johtopäätös: välimuistioptimointi on tärkeää. Vältä hajakäsittelyä kaikilla tasoilla. Suosi peräkkäiskäsittelyä. Suosi paikallisuutta. Suosi sopivan kokoisia lohkoja. Viimeisenpäälle tarkka välimuistioptimointi on arkkitehtuurikohtainen taiteelaji, mutta yo. neuvot pätevät kaikille alustoille. 231 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 231(279)

232 232 Ulkoisen muistin käsittely Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 232(279) e e+07 Esimerkki 5-4: Taulukon käsittely peräkkäin/hajasaantina: cs: 1,28GHz UltraSparc IIIi: 64kt 1-tason välimuisti, 1Mt 2-tason välimuisti Mt/s suora väli 1 väli e cs taulukko (t)

233 233 Ulkoisen muistin käsittely Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 233(279) cslap79: 1,6GHz Pentium M 32kt 1-tason datavälimuisti, 2Mt 2-tason välimuisti e e e suora väli 1 väli 257 cslap taulukko (t) Mt/s

234 234 Ulkoisen muistin käsittely Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 234(279) e+07 cspc33: 1,6GHz Pentium 4 8kt 1-tason datavälimuisti, 256kt 2-tason välimuisti e e suora väli 1 väli 257 cspc taulukko (t) Mt/s

235 235 Ulkoisen muistin käsittely Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 235(279) 2,0GHz AMD Athlon XP 128kt 1-tason välimuisti, 256kt 2-tason välimuisti koti e e e e suora väli 1 väli taulukko (t) Mt/s

236 Ulkoisen muistin käsittely Flash-muistin erikoisuudet Flash-muisti on sähköisesti pyyhittävää ohjelmoitavaa lukumuistia (Electrically-Erasable Programmable Read-Only Memory, EEPROM). Read-only: lukeminen nopeaa, ei kirjoitusmahdollisuutta. Programmable: säilytettävä arvo voidaan kirjoittaa muistiin ohjelmallisesti. Electrically-Erasable: muisti voidaan tyhjentää sähköisesti. Flash:ssä tyhjennys voidaan tehdä lohkoittain (eikä tavu kerrallaan kuten EEPROM / koko muisti kuten EPROM). Tyhjä muisti sisältää vain ykkösiä (bittejä), kirjoittaa voidaan vain nollia. Pyyhkiminen palauttaa kaikki ykkösiksi. Kahta päätyyppiä NOR: vanhempi tavuperustainen luku ja kirjoitus. NAND: uudempi, lohkoperustainen luku ja kirjoitus, suurempi kapasiteetti, halvempi. 236 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 236(279)

237 Ulkoisen muistin käsittely Lukeminen lähes yhtä nopeaa kuin DRAM:sta (varsinkin NOR-tyyppi NAND on hitaampi). NOR: 5 viive, NAND: 200 viive verrattuna DRAM. Kaistaa tosin vain 2-20 Mt/s (enemmän rinnakkaisuudella). Kirjoittaminen hidasta NOR:lla, hitaahkoa NAND:llä (2-6Mt/s). Lukeminen ja kirjoittaminen voidaan tehdä tyypistä riippuen tavu kerrallaan (NOR) tai sivu (0,5-4kt) kerrallaan (NAND). Tyhjentäminen tehdään suuremmissa lohkoissa, tyypillisesti 128kt. Tyhjennys kirjoitus sykli voidaan tehdä vain n (10k 1M) kertaa. Jotta muisti "kuluisi" tasaisesti, lohkoja kierrätetään. Vähän muutettuja tietoja siirretään paljon käytetyille aluelle. Paljon muutettuja tietoja tallennetaan vähän käytetyille alueille. 237 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 237(279)

238 Tiedon muuttaminen ei siis ole mahdollista. 238 Ulkoisen muistin käsittely Muuttaminen tehdään kopioimalla uusi tieto ja loppuosa vanhasta sivusta toiseen paikkaan. Yhden tavun kirjoittaminen on siten hitaampaa kuin koko sivun kirjoittaminen (lukeminen + kirjoittaminen vs. kirjoittaminen). Kirjoittaminen vie jopa 0,5ms. Tyhjentämisoperaatiot vievät aikaa useita millisekunteja, jopa sekunnin. Tehdään usein taustalla jos mahdollista. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 238(279)

239 5.3 Ulkoinen lajittelu 239 Ulkoisen muistin käsittely Esimerkki ulkoisen muistin algoritmeista. Käytetään kussakin vaiheessa peräkkäistä käsittelyä. Minimoidaan vaiheiden määrä. Puskuroidaan riittävästi. Lajittelussa tarvitaan ainakin kaksi tiedostoa (lähde ja tulos). Käytännössä myös kaksi kohtaa lähdetiedostosta tai kaksi lähdetiedostoa, eli 3 tiedosto(kohta)a. Mikä soveltuu? Ei mikään O(n 2 ) algoritmi. Pikalajittelu: siirtoja tehdään puolelta toiselle, rekursio pirstoo. Kasalajittelu: prioriteettijonon toteutus vaatii hajasaantia. Lomituslajittelu: peräkkäistä käsittelyä! Vältetään vielä rekursion pirstova vaikutus, niin kaikki vaatimukset täytetään. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 239(279)

240 Lomituslajittelu peräkkäistiedostoilla (jopa nauhoilla) 240 Ulkoisen muistin käsittely Vältetään rekursio menemällä suoraan 1:n mittaisiin lajiteluihin jaksoihin ja lomitetaan niitä kunnes saadaan yksi n:n mittainen jakso. Käytetään kussakin vaiheessa kahta syötetiedostoa ja kahta tulostiedostoa (tai saman täysikokoisen hajasaantitiedoston kahta eri kohtaa). Kaksi syötetiedostoa jotta voisimme käyttää peräkkäistä käsittelyä. Kaksi tulostiedostoa, jotta seuraavassa vaiheessa olisi jotain lomitettavaa. Aluksi jaetaan syöte tasan kahteen tiedostoon (tätä vaihetta voidaan virittää, kts. alla). Vaiheessa k syöte on kahdessa tiedostossa f 1 ja f 2 siten, että 1) molemmat tiedostot sisältävät k:n tietueen lajiteltuja osajonoja, 2) osajonojen lukumäärä f 1 :ssä eroaa enintään yhdellä f 2 :n osajonojen lukumäärästä, 3) enintään yhdessä tiedostoista saa olla viimeisenä vajaa osajono ja 4) mahdollisen vajaan osajonon sisältävässä tiedostossa on osajonoja vähintään yhtä monta kuin osajonoja on toisessakin tiedostossa. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 240(279)

241 Ulkoisen muistin käsittely Toiminta edellisten edellytysten vallitessa Luetaan kummastakin tiedostosta k tietuetta ja lomitetaan nämä yhdeksi järjestyksessä olevaksi jonoksi ja viedään ensimmäiseen aputiedostoon. Seuraavat k+k tietuetta lomitetaan toiseen aputiedostoon. Puskurointi Levyhakujen minimoimiseksi kustakin tiedostosta luetaan kerralla niin monta k:n mittaista jaksoa kuin puskureihin mahtuu. Lopussa k:n mittainen jakso ei välttämättä mahdu kerralla muistiin, mutta tämä ei sinänsä haittaa mitään kun kyse on peräkkäisestä lomituksesta. Luetaan k:n sijaan niin paljon kuin puskureihin mahtuu, jatketaan myöhemmin. Riittää vain tietää, missä vaiheessa jakso loppuu jotta osaamme vaihtaa tiedostoja. 241 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 241(279)

242 Ulkoisen muistin käsittely Aikavaativuus k kaksinkertaistuu jokaisessa vaiheessa, siten lomitusta toistetaan logn vaihetta, kussakin O(n) työ, siis aikavaativuus O(nlogn). Hakujen ja siirräntöjen ajankäyttö HT. Optimointi Tiedostoa kahtia jaettaessa, voidaan lukea muistiin m tietuetta, lajitella ne sisäisesti, ja kirjoittaa aputiedostoon valmiiksi m:n mittainen lajiteltu jakso. Näin varsinaisesta levy-lajittelusta säästetään n. logm vaihetta. Jos esim. n = , m = , niin logn = 20, logm = 13, eli 60% säästö siirrännässä. 242 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 242(279)

243 5.4 Tiedosto kokoelmana (*) 243 Ulkoisen muistin käsittely Tavallinen hajasaantitiedosto toimii jokseenkin kuten taulukko. 1) F.add() lisää tietueen tiedostoon (loppuun). 2) F.remove() poistaa tiedostosta tietueen. 3) F.update(i) muuttaa tiedoston tietueen i sisältöä. Tietueen avainta ei saa muuttaa. 4) F.get(i) hakee tiedostosta tietueen i. lisäys (ja poisto) vain loppuun (on järkevää) tietueita voidaan merkitä poistetuiksi vaikka fyysistä poistoa ei tehtäisikään heti haku järjestysnumeron (indeksin) perusteella tai (peräkkäin) selaamalla Peräkkäis- (sarja-) tiedosto kuten yksisuuntainen lista. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 243(279)

244 java.io.randomaccessfile 244 Ulkoisen muistin käsittely Hajasaantitiedosto jota indeksoidaan tavuittain. Tietueittain käsittely: jaetaan tavuindeksit tietueen koolla. Laskutoimitukset ovat ohjelmoijan vastuulla! Laskuvirhe johtaa yleensä tiedo(sto)n korruptoimumiseen. 1) RandomAccessFile RAF = new RandomAccessFile(tiedosto, tapa) avaa uuden hajasaantitiedoston käsittelijän, tiedosto on tiedoston nimi (String) tai aiemmin luotu File-ilmentymä. tapa on "r": vain luku, "rw" : lukukirjoitus, "rws" / "rwd" : varmista kirjoitus levylle. 2) void RAF.seek(long paikka) siirrä luku/kirjoituskohta tavun paikka edelle. 3) int RAF.skipBytes(int n) siirrä luku/kirjoituskohtaa n tavua eteenpäin. 4) long RAF.getFilePointer() palauttaa tämänhetkisen luku/kirjoituskohdan. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 244(279)

245 Ulkoisen muistin käsittely 5) byte RAF.read(), int RAF.read(byte[] b), int RAF.read(byte[] b, int off, int len), XXX RAF.readXXX() Lukee tavun/b.length/len tavua / yhden XXX (perustyyppejä):n. 6) RAF.write(b), RAF.write(byte[] b), RAF.write(byte[] b, int off, int len), RAF.writeXXX(XXX) Kirjoittaa tavun/b.length/len tavua / yhden XXX:n. 7) long RAF.length() Palauttaa tiedoston pituuden. 8) void RAF.close() sulkee tiedoston. 245 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 245(279)

246 Tiedostojen organisointitapoja 246 Ulkoisen muistin käsittely Sarjatiedosto Tietueet sekaisin, soveltuu vain peräkkäiskäsittelyyn. Lisääminen loppuun helppoa. Peräkkäistiedosto Tietueet lajiteltuna avaimen mukaan. Binäärihaku onnistuu logn levyhaulla (logn/m, missä m on tietuetta/ levyjakso). Lisääminen raskasta. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 246(279)

247 Ulkoisen muistin käsittely Hajautus (TRAI) Jos avain on (suunnilleen) järjestysnumero, voidaan hakea suoraan (avain harvoin on tälläinen). Jos avain ei ole sopivasti kokonaislukumuotoinen, käytetään hajautusta. Lasketaan avaimesta sopiva kokonaisluku, käsitellään törmäykset. Voidaan hakea suoraan tiedostosta. Tällöin tosin menetetään tehokas peräkkäiskäsittely järjestyksessä. 247 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 247(279)

248 Ulkoisen muistin käsittely Osoitteellinen (hakemistollinen) peräkkäistiedosto Talletetaan varsinaiset tiedot avaimen mukaan lajiteltuna tiedostoon. Lisäksi luodaan hakemisto, jossa on kunkin levyjakson osoite ja ensimmäisen tietueen avain. Pyritään säilyttämään hakemisto keskusmuistissa. Jos levyjaksoja olisi liikaa (hakemisto suuri), voidaan käyttää pidempiä "loogisia" jaksoja. Hakemistossa on vain joka 100:n (tai 1000:n) levylohkon ensimmäinen avain. Levyltä/lle siirrettävä tieto lisääntyy (kaikki 100 haettava/kirjoitettava), mutta tärkeintähän oli minimoida lukupään haut. Näin oikea levyjakso voidaan paikallistaa hakemistosta (binäärihaulla keskusmuistissa) ja hakea kerralla levyltä. Levyjaksoihin kannattaa jättää hieman tilaa lisäyksiä varten (jos niitä on odotettavissa). Jos levyjakso täyttyy, on se jaettava kahtia (kts. B-puu sivulla 250). Todella suuriin tiedostoihin voidaan tehdä 2-tasoinen indeksi, mutta nykyisillä keskusmuisteilla se on yleensä tarpeetonta. 248 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 248(279)

249 Ulkoisen muistin käsittely Käänteishakemistot Jos hakuja tarvitaan muiden avainten kuin varsinaisen avaimen perusteella, luodaan näitä varten omat hakemistonsa. Käänteishakemiston tietueessa toissijainen avain ja joko varsinainen avain tai varsinainen osoite. Käänteishakemisto lajiteltuna toissijaisen avaimen mukaan jotta (binääri)haku olisi nopeaa. Peräkkäiskäsittely toissijaisen avaimen mukaisessa järjestyksessä edelleen hidasta. Huomaa Koska tiedosto on kuten taulukko, kaikkia näitä talletustapoja voidaan käyttää myös keskusmuistissa taulukoiden avulla. Palataan tähän joukon toteutuksen yhteydessä. 249 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 249(279)

250 5.5 B-puu 250 Ulkoisen muistin käsittely Massamuistissa minimoidaan hakuja ja vältetään lisäykset suuren tiedoston keskelle. Järjestetyn joukon totetus? Hajautus ei säilytä järjestystä. Järjestetyyn peräkkäistiedostoon on hidas lisätä (ja haku liki logaritminen). AVL/Punamusta/2-3-4/jne -puun korkeus on logaritminen. AVL/Punamustan -puun kierto-operaatiot eivät sovellu helposti massamuistiin. Yhden haun kustannuksella massamuistista saadaan oleellisesti samalla vaivalla esim. 100kt tietoa. Pyritään hyödyntämään tätä ja vähentämään haut 2-3:een (jopa vähemmäksi). Madalletaan puuta! Siis levennetään, eli haarautetaan enemmän kuin kahteen. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 250(279)

251 m v 251 Ulkoisen muistin käsittely a b d e c f j g h i k Määritelmä 5-5: B-puun solmulla s on x s avainta ja x s +1 lasta siten, että avaimet jakavat ko. solmun avainalueen osiin. Alkiot järjestetään sisäjärjestykseen, kutakin alkiota pienemmät alkiot löytyvät vasemmalta, suuremmat oikealta. Kunkin solmun vasemmanpuoleisimman lapsen (ja jälkeläisten) avaimet ovat ensimmäistä avainta pienemmät. Toisen lapsen avaimet ovat suurempia kuin ensimmäinen avain, mutta pienempiä kuin toinen avain, jne. Viimeisen lapsen avaimet ovat suurempia kuin viimeinen avain. B-puun kaikki lehtisolmut ovat samalla syvyydellä. l n o Kullakin haarautumissolmulla on t..2t lasta, eli t 1..2t 1 avainta ja lehtisolmulla on t 1..2t 1 avainta. Juurisolmulla voi olla vähemmän lapsia. q p r s t u x y z ö å ä 1 2 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 251(279)

252 Ulkoisen muistin käsittely B-puun muodostaminen Luokitellaan solmut lehtisolmuiksi ja haarautumissolmuiksi. B-puu on aluksi vain juurisolmu joka on alussa myös lehtisolmu. Kun juurisolmuun kertyy liikaa (2t 1) avaimia, muodostetaan keskimmäisestä alkiosta uusi juurisolmu ja sille kaksi lasta. Samoin toimitaan myöhemminkin kun juurella on jo lapsia ja avaimia kertyy juurisolmuun liikaa. c f j m p t z T 1 T 2 T 3 T 4 T 5 T 6 T 7 T 8 T 1 T 2 T 3 T 4 T 5 T 6 T 7 T 8 Tämä on ainoa tilanne jossa puun korkeus kasvaa. Samoin tämä on ainoa tilanne jossa solmulla (aina juuri) on vähemmän kuin t avainta. c f j m p t z 252 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 252(279)

253 Ulkoisen muistin käsittely Lisäys tehdään aina lehtisolmuun kuten binääripuussakin, mutta uuden solmun perustamisen sijaan uusi avain lisätään olemassaolevaan lehtisolmuun oikealle kohdalle. bnz g bnz bnz T c f j T T c f g j T T T c f g j k TT Kun lehtisolmu (tai muu solmu kuin juurisolmu) kasvaa liian suureksi, se jaetaan kahtia, jolloin sen vanhemmalle tulee yksi lapsi lisää, ja samalla yksi avain lisää. Tuoksi vanhemman uudeksi avaimeksi tulee jaettavan solmun keskimmäinen (mediaani). m bnz T c f g j k l m T T T c f g k l m T T Poistossa vastaavasti solmuja yhdistellään jos ne käyvät liian pieneksi, ja lopulta juuri ja sen kaksi vajaata lasta voidaan yhdistää. Jos poistoja on hyvin vähän, käytännössä riittää yksinkertainenkin poistoalgoritmi eikä vajaista solmuista tarvitse välittää. k b j n z 253 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 253(279)

254 Ulkoisen muistin käsittely B-puun toteutus massamuistissa t vähintään 1000, jopa >10000, riippuen avaimen/tietueen koosta, keskusmuistin määrästä ja massamuistin ominaisuuksista. Juurisolmun kopiota pidetään keskusmuistissa, mutta se toki kirjoitetaan massamuistiin aina kun se muuttuu. Solmua käsiteltäessä se luetaan muistiin kokonaisuudessaan, solmua muutettaessa (lisäavain, jako kahtia) vastaavasti kirjoitetaan kokonaisuudessaan). Keskusmuistissa solmun sisällä binäärihaku. Jos t = 1000, tieto löytyy kahdella levyhaulla kannasta jossa on vähintään miljardi (10 9 ) avainta (jopa ). Jos t = 10000, tieto löytyy kahdella levyhaulla kannasta jossa on vähintään biljoona (10 12 ) avainta, yhdellä haullakin jo sata miljoonaa (10 8 ). B-puun variaatioita puu: B-puu t:n arvolla 2. B+ puu: kaikki alkiot lehtisolmuissa, lehtisolmut linkitetty listaksi. Hieman nopeampi/helpompi läpikäynti, vaikeampi lisäys. 254 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 254(279)

255 Abstraktien tietotyyppien toteuttaminen (kertausta ja pari täydennystä Luku 6 Abstraktien tietotyyppien toteuttaminen (kertausta ja pari täydennystä TRAI:een) (*) Jotta abstraktia tietotyyppiä voitaisiin todella käyttää, on se toteutettava. Valmis toteutus on kierrätyksen (reuse) nimissä ensisijainen, mutta joskus sopivaa ei ole valmiina. Sopiva (käyttökelpoinen, riittävän tehokas): tarvitsemamme operaatiot riittävän tehokkaina alkiotyyppi sovitettavissa tarpeisiimme sopivalla ohjelmointikielellä toteutettuna tällä kurssilla Java 255 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 255(279)

256 Vaikka itse toteutammekin operaatiot, pidetään silti liittymä ja toteutus erillään, niin pääsemme joskus kierrättämään sitä samaa toteutusta. 256 Abstraktien tietotyyppien toteuttaminen (kertausta ja pari täydennystä Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 256(279) Lisäksi niin algoritmistamme kuin ADT:n toteutuksesta tulee selkeämpi eli helpommin luettava, tarkastettava, ylläpidettävä ja siirrettävä.

257 Abstraktien tietotyyppien toteuttaminen (kertausta ja pari täydennystä 6.1 Kotelointi ja parametrointi Toteutetaan annetun/tarvitsemamme abstraktin tietotyypin mukainen kokoelma. Liittymä määrää toteutuksen (ei päinvastoin). Joskin toteutusta suunniteltaessa voimme ohjata/tarkentaa liittymässä ilmoitettuja asioita (mikäli tarpeen toteutuksen tehokkuuden kannalta). Liittymän dokumentointiin tulee joitakin asioita vasta toteutuksesta riippuen. Todellisen toteutustavan voimme valita vapaasti (ideaalitapauksessa). Käytännössä usein toteutustapa vaikuttaa ainakin konkreettisten kokoelmien liittymäänkin, esim. listan aseman käytös. Esim. pinon ja joukon toteutustapa sensijaan vaikuttaa korkeintaan aikavaativuuksiin. 257 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 257(279)

258 Abstraktien tietotyyppien toteuttaminen (kertausta ja pari täydennystä Kotelointi Käyttäjälle annetaan vain liittymä, ei toteutusta. Käyttäjällä ei pitäisi olla keinoa käyttää toteutusriippuvaisia ominaisuuksia (ts. muuten kuin liittymän kautta). Liittymä tyypit rajoitukset operaatiot parametrit, palautusarvot rajoitukset aikavaativuudet dokumentaatio 258 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 258(279)

259 259 Abstraktien tietotyyppien toteuttaminen (kertausta ja pari täydennystä Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 259(279) Toteutus piilossa käyttäjältä sisäiset tyypit operaatioiden toteutukset (aliohjelmien rungot) Toteutuksen on oltava täsmälleen liittymän (ja sen dokumentoinnin) mukainen. Eri ohjelmointikielet tukevat kotelointia eri lailla.

260 Abstraktien tietotyyppien toteuttaminen (kertausta ja pari täydennystä Java Tarvittaessa voidaan liittymä (interface) ja sen toteuttava luokka esitellä erikseen, kts. esim java.util.set. Yksinkertaisemmin, kirjoitetaan liittymä ja toteutus suoraan samaan tiedostoon. Liittymää itseasiassa ei kirjoiteta erikseen lainkaan. Generoidaan liittymän kuvaus javadoc:lla. Käyttäjä ei tarvitse/saa liittymän lähdekoodia, vaan kaikki riittävä informaatio kokoelman käyttämiseen löytyy generoidusta dokumentaatiosta. Hyvää: helppo tehdä (kunhan muistaa javadoc:n kommentointivaatimukset) voidaan valita mitkä osat dokumentoidaan, tarvittaessa editoida jälkikäteen tukee luokkahierarkioita (erityisesti perityt menetelmät) Epävarmaa: Dokumentaation päivitys muistettava (mutta se on helpompi muistaa kun dokumentaatio on samassa tiedostossa). 260 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 260(279)

261 Parametrointi 261 Abstraktien tietotyyppien toteuttaminen (kertausta ja pari täydennystä Haluamme kerran toteutetun listan toimivan erilaisille elementtityypeille sujuvasti. Mieluiten vieläpä perustamatta erillistä toteutusta. Reunaehtoja: Elementtityypin vertailut, luonnit, tulostukset, muut käsittelyt, kopioinnit ja vapautukset pitää olla toteutettuna elementtityypin esittelyssä. Jos elementtityyppi on iso (rakenteinen), niin varsinainen elementti on osoitin/viite rakenteeseen. Tällöin luonnissa ja erityisesti tilan vapautuksessa tulee olla huolellinen. ADT:n tyypit ja operaatiot on syytä nimetä siten, ettei tule konflikteja käytettäessä eri ADT:tä samassa ohjelmassa (sikäli kun kieli sellaisesta välittää). Esittelyt ja toteutus koteloitava. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 261(279)

262 Abstraktien tietotyyppien toteuttaminen (kertausta ja pari täydennystä (Javan) geneeriset kokoelmat Sukua tekstuaaliselle parametroinnille, mutta hieman lisää tukea kääntäjältä ja erityisesti (linkkeriltä (jota Javassa tekee JVM)). Geneerinen kokoelma parametroidaan yhdellä tai useammalla tyypillä. Kokoelma<Alkiotyyppi> (6-1) Kokoelma<Alkiotyyppi1, Alkiotyyppi2> Esimerkiksi kuvauksessa annetaan avaimen tyyppi ja kuvan tyyppi. Alkiotyypin on oltava luokka, yksinkertaista tyyppiä ei voi käyttää. Kokoelmaa esiteltäessä ja toteutettaessa käytetään muodollista tyyppiparametria, (mikä tahansa merkkijono, mutta käytetään "E":tä). public class BTreeNode<E> { (6-2) private E element;... public E setelement(e element) { Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 262(279)

263 Abstraktien tietotyyppien toteuttaminen (kertausta ja pari täydennystä E on siis alkiotyyppi (luokka) koko luokan esittelevässä lohkossa (muttei tietenkään sen ulkopuolella). Jos alkiotyyppiä halutaan jotenkin rajoittaa (yleensä tarvittaessa jotain ominaisuuksia), voidaan käyttää esittelyä <E extends HaluttuYläluokka> tai <E super HaluttuAliluokka>, esim: public class LajittuvaLista<E extends Comparable> { (6-3) Näin kokoelman alkioilta voidaan olettaa (ilman pakotettua tyypinmuunnosta) compareto -metodin toteuttaminen. Kokoelmaa käyttöönotettaessa annetaan todellinen tyyppiparametri. Esim. Kokoelma<Alkio> oma = new Kokoelma<Alkio>(); (6-4) LinkedList<String> mjonolista = new LinkedList<String>(); (6-5) LinkedList<Set<Integer>> lukujoukkojenlista = new LinkedList<Set<Integer>>() 263 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 263(279)

264 Jos kokoelmalla on (toteutuksessa) komponentteina muita luokkia, molemmille määritellään erikseen (samat) alkiotyypit. 264 Abstraktien tietotyyppien toteuttaminen (kertausta ja pari täydennystä Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 264(279) List<Integer> lista; (6-6)... ListNode<Integer> p = lista.getfirst(); Integer x = p.getelement();

265 Abstraktien tietotyyppien toteuttaminen (kertausta ja pari täydennystä Javan kokoelmajärjestelmä (Collection framework) Sisältää liittymiä, runkototeutuksia ja varsinaisia toteutuksia, kaikki geneerisinä. Liittymä määrittelee mitä jonkin kokoelman on osattava (toteutettava). Esim. Collection, Set, Map, List. Runkototeutus sisältää mahdollisuuksien mukaan pääosan monimutkaisemmasta toiminnallisuudesta (yksinkertaisina, geneerisinä versioina). Esim. AbstractCollection, AbstractList Perustoiminnallisuus (esim. lisäys, poisto, läpikäynnit) on toki näihin vielä rakennettava itse. Varsinaiset toteutukset ovat valmiita paketteja. Näitä voi olla useita samaan liittymään. Esim. TreeSet, HashSet, LinkedList, ArrayList Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 265(279)

266 Abstraktien tietotyyppien toteuttaminen (kertausta ja pari täydennystä Iteraattorit Jotta luokka (yleensä kokoelma) toteuttaa Iterable -liittymän, sillä on oltava menetelmä Iterator<E> iterator() (6-7) joka palauttaa Iterator -liittymän toteuttavaa luokkaa olevan objektin jolla kokoelma voidaan käydä läpi. Iterator -liittymä edellyttää operaatiot hasnext() ja next() (ja remove(), jonka tosin ei tarvitse toimia). Iterator -liittymän toteuttava luokka on näppärintä sijoittaa kokoelman sisäluokaksi, joten sitä ei voi muualta suoraan kutsua. Kts. JLaukku.java, Permutation.java LongHashFile.java. 266 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 266(279)

267 267 Abstraktien tietotyyppien toteuttaminen (kertausta ja pari täydennystä Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 267(279) Muuttuvaprioriteettinen prioriteettijono Dijkstran algoritmissa joudutaan parantamaan jo prioriteettijonossa olevien solmujen prioriteettia. Kts. AdjustablePriorityQueue.java, Dijkstra.java

268 6.2 Verkot 268 Abstraktien tietotyyppien toteuttaminen (kertausta ja pari täydennystä Muodollisesti verkko koostuu solmujen ja kaarten joukoista, joten toteutuskin voisi käyttää joukko-operaatioita. Käytännössä kuitenkin hakemista tai vahvoja joukko-operaatioita (yhdiste jne) ei juuri tarvita verkkoja käsiteltäessä. Niinpä yksinkertaisempikin toteustapa riittää. Operaatioita tulee runsaasti, joskin niissä on runsaasti yhteisiä osia: Lisäys, poisto, väritys, jne erikseen solmuille ja kaarille. Läpikäynnit erilaisille ryhmille. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 268(279)

269 Abstraktien tietotyyppien toteuttaminen (kertausta ja pari täydennystä Kuten listoilla ja puillakin, totetustavan valinta riippuu kokoelman käyttötavasta: Tunnetaanko maksimikoko? Tehdäänkö solmujen lisäyksiä ja poistoja? Minkälaisia läpikäyntejä tarvitaan? Tarvitaanko lisäinformaatiota solmuista/kaarista? Tarvitaanko suoraa pääsyä halutun solmuparin kaareen? Onko verkko tiheä vai harva? Suunnattu vai suuntaamaton verkko? Esitellään kaksi toteutustapaa. 269 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 269(279)

270 Abstraktien tietotyyppien toteuttaminen (kertausta ja pari täydennystä Vierusmatriisi Jos: Maksimikoko tunnetaan. Solmuja ei poisteta. Kaaria lisätään, kaaria paljon, mutta ei rinnakkaisia kaaria samaan suuntaan. Tarvitaan suora pääsy solmuihin ja kaariin. Naapurien läpikäynnin ei tarvitse olla nopeaa. Solmuja ei ole paljoa. Vierusmatriisi. Vierusmatriisi on n n-matriisi G, jonka alkio G(i, j) kuvaa kaarta (i, j). Matriisin alkion tyyppi on joko paino tai totuusarvo. Jos kaarilla useampi kuin yksi tieto : erillinen matriisi (tai rakenteinen alkio). Jos solmuilla nimiöt tms muuta tietoa: erillinen [1..n] taulukko (tai rakenteinen alkio). 270 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 270(279)

271 Abstraktien tietotyyppien toteuttaminen (kertausta ja pari täydennystä Solmun ja kaaren lisääminen helppoa. Paitsi jos matriisi täyttyy, tai tarvitaan useampikertainen kaari tai halutaan tallettaa solmut jossain tietyssä järjestyksessä. Kaaren poisto on helppoa. Solmun poisto vaatii siirtelyä ja kaarten läpikäyntiä, Ω(n). Tai monimutkaisen linkityksen. Solmujen läpikäynti yhteensä O(n). Kaarten läpikäynti yhteensä Θ(n 2 ). Naapurien läpikäynti yhteensä Θ(n). Jos naapurien tai kaarten läpikäynti tehokkaasti on tärkeää niin tehdään lisäksi erillinen naapuritalletusrakenne (lista). Suuntaamattomalla verkolla ylä-/alakolmiomatriisi riittää. 271 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 271(279)

272 Abstraktien tietotyyppien toteuttaminen (kertausta ja pari täydennystä Vieruslista (vierusjoukot) Jos Solmuja (ja kaaria) lisätään ja poistetaan. Solmuja on paljon tai niiden määrää ei tiedetä etukäteen. Tarvitaan useampikertaisia kaaria. Tarvitaan tehokasta naapureiden läpikäyntiä. Vieruslistat. Säilytetään solmut kokoelmana ja kustakin solmusta lähtevät kaaret omana kokoelmanaan (kokoelma joukko). 272 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 272(279)

273 Abstraktien tietotyyppien toteuttaminen (kertausta ja pari täydennystä Toteutus yksinkertaisimmillaan: Solmujen lista. Kullakin solmulla lähtevien kaarten lista. Kaaressa on viittaus maalisolmuun. Solmun ja kaaren tietueeseen kaikki tarvittava tieto. Käyttäjälle solmu ja kaari ovat viittauksia. Verkko on viittaus ensimmäiseen (ja viimeiseen) solmuun. Viritysmahdollisuuksia: Erillinen tunnussolmu verkolle. Solmut taulukkoon. Solmut valmiiksi numeroitu. Poisto vaikeutuu. Naapurit (ja/tai solmut) hakupuuhun. Nopeahko pääsy haluttuun solmuun/kaareen (esim. isadjacent()). 273 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 273(279)

274 274 Abstraktien tietotyyppien toteuttaminen (kertausta ja pari täydennystä Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 274(279) Solmut Kaaret A B C D A B Kuva 6-1: Suunnatun verkon vieruslistatoteutus. Solmujen kuvaajien kokoelma voidaan toteuttaa joko listana tai taulukkona D C

275 Suuntaamaton verkko 275 Abstraktien tietotyyppien toteuttaminen (kertausta ja pari täydennystä Duplikaatteja ei sallita. Kaarta voitava käyttää molempiin suuntiin "automaattisesti". Kun kaari esim. lisätään tai väritetään yhteen suuntaan, myös toinen suunta tulee lisättyä/väritettyä. Vaihtoehdot: Tallennetaan kaikki kaaret molempiin suuntiin. Helppo läpikäydä naapurit, helppo tutkia olemassaolo. Vaikuttaa kaikkien kaarten läpikäyntiin. Vaikuttaa kaaren poistamiseen. Linkki kaaren esiintymien välille helpottaa parin löytämistä. Tallennetaan vain 1. solmusta 2. solmuun. Vaatii yksikäsitteisen ja helpon solmujen järjestyksen. Vaikeuttaa läpikäyntiä (erit. naapurien läpikäynti). Tallennetaan vain jompaan kumpaan suuntaan. Tutkittaessa kaaren olemassaoloa tutkittava molemmat solmut. Vaikeuttaa naapurien läpikäyntiä huomattavasti. Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 275(279)

276 276 Abstraktien tietotyyppien toteuttaminen (kertausta ja pari täydennystä Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 276(279) Solmut Kaaret A B C A B Kuva 6-2: Suuntaamattoman verkon vieruslistatoteutus. Kukin kaari on esitetty molempiin suuntiin, kaarten kuvaajat kytketty toisiinsa.... C

277 [1] Aho A. V., Hopcroft J. E., Ullman J.D.: Data Structures and Algorithms. Addison- Wesley, [2] Apostolico A., Galil Z. (eds.): Pattern Matching Algorithms. Oxford University Press, [3] Cormen T. H., Leiserson C. E., Rivest R. L.: Introduction to Algorithms. MIT Press [4] Hämäläinen A.: Tietorakennekirjasto Javalla. Joensuun Yliopisto, Tietojenkäsittelytieteen laitos, [5] Katainen T., Meriläinen M., Juvaste S.: Tietorakennekirjasto Pascalilla ja C:llä. Joensuun Yliopisto, Tietojenkäsittelytieteen laitos, [6] Knuth D. E.: The Art of Computer Programming, Volumes 1-3, (2-3ed). Addison- Wesley, Abstraktien tietotyyppien toteuttaminen (kertausta ja pari täydennystäkirjallisuutta 277 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 277(279)

278 [7] Weiss M. A.: Data Structures and Algorithm Analysis in C. Addison-Wesley, Abstraktien tietotyyppien toteuttaminen (kertausta ja pari täydennystä Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 278(279) [8] Weiss M. A.: Data Structures and Algorithm Analysis in Java. Addison-Wesley, 1999.

279 Abstraktien tietotyyppien toteuttaminen (kertausta ja pari täydennystä Olemassaolevia tietorakenne/algoritmikirjastoja C luokkaa Kaupallistettu Eiffel, Oberon, Modula-3 -kirjastot tkt-laitoksella. Numerical Recipes in [Fortran [77 90] C Pascal ( Basic Lisp Modula-2 IDL Mathcad ] Animointeja: Jeliot, Polka, XTango, jne. TR&A oppi/käsikirjat, erityisesti Cormen, Leiserson, Rivest. 279 Tietorakenteet ja algoritmit II :47 UEF/tkt Simo Juvaste 279(279)

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

Tietorakenteet ja algoritmit II

Tietorakenteet ja algoritmit II Tietorakenteet ja algoritmit II Luentomuistiinpanoja Simo Juvaste Asko Niemeläinen Itä-Suomen yliopisto Tietojenkäsittelytiede Alkusanat Tämä uuden TRAII kurssin luentomateriaali on kutakuinkin edellisen

Lisätiedot

Algoritmit 2. Luento 14 Ke Timo Männikkö

Algoritmit 2. Luento 14 Ke Timo Männikkö Algoritmit 2 Luento 14 Ke 3.5.2017 Timo Männikkö Luento 14 Ositus ja rekursio Rekursion toteutus Kertaus ja tenttivinkit Algoritmit 2 Kevät 2017 Luento 14 Ke 3.5.2017 2/30 Ositus Tehtävän esiintymä ositetaan

Lisätiedot

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

f(n) = Ω(g(n)) jos ja vain jos g(n) = O(f(n)) Määritelmä: on O(g(n)), jos on olemassa vakioarvot n 0 > 0 ja c > 0 siten, että c g(n) kun n > n 0 O eli iso-o tai ordo ilmaisee asymptoottisen ylärajan resurssivaatimusten kasvun suuruusluokalle Samankaltaisia

Lisätiedot

Algoritmit 1. Luento 3 Ti Timo Männikkö

Algoritmit 1. Luento 3 Ti Timo Männikkö Algoritmit 1 Luento 3 Ti 17.1.2017 Timo Männikkö Luento 3 Algoritmin analysointi Rekursio Lomituslajittelu Aikavaativuus Tietorakenteet Pino Algoritmit 1 Kevät 2017 Luento 3 Ti 17.1.2017 2/27 Algoritmien

Lisätiedot

Algoritmit 1. Luento 12 Ti Timo Männikkö

Algoritmit 1. Luento 12 Ti Timo Männikkö Algoritmit 1 Luento 12 Ti 19.2.2019 Timo Männikkö Luento 12 Osittamisen tasapainoisuus Pikalajittelun vaativuus Lajittelumenetelmien vaativuus Laskentalajittelu Lokerolajittelu Kantalukulajittelu Algoritmit

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

Tietorakenteet ja algoritmit Johdanto Lauri Malmi / Ari Korhonen

Tietorakenteet ja algoritmit Johdanto Lauri Malmi / Ari Korhonen Tietorakenteet ja algoritmit Johdanto Lauri Malmi / Ari 1 1. JOHDANTO 1.1 Määritelmiä 1.2 Tietorakenteen ja algoritmin valinta 1.3 Algoritmit ja tiedon määrä 1.4 Tietorakenteet ja toiminnot 1.5 Esimerkki:

Lisätiedot

Algoritmit 2. Luento 1 Ti Timo Männikkö

Algoritmit 2. Luento 1 Ti Timo Männikkö Algoritmit 2 Luento 1 Ti 14.3.2017 Timo Männikkö Luento 1 Algoritmi Algoritmin valinta Algoritmin analysointi Algoritmin suoritusaika Peruskertaluokkia Kertaluokkamerkinnät Kertaluokkien ominaisuuksia

Lisätiedot

Tietorakenteet ja algoritmit - syksy 2015 1

Tietorakenteet ja algoritmit - syksy 2015 1 Tietorakenteet ja algoritmit - syksy 2015 1 Tietorakenteet ja algoritmit - syksy 2015 2 Tietorakenteet ja algoritmit Johdanto Ari Korhonen Tietorakenteet ja algoritmit - syksy 2015 1. JOHDANTO 1.1 Määritelmiä

Lisätiedot

Algoritmit 2. Luento 7 Ti Timo Männikkö

Algoritmit 2. Luento 7 Ti Timo Männikkö Algoritmit 2 Luento 7 Ti 4.4.2017 Timo Männikkö Luento 7 Joukot Joukko-operaatioita Joukkojen esitystapoja Alkiovieraat osajoukot Toteutus puurakenteena Algoritmit 2 Kevät 2017 Luento 7 Ti 4.4.2017 2/26

Lisätiedot

4 Tehokkuus ja algoritmien suunnittelu

4 Tehokkuus ja algoritmien suunnittelu TIE-20100 Tietorakenteet ja algoritmit 52 4 Tehokkuus ja algoritmien suunnittelu Tässä luvussa pohditaan tehokkuuden käsitettä ja esitellään kurssilla käytetty kertaluokkanotaatio, jolla kuvataan algoritmin

Lisätiedot

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

58131 Tietorakenteet ja algoritmit (kevät 2014) Uusinta- ja erilliskoe, , vastauksia 58131 Tietorakenteet ja algoritmit (kevät 2014) Uusinta- ja erilliskoe, 10..2014, vastauksia 1. [9 pistettä] (a) Todistetaan 2n 2 + n + 5 = O(n 2 ): Kun n 1 on 2n 2 + n + 5 2n 2 + n 2 +5n 2 = 8n 2. Eli

Lisätiedot

A274101 TIETORAKENTEET JA ALGORITMIT

A274101 TIETORAKENTEET JA ALGORITMIT A274101 TIETORAKENTEET JA ALGORITMIT ALGORITMIEN ANALYYSISTÄ 1.ratkaisu Laskentaaika hakkeri - optimoitu ALGORITMIANALYYSIÄ hyvä algoritmi hakkeri -optimoitu hyvä algoritmi Tehtävän koko Kuva mukailtu

Lisätiedot

A274101 TIETORAKENTEET JA ALGORITMIT

A274101 TIETORAKENTEET JA ALGORITMIT A274101 TIETORAKENTEET JA ALGORITMIT PERUSTIETORAKENTEET LISTA, PINO, JONO, PAKKA ABSTRAKTI TIETOTYYPPI Tietotyyppi on abstrakti, kun se on määritelty (esim. matemaattisesti) ottamatta kantaa varsinaiseen

Lisätiedot

1.4 Funktioiden kertaluokat

1.4 Funktioiden kertaluokat 1.4 Funktioiden kertaluokat f on kertaluokkaa O(g), merk. f = O(g), jos joillain c > 0, m N pätee f(n) cg(n) aina kun n m f on samaa kertaluokkaa kuin g, merk. f = Θ(g), jos joillain a, b > 0, m N pätee

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

Algoritmit 2. Luento 8 To Timo Männikkö

Algoritmit 2. Luento 8 To Timo Männikkö Algoritmit 2 Luento 8 To 4.4.2019 Timo Männikkö Luento 8 Algoritmien analysointi Algoritmien suunnittelu Rekursio Osittaminen Rekursioyhtälöt Rekursioyhtälön ratkaiseminen Master-lause Algoritmit 2 Kevät

Lisätiedot

Algoritmit 1. Luento 12 Ke Timo Männikkö

Algoritmit 1. Luento 12 Ke Timo Männikkö Algoritmit 1 Luento 12 Ke 15.2.2017 Timo Männikkö Luento 12 Pikalajittelu Pikalajittelun vaativuus Osittamisen tasapainoisuus Lajittelumenetelmien vaativuus Laskentalajittelu Lokerolajittelu Kantalukulajittelu

Lisätiedot

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

58131 Tietorakenteet ja algoritmit (kevät 2016) Ensimmäinen välikoe, malliratkaisut 58131 Tietorakenteet ja algoritmit (kevät 2016) Ensimmäinen välikoe, malliratkaisut 1. Palautetaan vielä mieleen O-notaation määritelmä. Olkoon f ja g funktioita luonnollisilta luvuilta positiivisille

Lisätiedot

Tietorakenteet, laskuharjoitus 7, ratkaisuja

Tietorakenteet, laskuharjoitus 7, ratkaisuja Tietorakenteet, laskuharjoitus, ratkaisuja. Seuraava kuvasarja näyttää B + -puun muutokset lisäysten jälkeen. Avaimet ja 5 mahtuvat lehtisolmuihin, joten niiden lisäys ei muuta puun rakennetta. Avain 9

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 1. Luento 10 Ke Timo Männikkö

Algoritmit 1. Luento 10 Ke Timo Männikkö Algoritmit 1 Luento 10 Ke 14.2.2018 Timo Männikkö Luento 10 Algoritminen ongelmanratkaisu Suunnittelumenetelmät Raaka voima Järjestäminen eli lajittelu Kuplalajittelu Lisäyslajittelu Valintalajittelu Permutaatiot

Lisätiedot

Algoritmit 2. Luento 2 To Timo Männikkö

Algoritmit 2. Luento 2 To Timo Männikkö Algoritmit 2 Luento 2 To 14.3.2019 Timo Männikkö Luento 2 Tietorakenteet Lineaarinen lista, binääripuu Prioriteettijono Kekorakenne Keko-operaatiot Keon toteutus taulukolla Algoritmit 2 Kevät 2019 Luento

Lisätiedot

Algoritmit 2. Luento 2 Ke Timo Männikkö

Algoritmit 2. Luento 2 Ke Timo Männikkö Algoritmit 2 Luento 2 Ke 15.3.2017 Timo Männikkö Luento 2 Tietorakenteet Lineaarinen lista, binääripuu Prioriteettijono Kekorakenne Keko-operaatiot Keon toteutus taulukolla Algoritmit 2 Kevät 2017 Luento

Lisätiedot

Tieto- ja tallennusrakenteet

Tieto- ja tallennusrakenteet Tieto- ja tallennusrakenteet Sisältö Tyyppi, abstrakti tietotyyppi, abstraktin tietotyypin toteutus Tallennusrakenteet Taulukko Linkitetty rakenne Abstraktit tietotyypit Lista (Puu) (Viimeisellä viikolla)

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

Algoritmit 1. Luento 14 Ke 25.2.2015. Timo Männikkö

Algoritmit 1. Luento 14 Ke 25.2.2015. Timo Männikkö Algoritmit 1 Luento 14 Ke 25.2.2015 Timo Männikkö Luento 14 Heuristiset menetelmät Heuristiikkoja kapsäkkiongelmalle Kauppamatkustajan ongelma Lähimmän naapurin menetelmä Kertaus ja tenttivinkit Algoritmit

Lisätiedot

Algoritmit 1. Luento 11 Ti Timo Männikkö

Algoritmit 1. Luento 11 Ti Timo Männikkö Algoritmit 1 Luento 11 Ti 14.2.2017 Timo Männikkö Luento 11 Algoritminen ongelmanratkaisu Osittaminen Lomituslajittelu Lomituslajittelun vaativuus Rekursioyhtälöt Pikalajittelu Algoritmit 1 Kevät 2017

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

Sisällys. 18. Abstraktit tietotyypit. Johdanto. Johdanto

Sisällys. 18. Abstraktit tietotyypit. Johdanto. Johdanto Sisällys 18. bstraktit tietotyypit Johdanto abstrakteihin tietotyyppeihin. Pino ja jono. Linkitetty lista. Pino linkitetyllä listalla toteutettuna. 18.1 18.2 Johdanto Javan omat tietotyypit ovat jo tuttuja:

Lisätiedot

3. Laskennan vaativuusteoriaa

3. Laskennan vaativuusteoriaa 3. Laskennan vaativuusteoriaa tähän asti puhuttu siitä, mitä on mahdollista laskea äärellisessä ajassa siirrytään tarkastelemaan laskemista kohtuullisessa ajassa vaihtoehtoisesti voidaan laskenta-ajan

Lisätiedot

Nopea kertolasku, Karatsuban algoritmi

Nopea kertolasku, Karatsuban algoritmi Nopea kertolasku, Karatsuban algoritmi Mikko Männikkö 16.8.2004 Lähde: ((Gathen and Gerhard 1999) luku II.8) Esityksen kulku Algoritmien analysointia (1), (2), (3), (4) Klassinen kertolasku Parempi tapa

Lisätiedot

Algoritmianalyysin perusteet

Algoritmianalyysin perusteet Tietorakenteet ja algoritmit Algoritmianalyysin perusteet Ari Korhonen 1 5. ALGORITMIANALYYSI 5.1 Johdanto 5.2 Tavoitteet 5.3 Algoritmien luokittelu 5.4 Kertaluokkamerkinnät (Big Oh Notation) 5.5 Kertaluokkamerkinnöillä

Lisätiedot

Tietorakenteet, laskuharjoitus 2,

Tietorakenteet, laskuharjoitus 2, Tietorakenteet, laskuharjoitus, 6.-9.1 Muista TRAKLA-tehtävien deadline 31.1. 1. Tarkastellaan ensin tehtävää yleisellä tasolla. Jos funktion T vaativuusluokka on O(f), niin funktio T on muotoa T (n) =

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

811312A Tietorakenteet ja algoritmit, , Harjoitus 3, Ratkaisu

811312A Tietorakenteet ja algoritmit, , Harjoitus 3, Ratkaisu 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

Lisätiedot

Algoritmit 2. Luento 5 Ti Timo Männikkö

Algoritmit 2. Luento 5 Ti Timo Männikkö Algoritmit 2 Luento 5 Ti 26.3.2019 Timo Männikkö Luento 5 Puurakenteet B-puu B-puun korkeus B-puun operaatiot B-puun muunnelmia Algoritmit 2 Kevät 2019 Luento 5 Ti 26.3.2019 2/34 B-puu B-puut ovat tasapainoisia

Lisätiedot

Algoritmit 2. Luento 6 To Timo Männikkö

Algoritmit 2. Luento 6 To Timo Männikkö Algoritmit 2 Luento 6 To 28.3.2019 Timo Männikkö Luento 6 B-puun operaatiot Nelipuu Trie-rakenteet Standarditrie Pakattu trie Algoritmit 2 Kevät 2019 Luento 6 To 28.3.2019 2/30 B-puu 40 60 80 130 90 100

Lisätiedot

Tietorakenteet ja algoritmit. Kertaus. Ari Korhonen

Tietorakenteet ja algoritmit. Kertaus. Ari Korhonen 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

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

18. Abstraktit tietotyypit 18.1

18. Abstraktit tietotyypit 18.1 18. Abstraktit tietotyypit 18.1 Sisällys Johdanto abstrakteihin tietotyyppeihin. Pino ja jono. Linkitetty lista. Pino linkitetyllä listalla toteutettuna. 18.2 Johdanto Javan omat tietotyypit ovat jo tuttuja:

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 Kertausta kurssin alkuosasta

811312A Tietorakenteet ja algoritmit Kertausta kurssin alkuosasta 811312A Tietorakenteet ja algoritmit 2017-2018 Kertausta kurssin alkuosasta II Perustietorakenteet Pino, jono ja listat tunnettava Osattava soveltaa rakenteita algoritmeissa Osattava päätellä operaatioiden

Lisätiedot

Algoritmit 1. Demot Timo Männikkö

Algoritmit 1. Demot Timo Männikkö Algoritmit 1 Demot 1 25.-26.1.2017 Timo Männikkö Tehtävä 1 (a) Algoritmi, joka laskee kahden kokonaisluvun välisen jakojäännöksen käyttämättä lainkaan jakolaskuja Jaettava m, jakaja n Vähennetään luku

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

Algoritmit 2. Luento 6 Ke Timo Männikkö

Algoritmit 2. Luento 6 Ke Timo Männikkö Algoritmit 2 Luento 6 Ke 29.3.2017 Timo Männikkö Luento 6 B-puun operaatiot B-puun muunnelmia Nelipuu Trie-rakenteet Standarditrie Pakattu trie Algoritmit 2 Kevät 2017 Luento 6 Ke 29.3.2017 2/31 B-puu

Lisätiedot

Pinot, jonot, yleisemmin sekvenssit: kokoelma peräkkäisiä alkioita (lineaarinen järjestys) Yleisempi tilanne: alkioiden hierarkia

Pinot, jonot, yleisemmin sekvenssit: kokoelma peräkkäisiä alkioita (lineaarinen järjestys) Yleisempi tilanne: alkioiden hierarkia Pinot, jonot, yleisemmin sekvenssit: kokoelma peräkkäisiä alkioita (lineaarinen järjestys) Yleisempi tilanne: alkioiden hierarkia Kukin alkio (viite) talletettuna solmuun (node) vastaa paikan käsitettä

Lisätiedot

TKT20001 Tietorakenteet ja algoritmit Erilliskoe , malliratkaisut (Jyrki Kivinen)

TKT20001 Tietorakenteet ja algoritmit Erilliskoe , malliratkaisut (Jyrki Kivinen) TKT0001 Tietorakenteet ja algoritmit Erilliskoe 5.1.01, malliratkaisut (Jyrki Kivinen) 1. [1 pistettä] (a) Esitä algoritmi, joka poistaa kahteen suuntaan linkitetystä järjestämättömästä tunnussolmullisesta

Lisätiedot

Algoritmit 2. Luento 13 Ti Timo Männikkö

Algoritmit 2. Luento 13 Ti Timo Männikkö Algoritmit 2 Luento 13 Ti 8.5.2018 Timo Männikkö Luento 13 Laskennallinen vaativuus Päätösongelmat Epädeterministinen algoritmi Vaativuusluokat NP-täydellisyys Kertaus ja tenttivinkit Algoritmit 2 Kevät

Lisätiedot

Tutkimusmenetelmät-kurssi, s-2004

Tutkimusmenetelmät-kurssi, s-2004 Algoritmitutkimuksen menetelmistä Tutkimusmenetelmät-kurssi, s-2004 Pekka Kilpeläinen Kuopion yliopisto Tietojenkäsittelytieteen laitos Algoritmitutkimuksen menetelmistä p.1/20 Sisällys Tänään Tietojenkäsittelytiede

Lisätiedot

Diskreetin matematiikan perusteet Laskuharjoitus 2 / vko 9

Diskreetin matematiikan perusteet Laskuharjoitus 2 / vko 9 Diskreetin matematiikan perusteet Laskuharjoitus 2 / vko 9 Tuntitehtävät 9-10 lasketaan alkuviikon harjoituksissa ja tuntitehtävät 13-14 loppuviikon harjoituksissa. Kotitehtävät 11-12 tarkastetaan loppuviikon

Lisätiedot

Kääreluokat (oppikirjan luku 9.4) (Wrapper-classes)

Kääreluokat (oppikirjan luku 9.4) (Wrapper-classes) Kääreluokat (oppikirjan luku 9.4) (Wrapper-classes) Kääreluokista Javan alkeistietotyypit ja vastaavat kääreluokat Autoboxing Integer-luokka Double-luokka Kääreluokista Alkeistietotyyppiset muuttujat (esimerkiksi

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

58131 Tietorakenteet ja algoritmit Uusinta- ja erilliskoe ratkaisuja (Jyrki Kivinen)

58131 Tietorakenteet ja algoritmit Uusinta- ja erilliskoe ratkaisuja (Jyrki Kivinen) 58131 Tietorakenteet ja algoritmit Uusinta- ja erilliskoe 12.9.2018 ratkaisuja (Jyrki Kivinen) 1. [10 pistettä] Iso-O-merkintä. (a) Pitääkö paikkansa, että n 3 + 5 = O(n 3 )? Ratkaisu: Pitää paikkansa.

Lisätiedot

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

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 return

Lisätiedot

Algoritmit 1. Luento 10 Ke 11.2.2015. Timo Männikkö

Algoritmit 1. Luento 10 Ke 11.2.2015. Timo Männikkö Algoritmit 1 Luento 10 Ke 11.2.2015 Timo Männikkö Luento 10 Algoritminen ongelman ratkaisu Suunnittelumenetelmät Raaka voima Järjestäminen eli lajittelu Kuplalajittelu Väliinsijoituslajittelu Valintalajittelu

Lisätiedot

Sisältö. 2. Taulukot. Yleistä. Yleistä

Sisältö. 2. Taulukot. Yleistä. Yleistä Sisältö 2. Taulukot Yleistä. Esittely ja luominen. Alkioiden käsittely. Kaksiulotteinen taulukko. Taulukko operaation parametrina. Taulukko ja HelloWorld-ohjelma. Taulukko paluuarvona. 2.1 2.2 Yleistä

Lisätiedot

58131 Tietorakenteet Erilliskoe , ratkaisuja (Jyrki Kivinen)

58131 Tietorakenteet Erilliskoe , ratkaisuja (Jyrki Kivinen) 58131 Tietorakenteet Erilliskoe 11.11.2008, ratkaisuja (Jyrki Kivinen) 1. (a) Koska halutaan DELETEMAX mahdollisimman nopeaksi, käytetään järjestettyä linkitettyä listaa, jossa suurin alkio on listan kärjessä.

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

ITKP102 Ohjelmointi 1 (6 op)

ITKP102 Ohjelmointi 1 (6 op) ITKP102 Ohjelmointi 1 (6 op) Tentaattori: Antti-Jussi Lakanen 7. huhtikuuta 2017 Vastaa kaikkiin tehtäviin. Tee jokainen tehtävä erilliselle konseptiarkille. Kirjoittamasi luokat, funktiot ja aliohjelmat

Lisätiedot

13. Loogiset operaatiot 13.1

13. Loogiset operaatiot 13.1 13. Loogiset operaatiot 13.1 Sisällys Loogiset operaatiot AND, OR, XOR ja NOT. Operaatioiden ehdollisuus. Bittioperaatiot. Loogiset operaatiot ohjausrakenteissa. Loogiset operaatiot ja laskentajärjestys.

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

Algoritmit 1. Luento 5 Ti Timo Männikkö

Algoritmit 1. Luento 5 Ti Timo Männikkö Algoritmit 1 Luento 5 Ti 24.1.2017 Timo Männikkö Luento 5 Järjestetty lista Järjestetyn listan operaatiot Listan toteutus taulukolla Binäärihaku Binäärihaun vaativuus Algoritmit 1 Kevät 2017 Luento 5 Ti

Lisätiedot

ITKP102 Ohjelmointi 1 (6 op)

ITKP102 Ohjelmointi 1 (6 op) ITKP102 Ohjelmointi 1 (6 op) Tentaattori: Antti-Jussi Lakanen 12. huhtikuuta 2019 Tee kukin tehtävä omalle konseptiarkille. Noudata ohjelmointitehtävissä kurssin koodauskäytänteitä. Yksi A4-kokoinen lunttilappu

Lisätiedot

811312A Tietorakenteet ja algoritmit II Perustietorakenteet

811312A Tietorakenteet ja algoritmit II Perustietorakenteet 811312A Tietorakenteet ja algoritmit 2017-2018 II Perustietorakenteet Sisältö 1. Johdanto 2. Pino 3. Jono 4. Lista 811312A TRA, Perustietorakenteet 2 II.1. Johdanto Tietorakenne on tapa, jolla algoritmi

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

Algoritmit 2. Luento 5 Ti Timo Männikkö

Algoritmit 2. Luento 5 Ti Timo Männikkö Algoritmit 2 Luento 5 Ti 28.3.2017 Timo Männikkö Luento 5 Puurakenteet B-puu B-puun korkeus B-puun operaatiot Algoritmit 2 Kevät 2017 Luento 5 Ti 28.3.2017 2/29 B-puu Algoritmit 2 Kevät 2017 Luento 5 Ti

Lisätiedot

Tietorakenteet, laskuharjoitus 1,

Tietorakenteet, laskuharjoitus 1, Tietorakenteet, laskuharjoitus 1, 19.-22.1 Huom: laskarit alkavat jo ensimmäisellä luentoviikolla 1. Taustaa http://wiki.helsinki.fi/display/mathstatkurssit/matukurssisivu Halutaan todistaa, että oletuksesta

Lisätiedot

Algoritmit 2. Luento 13 Ti Timo Männikkö

Algoritmit 2. Luento 13 Ti Timo Männikkö Algoritmit 2 Luento 13 Ti 2.5.2017 Timo Männikkö Luento 13 Merkkijonon sovitus Horspoolin algoritmi Laskennallinen vaativuus Päätösongelmat Epädeterministinen algoritmi Vaativuusluokat NP-täydellisyys

Lisätiedot

Sisältö. 22. Taulukot. Yleistä. Yleistä

Sisältö. 22. Taulukot. Yleistä. Yleistä Sisältö 22. Taulukot Yleistä. Esittely ja luominen. Alkioiden käsittely. Kaksiulotteinen taulukko. Taulukko metodin parametrina. Taulukko ja HelloWorld-ohjelma. Taulukko paluuarvona. 22.1 22.2 Yleistä

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

Algoritmit 2. Luento 13 Ti Timo Männikkö

Algoritmit 2. Luento 13 Ti Timo Männikkö Algoritmit 2 Luento 13 Ti 30.4.2019 Timo Männikkö Luento 13 Simuloitu jäähdytys Merkkijonon sovitus Horspoolin algoritmi Ositus ja rekursio Rekursion toteutus Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019

Lisätiedot

Algoritmit 2. Luento 3 Ti Timo Männikkö

Algoritmit 2. Luento 3 Ti Timo Männikkö Algoritmit 2 Luento 3 Ti 21.3.2017 Timo Männikkö Luento 3 Järjestäminen eli lajittelu Kekorakenne Kekolajittelu Hajautus Yhteentörmäysten käsittely Ketjutus Algoritmit 2 Kevät 2017 Luento 3 Ti 21.3.2017

Lisätiedot

Imperatiivisen ohjelmoinnin peruskäsitteet. Meidän käyttämän pseudokielen lauseiden syntaksi

Imperatiivisen ohjelmoinnin peruskäsitteet. Meidän käyttämän pseudokielen lauseiden syntaksi Imperatiivisen ohjelmoinnin peruskäsitteet muuttuja muuttujissa oleva data voi olla yksinkertaista eli primitiivistä (esim. luvut ja merkit) tai rakenteista jolloin puhutaan tietorakenteista. puhuttaessa

Lisätiedot

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 13 Ti 23.2.2016. Timo Männikkö

Algoritmit 1. Luento 13 Ti 23.2.2016. Timo Männikkö Algoritmit 1 Luento 13 Ti 23.2.2016 Timo Männikkö Luento 13 Suunnittelumenetelmät Taulukointi Kapsäkkiongelma Ahne menetelmä Verkon lyhimmät polut Dijkstran menetelmä Verkon lyhin virittävä puu Kruskalin

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

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

Algoritmit 1. Demot Timo Männikkö

Algoritmit 1. Demot Timo Männikkö Algoritmit 1 Demot 1 31.1.-1.2.2018 Timo Männikkö Tehtävä 1 (a) Algoritmi, joka tutkii onko kokonaisluku tasan jaollinen jollain toisella kokonaisluvulla siten, että ei käytetä lainkaan jakolaskuja Jaettava

Lisätiedot

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

58131 Tietorakenteet ja algoritmit (syksy 2015) Toinen välikoe, malliratkaisut Tietorakenteet ja algoritmit (syksy 0) Toinen välikoe, malliratkaisut. (a) Alussa puu näyttää tältä: Lisätään 4: 4 Tasapaino rikkoutuu solmussa. Tehdään kaksoiskierto ensin oikealle solmusta ja sitten

Lisätiedot

Tietorakenteet (syksy 2013)

Tietorakenteet (syksy 2013) Tietorakenteet (syksy 2013) Harjoitus 1 (6.9.2013) Huom. Sinun on osallistuttava perjantain laskuharjoitustilaisuuteen ja tehtävä vähintään kaksi tehtävää, jotta voit jatkaa kurssilla. Näiden laskuharjoitusten

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

13. Loogiset operaatiot 13.1

13. Loogiset operaatiot 13.1 13. Loogiset operaatiot 13.1 Sisällys Loogiset operaatiot AND, OR, XOR ja NOT. Operaatioiden ehdollisuus. Bittioperaatiot. Loogiset operaatiot ohjausrakenteissa. Loogiset operaatiot ja laskentajärjestys.

Lisätiedot

ITKP102 Ohjelmointi 1 (6 op)

ITKP102 Ohjelmointi 1 (6 op) ITKP102 Ohjelmointi 1 (6 op) Tentaattori: Antti-Jussi Lakanen 20. huhtikuuta 2018 Vastaa kaikkiin tehtäviin. Tee kukin tehtävä omalle konseptiarkille. Noudata ohjelmointitehtävissä kurssin koodauskäytänteitä.

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

Lyhyt kertaus osoittimista

Lyhyt kertaus osoittimista , syksy 2007 Kertausta Luento 10 12.10.2007 Syksy 2007 1 Lyhyt kertaus osoittimista char *p; /* char, int, jne ilmoittavat, minkä tyyppisiä */ Keskusmuisti int *q; /* olioita sisältäviin muistilohkoihin

Lisätiedot

Esimerkkejä polynomisista ja ei-polynomisista ongelmista

Esimerkkejä polynomisista ja ei-polynomisista ongelmista Esimerkkejä polynomisista ja ei-polynomisista ongelmista Ennen yleisempiä teoriatarkasteluja katsotaan joitain tyypillisiä esimerkkejä ongelmista ja niiden vaativuudesta kaikki nämä ongelmat ratkeavia

Lisätiedot

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

Koe ma 1.3 klo 16-19 salissa A111, koeaika kuten tavallista 2h 30min Koe Koe ma 1.3 klo 16-19 salissa A111, koeaika kuten tavallista 2h 30min Kokeessa saa olla mukana A4:n kokoinen kaksipuolinen käsiten tehty, itse kirjoitettu lunttilappu 1 Tärkeää ja vähemmäntärkeää Ensimmäisen

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

Algoritmit 2. Luento 3 Ti Timo Männikkö

Algoritmit 2. Luento 3 Ti Timo Männikkö Algoritmit 2 Luento 3 Ti 20.3.2018 Timo Männikkö Luento 3 Järjestäminen eli lajittelu Kekorakenne Kekolajittelu Hajautus Yhteentörmäysten käsittely Ketjutus Algoritmit 2 Kevät 2018 Luento 3 Ti 20.3.2018

Lisätiedot

1. Mitä tehdään ensiksi?

1. Mitä tehdään ensiksi? 1. Mitä tehdään ensiksi? Antti Jussi i Lakanen Ohjelmointi 1, kevät 2010/ Jyväskylän yliopisto a) Etsitään Googlesta valmis algoritmi b) Mietitään miten itse tehtäisiin sama homma kynällä ja paperilla

Lisätiedot

Luku 3. Listankäsittelyä. 3.1 Listat

Luku 3. Listankäsittelyä. 3.1 Listat Luku 3 Listankäsittelyä Funktio-ohjelmoinnin tärkein yksittäinen tietorakenne on lista. Listankäsittely on paitsi käytännöllisesti oleellinen aihe, se myös valaisee funktio-ohjelmoinnin ideaa. 3.1 Listat

Lisätiedot

Pino S on abstrakti tietotyyppi, jolla on ainakin perusmetodit:

Pino S on abstrakti tietotyyppi, jolla on ainakin perusmetodit: Pino (stack) Pino: viimeisenä sisään, ensimmäisenä ulos (LIFO, Last In, First Out) -tietorakenne kaksi perusoperaatiota: alkion lisäys pinon päälle (push), ja päällimmäisen alkion poisto (pop) Push(alkio)

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

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

811120P Diskreetit rakenteet

811120P Diskreetit rakenteet 811120P Diskreetit rakenteet 2016-2017 ari.vesanen (at) oulu.fi 5. Rekursio ja induktio Rekursio tarkoittaa jonkin asian määrittelyä itseensä viittaamalla Tietojenkäsittelyssä algoritmin määrittely niin,

Lisätiedot

Tietorakenteet, laskuharjoitus 6,

Tietorakenteet, laskuharjoitus 6, Tietorakenteet, laskuharjoitus, 23.-2.1 1. (a) Kuvassa 1 on esitetty eräät pienimmistä AVL-puista, joiden korkeus on 3 ja 4. Pienin h:n korkuinen AVL-puu ei ole yksikäsitteinen juuren alipuiden keskinäisen

Lisätiedot