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 Luento 11 Ti 14.2.2017 2/31
Algoritminen ongelmanratkaisu Algoritmin suunnittelu: Käytetään hyviksi osoittautuneita suunnittelumenetelmiä Samantyyppisille ongelmille sopivat samantyyppiset algoritmit Voidaanko ongelma muuntaa joksikin tunnetuksi ongelmaksi Algoritmit 1 Kevät 2017 Luento 11 Ti 14.2.2017 3/31
Suunnittelumenetelmät Yleisiä tekniikoita ja periaatteita algoritmin muodostamiseksi Joskus algoritmi voidaan katsoa kuuluvan usean eri suunnittelumenetelmän mukaiseksi Joskus algoritmin ei voida katsoa kuuluvan mihinkään erityiseen suunnittelumenetelmäluokkaan Monesti algoritmi käyttää hyväksi ongelman erityisominaisuuksia Algoritmit 1 Kevät 2017 Luento 11 Ti 14.2.2017 4/31
Osittaminen Osittaminen (hajota ja hallitse): Jos ongelman esiintymä riittävän pieni tai yksinkertainen, ratkaistaan se jollain suoralla menetelmällä Muuten ositetaan ongelman esiintymä saman ongelman useaksi pienemmäksi esiintymäksi Ratkaistaan osaongelmat (yleensä) rekursiivisesti Muodostetaan osaongelmien ratkaisuista alkuperäisen ongelman esiintymän ratkaisu Algoritmit 1 Kevät 2017 Luento 11 Ti 14.2.2017 5/31
Osittaminen Yleensä ositus kannattaa tehdä siten, että osaongelmat ovat keskenään suunnilleen samankokoisia Joissain tapauksissa on mahdollista, että osaongelmat eivät ole täysin erillisiä Algoritmit 1 Kevät 2017 Luento 11 Ti 14.2.2017 6/31
Osittaminen vastaus osittava(tapaus x) { if (x on "pieni") y = pienen tapauksen ratkaisu; else { jaetaan x osiin x[1],...,x[m]; y[1] = osittava(x[1]);... y[m] = osittava(x[m]); kootaan x:n vastaus y osista y[1],...,y[m]; } return y; } Algoritmit 1 Kevät 2017 Luento 11 Ti 14.2.2017 7/31
Lomituslajittelu (merge sort) Oletus: Järjestettäviä alkioita n = 2 k Jaetaan järjestettävät alkiot kahteen osajoukkoon Osajoukoissa n/2 alkiota Osajoukot lajitellaan rekursiivisesti Rekursio lopetetaan, kun osajoukossa on yksi alkio Yhdistetään kahden järjestetyn osajoukon alkiot lomittamalla Algoritmit 1 Kevät 2017 Luento 11 Ti 14.2.2017 8/31
Lomituslajittelu Merge_sort(a, l, h) { if (l < h) { k = (l + h)/2; Merge_sort(a, l, k); Merge_sort(a, k+1, h); Merge(a, l, k, h); } } Merge(a, l, k, h) // Lomitetaan alkiot l,...,k ja // k+1,...,h järjestykseen Algoritmit 1 Kevät 2017 Luento 11 Ti 14.2.2017 9/31
Lomituslajittelu Lomitus: Verrataan molempien osien ensimmäisiä alkioita ja siirretään niistä pienempi järjestettyjen alkioiden joukon viimeiseksi Verrataan uudestaan molempien osien tällä hetkellä ensimmäisinä olevia alkiota ja siirretään niistä pienempi järjestettyjen alkioiden joukon viimeiseksi Näin jatketaan kunnes jommastakummasta osasta alkiot loppuvat, minkä jälkeen toisessa osassa jäljellä olevat alkiot voidaan siirtää suoraan järjestettyjen alkioiden joukon loppuun Algoritmit 1 Kevät 2017 Luento 11 Ti 14.2.2017 10/31
Lomituslajittelu: Esimerkki 20 6 12 17 14 9 23 15 20 6 12 17 14 9 23 15 20 6 12 17 14 9 23 15 20 6 12 17 14 9 23 15 6 20 12 17 14 9 23 15 6 20 12 17 14 9 23 15 6 20 12 17 14 9 23 15 6 12 17 20 14 9 23 15 Algoritmit 1 Kevät 2017 Luento 11 Ti 14.2.2017 11/31
Lomituslajittelu: Esimerkki jatkuu 6 12 17 20 14 9 23 15 6 12 17 20 14 9 23 15 6 12 17 20 14 9 23 15 6 12 17 20 9 14 23 15 6 12 17 20 9 14 23 15 6 12 17 20 9 14 15 23 6 12 17 20 9 14 15 23 6 9 12 14 15 17 20 23 Algoritmit 1 Kevät 2017 Luento 11 Ti 14.2.2017 12/31
Lomituslajittelun vaativuus Merkitään: T (n) = suoritusajan pahimman tapauksen vaativuus, kun syöttötiedon koko n alkiota Yhden alkion järjestäminen: vakioaika b Rekursiivisten kutsujen suoritukset: kaksi kutsua T (n/2) Lomitus voidaan tehdä lineaarisessa ajassa: cn jollain vakiolla c Algoritmit 1 Kevät 2017 Luento 11 Ti 14.2.2017 13/31
Lomituslajittelun vaativuus T (n) = { b, kun n = 1 2T ( n ) + cn, kun n > 1 2 Tästä voidaan ratkaista T (n) Algoritmit 1 Kevät 2017 Luento 11 Ti 14.2.2017 14/31
Rekursioyhtälön ratkaiseminen n = 2 k k = log 2 n T (n) = 2T ( n 2 ) + cn ( = 2 2T ( n 4 ) + c n ) 2 = 21 T (2 k 1 ) + 1cn + cn = 4T ( n 4 ) + 2cn = 22 T (2 k 2 ) + 2cn =... = 2 k T (2 0 ) + kcn = nb + kcn = bn + cn log 2 n = O(n log n) Algoritmit 1 Kevät 2017 Luento 11 Ti 14.2.2017 15/31
Suurten kokonaislukujen kertolasku Annettu n-bittisiä kokonaislukuja Oletus: n = 2 k jollain k = 0, 1,... Kahden luvun yhteenlasku: Bitti kerrallaan O(n) Kertominen kakkosen potenssilla 2 m : Voidaan toteuttaa sivuttaissiirtona O(m) Kahden luvun kertolasku: Bitti kerrallaan ( peruskoulualgoritmilla ) O(n 2 ) Algoritmit 1 Kevät 2017 Luento 11 Ti 14.2.2017 16/31
Suurten kokonaislukujen kertolasku Tehtävä: Kokonaislukujen X ja Y kertolasku Osittavaa ratkaisua varten: Jaetaan X :n bitit kahteen yhtäsuureen osaan: X [A, B] Jaetaan Y :n bitit kahteen yhtäsuureen osaan: Y [C, D] X = A 2 n/2 + B Y = C 2 n/2 + D Algoritmit 1 Kevät 2017 Luento 11 Ti 14.2.2017 17/31
Suurten kokonaislukujen kertolasku Osittava ratkaisu 1: XY = AC 2 n + (AD + BC) 2 n/2 + BD 4 kpl kertolaskuja n/2-bittisillä luvuilla 2 kpl sivuttaissiirtoja 3 kpl yhteenlaskuja T (n) = { b, kun n = 1 4T ( n 2 ) + cn, kun n = 2k T (n) = = O(n log 2 4 ) = O(n 2 ) Algoritmit 1 Kevät 2017 Luento 11 Ti 14.2.2017 18/31
Suurten kokonaislukujen kertolasku Osittava ratkaisu 2 (Karatsuba & Ofman 1962): XY = AC 2 n + [(A B)(D C) + AC + BD] 2 n/2 + BD 3 kpl kertolaskuja n/2-bittisillä luvuilla 2 kpl sivuttaissiirtoja 6 kpl yhteen- ja vähennyslaskuja T (n) = { b, kun n = 1 3T ( n 2 ) + cn, kun n = 2k T (n) = = O(n log 2 3 ), log 2 3 1.58 < 2 Algoritmit 1 Kevät 2017 Luento 11 Ti 14.2.2017 19/31
Suurten kokonaislukujen kertolasku Aikavaativuusfunktion vakiot ovat sellaisia, että peruskoulualgoritmi on tehokkaampi aina noin 500-bittisiin lukuihin asti Vielä nopeampi algoritmi: O(n log n log(log n)) (Schönhage & Strassen 1971) Avoin ongelma: Onko algoritmia, jolla O(n) Toteutuksissa osittamista jatketaan vain käytettävän tietokoneen sananpituuteen asti Osien kertolasku voidaan toteuttaa yhdellä konekäskyllä Algoritmit 1 Kevät 2017 Luento 11 Ti 14.2.2017 20/31
Pikalajittelu (quicksort) Perustuu osittamiseen ja rekursioon Periaate: Alkiot jaetaan kahteen pienempään osaan, jotka voidaan lajitella erikseen toisistaan riippumatta Pikalajittelu: Jos taulukon pituus pienempi kuin jokin raja, järjestetään alkiot lisäyslajittelulla (ainakin silloin jos pituus < 3) Valitaan jokin alkioista jakotietueeksi (Jatkuu) Algoritmit 1 Kevät 2017 Luento 11 Ti 14.2.2017 21/31
Pikalajittelu jatkuu Ositetaan taulukko siirtelemällä alkioita siten, että tämän vaiheen jälkeen: Jakotietue on paikassa j Alkiot, jotka ovat pienempiä kuin jakotietue, ovat ennen paikkaa j Alkiot, jotka ovat suurempia kuin jakotietue, ovat paikan j jälkeen Alkiot, jotka ovat yhtä suuria kuin jakotietue, voivat olla paikan j kummalla puolella tahansa (Jatkuu) Algoritmit 1 Kevät 2017 Luento 11 Ti 14.2.2017 22/31
Pikalajittelu jatkuu Lajitellaan alkuosa (paikat 0, 1,..., j-1): Pikalajittelulla (rekursio) Lajitellaan loppuosa (paikat j+1, j+2,..., n-1): Pikalajittelulla (rekursio) Algoritmit 1 Kevät 2017 Luento 11 Ti 14.2.2017 23/31
Jakotietueen valinta Ensimmäinen alkio Jos alkiot satunnaisessa järjestyksessä, sopiva valinta Jos alkiot jo järjestyksessä, jakotietue jää tarkasteltavan osan alkuun (tai loppuun) Epäonnistunut ositus: Epätasainen jako johtaa tehottomuuteen Satunnainen alkio Suurin tai pienin alkio valitaan todennäköisyydellä 2/n Epäonnistumisen todennäköisyys ei kovin suuri Algoritmit 1 Kevät 2017 Luento 11 Ti 14.2.2017 24/31
Jakotietueen valinta jatkuu Keskimmäinen alkio Jos alkiot jo järjestyksessä, ositus ei voi epäonnistua Muuten epäonnistumisen todennäköisyys sama kuin edellä Mediaanimenetelmä Valitaan suuruudeltaan keskimmäinen ensimmäisestä, keskimmäisestä ja viimeisestä alkiosta Jos alkuperäisestä järjestyksestä ei tiedetä mitään etukäteen, tämä on yleensä parempi kuin edelliset Algoritmit 1 Kevät 2017 Luento 11 Ti 14.2.2017 25/31
Jakotietueen valinta jatkuu Yhdeksän alkion pseudomediaani Valitaan tasavälisesti yhdeksän alkiota Valitaan näistä kolmen ensimmäisen mediaani, sitten kolmen seuraavan ja vielä kolmen viimeisen mediaani Jakotietueeksi valitaan näiden kolmen mediaanialkion mediaani Voidaan käyttää, kun alkioiden lukumäärä riittävän suuri (yleensä 40) Algoritmit 1 Kevät 2017 Luento 11 Ti 14.2.2017 26/31
Ositus Alkiot taulukossa t Indeksit l ja r ilmoittavat tarkasteltavan osan ensimmäisen ja viimeisen alkiot paikat Järjestettävänä siis taulukon osa t[l..r] Jakotietueeksi on valittu (jollain tavalla) alkio t[k] Ositus esimerkiksi seuraavan aliohjelman mukaisesti Algoritmit 1 Kevät 2017 Luento 11 Ti 14.2.2017 27/31
Ositus, aliohjelma int partition(int[] t, int l, int r, int k) { swap(l, k); // jakotietue taulukon alkuun i = l; j = r+1; while (true) { do i++; while (i < r+1 && t[i].key < t[l].key); do j--; while (t[j].key > t[l].key); if (j < i) break; swap(i, j); // vaihdetaan t[i] ja t[j] } swap(l, j); // jakotietue paikalleen return j; // jakotietueen indeksi } Algoritmit 1 Kevät 2017 Luento 11 Ti 14.2.2017 28/31
Ositus, erikoistapauksia Kaikki alkiot pienempiä kuin jakotietue: Ensimmäisen do-silmukan jälkeen i = r+1 Toisen do-silmukan jälkeen j = r Jakotietue siirretään paikkaan r Kaikki alkiot suurempia kuin jakotietue: Ensimmäisen do-silmukan jälkeen i = l+1 Toisen do-silmukan jälkeen j = l Jakotietue säilyy paikassa l Algoritmit 1 Kevät 2017 Luento 11 Ti 14.2.2017 29/31
Pikalajittelu void quicksort(int[] t, int l, int r) { if (r-l < raja) { // järjestetään lisäyslajittelulla } else { k = pivot(t, l, r); // jakotietue j = partition(t, l, r, k); // ositus quicksort(t, l, j-1); // alkuosa quicksort(t, j+1, r); // loppuosa } } Algoritmit 1 Kevät 2017 Luento 11 Ti 14.2.2017 30/31
Lajittelumenetelmien stabiilisuus Lomituslajittelu: Stabiili Pikalajittelu: Edellä esitetty versio ei ole stabiili Mutta voidaan toteuttaa myös stabiilina Algoritmit 1 Kevät 2017 Luento 11 Ti 14.2.2017 31/31