811312A Tietorakenteet ja algoritmit, 2015-2016 VI Algoritmien suunnitteluparadigmoja
Sisältö 1. Hajota ja hallitse-menetelmä 2. Dynaaminen taulukointi 3. Ahneet algoritmit 4. Peruuttavat algoritmit 811312A TRA, Suunnitteluparadigmat 2
VI.1. Hajota ja hallitse-menetelmä Divide-and-conquer approach Soveltuu, kun ongelma voidaan pilkkoa pienempiin samankaltaisiin ongelmiin Lopulta helposti ratkaistava ongelma Algoritmi koostuu yleensä kolmesta osasta: 1. Hajota algoritmi osaongelmiksi. (Divide) 2. Hallitse: Ratkaise osaongelma rekursiivisesti ja kun ongelma on riittävän pieni, ratkaise se suoraan. (Conquer) 3. Yhdistä osaongelmien ratkaisut alkuperäisen ongelman ratkaisuksi. (Combine) 811312A TRA, Suunnitteluparadigmat 3
VI.1.1. Lomituslajittelu Syöte: Taulukko A[1,..,n], n >= 1, luvut 1 <= p <= q <= n Tulostus: Taulukon alkiot A[p..q] suuruusjärjestyksessä LOMITUSLAJITTELU(A,p,q) 1. if p < q then 2. r = ( p q) / 2 3. LOMITUSLAJITTELU(A,p,r) 4. LOMITUSLAJITTELU(A,r+1,q) 5. LOMITA(A,p,r,q) 6. return LOMITA yhdistää kaksi järjestettyä listaa yhdeksi järjestetyksi listaksi 3 5 8 9 2 6 7 8 2 3 5 6 7 8 8 9 811312A TRA, Suunnitteluparadigmat 4
VI.1.1. Lomituslajittelu (2) 1. Hajottaminen: Jaa taulukko puoliksi 2. Hallitse: Lajittele pienemmät taulukot Kun taulukossa vain yksi alkio, ongelma on triviaali Voidaan myös käyttää jotain nopeaa lajittelualgoritmia riittävän pienille taulukoille 3. Yhdistä: Algoritmi LOMITA yhdistää kaksi järjestettyä taulukkoa yhdeksi järjestetyksi taulukoksi HUOM! Kaikissa algoritmeissa ei tarvita kaikkia kolmea vaihetta Esimerkki: Puolitushaku ei kolmatta vaihetta 811312A TRA, Suunnitteluparadigmat 5
VI.1.2. Mediaanin etsiminen Ongelma: Annettu n erisuurta lukua. Etsittävä suuruusjärjestyksessä keskimmäinen (eli mediaani) Siis järjestyksessä (n + 1)/2 luku Voidaan ratkaista järjestämällä luvut Algoritmin kompleksisuus parhaimmillaan luokkaa Θ(n lg(n)) Onko olemassa parempaa algoritmia? Käytetään pikalajittelusta tuttua osittamista Sarana-alkio valitaan satunnaisesti 811312A TRA, Suunnitteluparadigmat 6
VI.1.2.1 Apualgoritmi OSITA Syöte: Taulukko A[1,..,n], n >= 1, 1 <= p <= r <= n. Tulostus: Palauttaa luvun k,jolle A[k] = x ja A[p,..,k-1] <= x ja A[k+1,..,r] >= x OSITA(A,p,r) 1. valitse x = A[m] satunnaisesti osasta A[p,..,r] 2. vaihda A[m] ja A[r] 3. i = p-1 4. for j = p to r-1 5. if A[j] == x ESIMERKKI:p=2,r=7,x=8, A: 6. vaihda A[j] ja A[r] 7. if A[j] <= x 1 2 3 4 5 6 7 8 8. i = i+1 11 8 5 3 12 9 9. vaihda A[i] ja A[j] 10. vaihda A[i+1] ja A[r] 11. return i+1 OSITA 5 3 8 9 12 11 Palauttaa arvon 4 811312A TRA, Suunnitteluparadigmat 7
VI.1.2.2 Ratkaisualgoritmi ETSI Syöte: Taulukko A[1,..,n], n >= 1, luvut 1 <= p <= q <= n, ja k, jolle p <= k <= q Tulostus: Palauttaa taulukon osasta A[p,..,q] taulukon k:nneksi pienimmän alkion. ETSI(A,p,q,k) 1. x = OSITA(A,p,q) 2. if x == k 3. return A[x] // Alkio löytyi 4. else if x > k // Haetaan alemmalta puolelta 5. return ETSI(A,p,x-1,k) 6. else // Haetaan ylemmältä puolelta 7. return ETSI(A,x+1,q,k) 811312A TRA, Suunnitteluparadigmat 8
VI.1.2.2 Ratkaisualgoritmi ETSI: Analyysi Oikeellisuus: Jos oletetaan, että OSITA toimii, on selvää että algoritmi on oikea Tarkasteltu pikalajittelun yhteydessä Hakee mediaanin kutsuttaessa ETSI(A,1,n, (n + 1)/2 ) Kompleksisuus: OSITA toimii lineaarisessa ajassa, ts. askelten lukumäärä on korkeintaan c (q-p) jollakin vakiolla c, kun ositetaan taulukon väliä A[p..q] 811312A TRA, Suunnitteluparadigmat 9
VI.1.2.2 Ratkaisualgoritmi ETSI: Analyysi (2) Merkitään koko algoritmin askelten lukumäärä = T n Huonoin tapaus: Osituksessa x aina pienin tai suurin alkio T n = θ(n + n 1 + 1) = θ(n 2 ) Paras tapaus: Osituksessa x jakaa taulukon osan puoliksi T n = θ(n + n 2 + n 4 1) = θ(n) Voidaan näyttää, että keskimäärin T n = θ(n) 811312A TRA, Suunnitteluparadigmat 10
VI.2 Dynaaminen taulukointi Hajota ja hallitse tehokas, kun osaongelmat erilliset Muuten tulee turhaa työtä Dynaaminen taulukointi toimii joskus, kun osaongelmat päällekkäiset Idea: Rakennetaan ratkaisu bottom-up-periaatteella Soveltuu erityisesti optimointiongelmiin 811312A TRA, Suunnitteluparadigmat 11
VI.2 Dynaaminen taulukointi (2) Algoritmin löytämisen kaava : 1. Hahmotetaan optimaalisen ratkaisun rakenne 2. Määritetään rekursio, jolla optimiratkaisu löydetään 3. Lasketaan optimiarvo ratkaisulle lähtien alhaalta 4. Konstruoidaan optimiratkaisu edellä saadun tiedon perusteella 811312A TRA, Suunnitteluparadigmat 12
VI.2.1 Kokoonpanolinjaongelma Piste P 1,1 Piste P 1,2 Piste P 1,n-1 Piste P 1,n Kokoonpanolinja 1 a 1,1 a 1,2 a 1,n-1 a 1,n Kori saapuu e 1 t 1,1 e 2 t 2,1 t 1,2 t 2,2 t 1,n-1 x 1 t 2,n-1 x 2 Valmis auto Kokoonpanolinja 2 a 2,1 a 2,2 a 2,n-1 a 2,n Työn aika Piste P 2,1 Piste P 2,2 Piste P 2,n-1 Piste P 2,n Ongelma: Etsi nopein reitti linjaston läpi Siirtymäaika 811312A TRA, Suunnitteluparadigmat 13
VI.2.1 Kokoonpanolinjaongelma (2) Jos kokeillaan kaikki vaihtoehdot, mahdollisuuksia 2 n Joka pisteellä 2 vaihtoehtoa Käyttökelvoton isoilla syötteillä Vaihe 1: Optimaalisen ratkaisun rakenne Nopein reitti linjaston alusta pisteelle P i,j : Jos ensimmäinen työpiste (j=1), vaihtoehtoja ei ole Muuten toinen seuraavista: 1. nopein reitti linjaston alusta saman linjan edelliselle pisteelle ja sitten P i,j tai 2. nopein reitti linjaston alusta toisen linjan edelliselle pisteelle ja linjan vaihdolla P i,j :lle 811312A TRA, Suunnitteluparadigmat 14
VI.2.1 Kokoonpanolinjaongelma (3) Vaihe 2: Etsitään rekursiivinen ratkaisu Osaongelmat: Nopeimman reitin määrittäminen kuhunkin työpisteeseen asti Taulukko f1: ajat linjan 1 työpisteille f1[j] on nopein aika alusta pisteeseen P 1,j Taulukko 2: ajat linjan 2 työpisteille f2[j] on nopein aika alusta pisteeseen P 2,j f1[j] = min(f1[j-1] + a 1,j, f2[j-1] + t 2,j-1 + a 1,j ) f2[j] = min(f2[j-1] + a 2,j, f1[j-1] + t 1,j-1 + a 2,j ) nopein aika = min(f1[n]+ x 1,f2[n]+x 2 ) 811312A TRA, Suunnitteluparadigmat 15
VI.2.1 Kokoonpanolinjaongelma (4) Vaihe 3: Lasketaan optimiratkaisu Rekursio ei kannata (kompleksisuus 2 n ) Lasketaan alusta: f1[1] = e 1 + a 1,1 ja f2[1] = e 2 + a 2,1 Näiden avulla f1[2] = min(f1[1] + a 1,2, f2[1] + t 2,1 + a 1,2 ) f2[2] = min(f2[j-1] + a 2,2, f1[j-1] + t 1,1 + a 2,2 ) jne. Saadaan lineaariaikainen (Θ(n)) algoritmi 811312A TRA, Suunnitteluparadigmat 16
VI.2.1 Kokoonpanolinjaongelma: Nopein reitti Syöte: Taulukot a1[1,..,n], a2[1,..,n], t1[1,..,n], t2[1,..,n], n >= 1, luvut e1, e2, x1,x2. Taulukoissa a1 ja ovat linjojen 1 ja 2 työpisteiden ajat. Taulukoissa t1 ja t2 ovat linjoilta 1 ja 2 kultakin työpisteeltä linjan vaihtoon kuluva aika. Luvut e1 ja e2 ovat linjojen aloitusajat ja x1 ja x2 lopetusajat. Tulostus: Taulukkoihin f1 ja f2 lasketaan linjojen 1 ja 2 työpisteille nopein mahdollinen alusta kuluva aika. Taulukkoihin l1 ja l2 lasketaan linja, jota pitkin nopeimmassa reittivalinnassa tullaan työpisteelle. Esimerkiksi l1[3] on 1, jos pisteelle P1,3 tullaan nopeimmassa reitissä pisteeltä P1,2 ja 2, jos pisteeltä P2,2. Luku fs on koko linjaston nopein aika ja ls linja, jolta nopeimmassa reitissä tullaan ulos. 811312A TRA, Suunnitteluparadigmat 17
VI.2.1 Kokoonpanolinjaongelma: Nopein reitti (2) NOPEINREITTI(a1,a2,t1, t2,e1,e2,x1,x2) 1.f1[1] = e1 + a1[1] 2.f2[1] = e2 + a2[1] 3.for j = 2 to n 4. if (f1[j-1]+a1[j]) <= (f2[j-1]+t2[j-1]+a1[j]) 5. f1[j] = f1[j-1]+a1[j] 6. l1[j] = 1 7. else 8. f1[j] = f2[j-1] +t2[j-1]+a1[j] 9. l1[j] = 2 10. if (f2[j-1] + a2[j]) <= (f1[j-1]+t1[j-1]+a2[j]) 11. f2[j] = f2[j-1] + a2[j] 12. l2[j]=2 13. else 14. f2[j] = f1[j-1] +t1[j-1]+a2[j] 15. l2[j]=1 // for-silmukka loppuu 16.if (f1[n]+x1) <= (f2[n]+x2) 17. fs = f1[n]+x1 18. ls = 1 19.else 20. fs = f2[n]+x2 21. ls = 2 22.return 811312A TRA, Suunnitteluparadigmat 18
VI.2.1 Kokoonpanolinjaongelma: Nopein reitti (3) Syöte: Taulukot l1[1,..,n], l2[1,..,n], luku ls Tulostus: Nopein reitti linjastolla lopusta alkuun. TULOSTAREITTI(l1,l2,ls) 1. edellinen = ls 2. for j = n downto 1 do 3. if edellinen == 1 then 4. print linja 1 piste j 5. edellinen = l1[j] 6. else 7. print linja 2 piste j 8. edellinen = l2[j] 9. return 811312A TRA, Suunnitteluparadigmat 19
VI.2.1 Kokoonpanolinjaongelma: Esimerkki Piste P 1,1 Piste P 1,2 Piste P 1,3 Piste P 1,4 Piste P 1,5 Kokoonpanolinja 1 7 9 3 4 8 2 2 3 1 3 3 Kori saapuu 4 2 1 2 2 2 Valmis auto Kokoonpanolinja 2 8 5 6 4 5 Piste P 2,1 Piste P 2,2 Piste P 2,3 Piste P 2,4 Piste P 2,5 Nopein reitti alusta linjanumero: 1,2,1,2,2 Reittiin kuluva aika 32
VI.3 Ahneet algoritmit Strategia yksinkertainen: tehdään aina parhaalta näyttävä ratkaisu Soveltuvat parhaiten optimointiongelmiin Yleensä helppo suunnitella Oikeaksi todistaminen monesti hankalaa Monesti ahne algoritmi hyvä likimääräinen ratkaisu vaikka ei antaisi täysin oikeaa ratkaisua 811312A TRA, Suunnitteluparadigmat 21
VI.3 Ahneet algoritmit (2) Esimerkki: Muodosta annettu rahamäärä 50, 20, 10 ja 5 sentin kolikoista mahdollisimman pienellä määrällä kolikoita Ahne strategia: otetaan mahdollisimman monta 50 sentin, sitten 20 sentin, 10 sentin ja 5 sentin kolikoita -> saadaan optimiratkaisu Riippuu kolikkojen arvoista: jos kolikot olisivat 40, 30, 10 ja 5 senttiä, ahne strategia ei toimi: 60 senttiä ahneesti 40+10+10 ja optimi 30+30 811312A TRA, Suunnitteluparadigmat 22
VI.3 Ahneet algoritmit (3) Ahneen algoritmin luominen yleensä: 1. Esitetään (optimointi)ongelma niin, että kun valinta tehty, jää jäljelle vain yksi osaongelma 2. Osoitetaan, että ahne valinta sisältyy aina johonkin alkuperäisongelman optimiratkaisuun Varmistaa, että ahne valinta on turvallinen 3. Varmistetaan, että yhdistettäessä ahne valinta osaongelman optimiratkaisuun saadaan alkuperäisongelman optimiratkaisu 811312A TRA, Suunnitteluparadigmat 23
VI.3.1 Toiminnonvalitsemisongelma Toimintojen a 1,a 2,,a 11 alkamis- ja loppumisajat i 1 2 3 4 5 6 7 8 9 10 11 s i 1 3 0 5 3 5 6 8 8 2 12 f i 4 5 6 7 8 9 10 11 12 13 14 Löydettävä mahdollisimman monen toiminnon joukko S, jossa mitkään toiminnot eivät mene päällekkäin Yksi ratkaisu S = {a 2,a 4, a 9,a 11 } 811312A TRA, Suunnitteluparadigmat 24
VI.3.1 Toiminnonvalitsemisongelma: Ahne ratkaisu Olkoon S jokin optimiratkaisu ja olkoon a k sen ajallisesti ensimmäinen toiminto. Olkoon a j koko toimintojoukon ensimmäiseksi päättyvä toiminto. Havainto: a k ei voi päättyä ennen a j :tä. Siis joukossa S toiminto a k voidaan korvata a j :llä ja ratkaisu on edelleen optimaalinen Seuraus: Aina on olemassa vähintään yksi ratkaisu, jossa toiminnoista ensimmäiseksi päättyvä on mukana Saadaan ahne strategia: valitaan aina ensimmäiseksi päättyvä toiminto, joka on mahdollinen 811312A TRA, Suunnitteluparadigmat 25
VI.3.1 Toiminnonvalitsemisongelma: Ahne ratkaisu (2) Algoritmi: 1. Lajittele toiminnot päättymisajan mukaan nousevaan järjestykseen 2. Valitse ensin päättyvä toiminto 3. Poista valitun toiminnon kanssa päällekkäiset 4. Jos toimintoja jäljellä, mene askeleeseen 2 811312A TRA, Suunnitteluparadigmat 26
VI.3.1 Toiminnonvalitsemisongelma: Ahne ratkaisu (3) Olkoon toimintoja n kappaletta. Mikä on algoritmin kompleksisuus Askel 1, lajittelu voidaan suorittaa algoritmilla, jonka kompleksisuus on luokkaa Θ(n lg(n)) Askeleissa 2,3 ja 4 käydään jokainen toiminto kerran läpi, kompleksisuus yhteensä luokkaa Θ(n) Siis koko algoritmin kompleksisuus on luokkaa Θ(n lg(n)) 811312A TRA, Suunnitteluparadigmat 27
VI.3.2 Huffmanin koodit Voidaan käyttää merkkijonojen pakkaamiseen Ns. etuliitekoodeja Koodin tulkinta helppoa Esimerkki: Tiedostossa kirjaimia a,b,c,d,e,f: a b c d e f 4000 1000 2500 500 1200 800 Jos käytetään 3 bit/merkki -> 30000 bittiä 811312A TRA, Suunnitteluparadigmat 28
VI.3.2 Huffmanin koodit (2) Etuliitekoodi: Koodi, jossa minkään merkin koodi ei ole alkuosana toisen merkin koodissa Esimerkki: a b c d e f 0 111 100 1101 101 1100 Etuliitekoodi: 23300 bittiä esimerkkijakaumalla Voidaanko vielä parantaa? 811312A TRA, Suunnitteluparadigmat 29
VI.3.2 Huffmanin koodit (3) Binäärinen koodi voidaan esittää puuna, esimerkiksi edellinen koodi Siis koodin muodostaminen palautuu puun muodostamiseen HUOM! Etuliitekoodissa merkit aina puun lehdissä a c 0 1 0 1 0 1 e 0 1 f d 0 1 b 811312A TRA, Suunnitteluparadigmat 30
VI.3.2 Huffmanin koodit: Algoritmi Syöte: Taulukko C[1,..,n], jossa merkit ja taulukko f[1,..,n], jossa merkkien suhteelliset osuudet Tulostus: Muodostaa puun, joka esittäää optimaalista etuliitekoodia. HUFFMAN(C,f) 1.Tee merkeistä n kappaletta pelkästä juuresta koostuvia binääripuita. Solmun datana merkki ja suhteellinen osuus, joka on avain. 2. Järjestä puut avainkentän mukaan (nouseva järj.) 3.for j = 1 to n-1 do 4. Yhdistä kaksi juuriarvoltaan pienintä puuta lisäämällä ne vasemmaksi ja oikeaksi haaraksi puuhun, jonka juuren avainkenttä on lisättävien puiden juuriarvojen summa. 5. Siirrä muodostettu puu järjestyksessä oikeaan kohtaan 6.end for 7. return 811312A TRA, Suunnitteluparadigmat 31
VI.3.2 Huffmanin koodin muodostaminen: Esimerkkitapaus VAIHE I d:5 f:8 b:10 e:12 c:25 a:40 VAIHE II b:10 e:12 13 c:25 a:40 0 1 d:5 f:8 VAIHE VI 13 22 c:25 a:40 0 1 0 1 d:5 f:8 b:10 e:12
VAIHE IV c:25 35 a:40 0 1 13 0 1 d:5 f:8 22 0 1 b:10 e:12 VAIHE V a:40 60 0 1 c:25 35 0 1 13 0 1 d:5 f:8 22 0 1 b:10 e:12
VAIHE VI: Valmis koodi 100 0 1 a 0 b 1110 a:40 60 0 1 c:25 35 0 1 c 10 d 1100 e 1111 13 0 1 d:5 f:8 22 0 1 b:10 e:12 f 1101 Koodaa esimerkkitiedoston 23000 bitillä
VI.3.2 Huffmanin koodit: Analyysi Rivi 1: Θ(n) Rivi 2: Θ(nlg(n)) Rivejä 4 ja 5 suoritetaan n-1 kertaa Rivi 4 vakioaikainen Rivi 5 Θ(lg(n)) Yhteensä Θ(nlg(n)) Koko algoritmin kompleksisuus Θ(nlg(n)) Oikeellisuus: Perustelu luentomateriaalissa 811312A TRA, Suunnitteluparadigmat 35
VI.3.2 Huffmanin koodit: Analyysi (2) Oikeellisuus seuraa havainnosta: Olkoon C merkkien joukko ja f[c] kunkin merkin c suhteellinen osuus. Olkoot x ja y harvimmin esiintyvät merkit (f[x] ja f[y] pienimmät). Olkoon C joukko, joka saadaan poistamalla joukosta C merkit x ja y sekä lisäämällä uusi merkki z, jolle f[z] = f[x]+f[y]. Olkoon T puu, joka esittää optimaalista etuliitekoodia joukolle C. Muodostetaan puu T seuraavasti: Korvataan puussa T merkin z lehti sisäisellä solmulla, jonka lapsina ovat x ja y. Tällöin T on optimaalinen etuliitekoodi joukolle C. Ks. perustelu luentomateriaalista 811312A TRA, Suunnitteluparadigmat 36
VI.4 Peruuttavat algoritmit Peruutus (backtracking) systemaattinen menetelmä ongelman ratkaisuavaruuden läpikäymiseen Takaa parhaan ratkaisun löytämisen Voi olla parempi kuin raa an voiman menetelmä Joudutaan suunnittelemaan yksityiskohdat jokaiselle sovelluskohteelle Soveltuu erityisesti kombinatorisiin haku- ja optimointiongelmiin Merkintä: Ongelmaan haetaan ratkaisua (r 1,r 2,...,r n ), missä r i valitaan järjestetystä äärellisestä joukosta S i. 811312A TRA, Suunnitteluparadigmat 37
IV.1 Peruuttavan algoritmin periaate Algoritmissa käsitellään tietyllä hetkellä osittaista ratkaisua r = (r 1,...,r k ) Seuraavassa vaiheessa tarkistetaan voidaanko ratkaisua laajentaa 1. Voidaan: Laajennetaan ja tarkistetaan onko jo ratkaisu, jatketaan algoritmia 2. Ei voida: poistetaan viimeinen alkio osittaisratkaisusta ja siirrytään seuraavaan osittaisratkaisuun Lopulta päädytään ratkaisuun tai havaitaan että ratkaisua ei ole 811312A TRA, Suunnitteluparadigmat 38
IV.2 Geneerinen peruuttava algoritmi Syöte: Osittainen ratkaisu r ja indeksi k Output: Kun ratkaisu löydetään se käsitellään Peruuta(r,k) 1. if r ratkaisu 2. Käsittele r 3. else 4. k = k + 1 5. Muodosta joukko S k 6. while S k!= ø 7. r k = alkio joukosta S k 8. Poista r k joukosta S k 9. Peruuta(r,k) 811312A TRA, Suunnitteluparadigmat 39
IV.3 Esimerkki: Kahdeksan kuningattaren ongelma Kuinka monella tavalla 8 kuningatarta voidaan asettaa shakkilaudalle niin, että ne eivät uhkaa toisiaan Yksi ratkaisu Q Q Q Q Q Q Q Q 811312A TRA, Suunnitteluparadigmat 40
IV.3.1 Kahdeksan kuningattaren ongelma: ratkaisu Huomataan, että ratkaisussa oltava yksi kuningatar jokaisessa sarakkeessa -> Ratkaisu on vektori r=(r 1,,r 8 ) missä r i on kuningattaren paikka i:nnessä sarakkeessa Esimerkissä r=(6 3 1 8 5 2 4 7) Algoritmissa muodostetaan ratkaisut järjestyksessä 8- paikkaiseen taulukkoon ja lasketaan niiden lukumäärä 811312A TRA, Suunnitteluparadigmat 41
IV.3.1 Kahdeksan kuningattaren ongelma: algoritmi Syöte: Taulukko t[1..8], jossa paikat ja sarake col Output: Kun ratkaisu löydetään lisätään lukumäärää Queens(t,col) 1. if col == 8 2. ratkaisuja = ratkaisuja+1 3. else 4. col = col + 1 5. for i = 1 to 8 6. t[col]=i 7. if osittaisratkaisu(t,col) 8. Queens(r,k) Aluksi t=[1,,1] ja kutsutaan Peruuta(t,0) Apualgoritmi osittaisratkaisu kertoo, onko taulukon alkuosa laillinen asetelma 811312A TRA, Suunnitteluparadigmat 42