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 2/40
Paikallinen etsintä Naapurimenetelmä: 1. Aloitetaan jostain tunnetusta alkuratkaisusta 2. Toistetaan niin kauan kuin löytyy parempi ratkaisu: Tutkitaan nykyisen ratkaisun naapuriratkaisut Jos jokin naapuriratkaisu on parempi kuin nykyinen ratkaisu, korvataan nykyinen ratkaisu kyseisellä naapuriratkaisulla Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 3/40
Paikallinen etsintä Juuttuminen lokaaliin optimiin: Naapuriratkaisut lähellä nykyistä ratkaisua Jos jo ollaan lokaalissa optimissa, siitä ei enää päästä pois, vaikka hieman kauempana olisi selvästi parempi ratkaisu Simuloitu jäähdytys: Sallitaan satunnaisesti siirtyminen myös nykyistä ratkaisua huonompiin ratkaisuihin Satunnaisuutta säädellään parametrilla, jota kutsutaan lämpötilaksi Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 4/40
Simuloitu jäähdytys Muotoillaan tehtävä siten, että siinä minimoidaan kustannusta c(x) Jonkin resurssin käyttö, reitin pituus, repun paino tms. (Entä jos haluttaisiin maksimoida jotain?) Nykyinen ratkaisu x, sen naapuriratkaisu x Ratkaisujen kustannusten erotus d = c(x ) c(x) Jos d 0, on naapuriratkaisu parempi kuin nykyinen ratkaisu, joten siirrytään siihen (Jatkuu) Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 5/40
Simuloitu jäähdytys (Jatkuu) Jos d > 0, on naapuriratkaisu huonompi kuin nykyinen ratkaisu Siirrytään naapuriratkaisuun todennäköisyydellä e d/t, missä T on satunnaisuutta säätelevä lämpötila Kun d kasvaa, e d/t pienenee kohti nollaa Naapuriratkaisuun siirrytään sitä pienemmällä todennäköisyydellä huonompi naapuriratkaisu on Kun T pienenee, e d/t pienenee kohti nollaa Suuri T :n arvo antaa suuren todennäköisyyden, pieni arvo pienen todennäköisyyden Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 6/40
Simuloitu jäähdytys Jäähdytys: Aluksi lämpötilalla T suuri alkuarvo Huonompiin ratkaisuihin siirrytään suurehkolla todennäköisyydellä Lämpötilan arvoa alennetaan hallitusti kohti loppuarvoa (lähellä nollaa, mutta ei tasan nolla) Menetelmän edetessä todennäköisyys muuttuu yhä pienemmäksi ja pienemmäksi Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 7/40
Esimerkki: Kauppamatkustajan ongelma Kustannus: Reitin pituus Naapuriratkaisu 2-vaihdolla: Poistetaan kaksi tietä, lisätään kaksi tietä Siirtyminen naapuriratkaisuun: Erotus d = reitin pituuden muutos Hyväksytään naapuriratkaisu, jos d 0 Hyväksytään naapuriratkaisu, jos d > 0 ja jos e d/t satunnaisluku väliltä [0, 1] Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 8/40
Simuloitu jäähdytys T = Talku; x = satunnainen alkuratkaisu; while (T > Tloppu) { while (lämpötilaa T ei vielä tutkittu kokonaan) { x = satunnainen x:n naapuriratkaisu; d = c(x ) - c(x); if (d <= 0) x = x ; else if (exp(-d/t) >= random(0,1)) x = x ; } T = alenna(t); } return x; Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 9/40
Simuloitu jäähdytys Algoritmin yksityiskohdat tehtäväkohtaisia Tietyin edellytyksin voidaan osoittaa: Jos lämpötilaa T alennetaan riittävän hitaasti, algoritmi löytää globaalin optimin todennäköisyydellä, joka lähestyy ykköstä Joissain tapauksissa algoritmi saattaa antaa hyviä tuloksia myös paljon nopeammalla jäähdytyksellä Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 10/40
Merkkijonon sovitus Merkkijono taulukossa T, pituus n Yksittäinen merkki T [i], missä 0 i n 1 Alimerkkijono T [i..j], missä 0 i j n 1 Mallimerkkijono P, pituus m Tehtävä: Löytyykö P jostain kohtaa merkkijonoa T Toisin sanoen: Onko jollain i voimassa T [i.. (i + m 1)] = P[0.. (m 1)] Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 11/40
Merkkijonon sovitus Raa an voiman menetelmä: Etsitään P:n merkkejä yksi kerrallaan T :n ensimmäisestä merkistä alkaen Jos jokin merkeistä ei täsmää, siirretään P:tä yksi askel eteenpäin Etsitään P:n merkkejä T :n toisesta merkistä alkaen Jne. Jatketaan kunnes kaikki P:n merkit täsmäävät, tai kun P:tä ei enää voi siirtää eteenpäin Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 12/40
Merkkijonon sovitus for (i = 0; i < n-m+1; i++) { j = 0; while (j < m && T[i+j] == P[j]) j++; if (j == m) return i; // löytyi } return -1; // ei löytynyt Pahimman tapauksen aikavaativuus Θ(nm) Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 13/40
Merkkijonon sovitus Tehokkaampia menetelmiä: Esikäsitellään mallimerkkijono Kerätty tieto tallennetaan aputaulukkoon Aputaulukon tietoa käytetään hyväksi varsinaisessa sovitusvaiheessa Esimerkiksi: Horspoolin algoritmi Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 14/40
Horspoolin algoritmi Mallimerkkijono P asetetaan merkkijonon T alkuun Vertaillaan merkkejä P:n lopusta alkaen Jos jokin merkki ei täsmää, siirretään P:tä eteenpäin (oikealle) Siirto voi olla useampia askelia Jatketaan kunnes kaikki P:n merkit täsmäävät, tai kun P:tä ei enää voi siirtää eteenpäin Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 15/40
Horspoolin algoritmi Mallimerkkijonon siirto: Siirto tehdään mahdollisimman pitkälle kuitenkin siten, että mahdollista sopivaa alimerkkijonoa ei ohiteta Siirron suuruus päätetään siitä T :n merkistä, jota sovitettiin P:n viimeiseen merkkiin Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 16/40
Horspoolin algoritmi Esimerkki: Mallimerkkijonossa ei ole lainkaan sovitettavaa merkkiä d: a b c d a c d x x x x x x x a c a c c Siirretään koko P:n pituuden verran (viisi askelta): a b c d a c d x x x x x x x a c a c c Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 17/40
Horspoolin algoritmi Esimerkki: Mallimerkkijonossa on sovitettava merkki d viimeisenä merkkinä, mutta ei sitä edeltävien merkkien joukossa: a b c d a c d x x x x x x x a c a c d Siirretään koko P:n pituuden verran (viisi askelta): a b c d a c d x x x x x x x a c a c d Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 18/40
Horspoolin algoritmi Esimerkki: Mallimerkkijonossa on sovitettava merkki d, mutta ei viimeisenä merkkinä: a b c d a c d x x x x x x x a c d c c Siirretään P:n kaikkein oikeanpuoleisin d-merkki sovitettavan d:n kohdalle (kaksi askelta): a b c d a c d x x x x x x x a c d c c Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 19/40
Horspoolin algoritmi Esimerkki: Mallimerkkijonossa on useampia d-merkkejä: a b c d a c d x x x x x x x d a c d d Siirretään P:n kaikkein oikeanpuoleisin d-merkki, viimeistä huomioimatta, sovitettavan d:n kohdalle (yksi askel): a b c d a c d x x x x x x x d a c d d Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 20/40
Horspoolin algoritmi Siirtymät lasketaan etukäteen siirtymätaulukkoon s Taulukko indeksoidaan kaikilla mahdollisilla merkkijonossa ja mallimerkkijonossa esiintyvillä merkeillä Sovitettavaa merkkiä x vastaava siirtymä: s(x) = mallimerkkijonon pituus m, jos x ei esiinny mallimerkkijonon (m 1):n ensimmäisen merkin joukossa s(x) = oikeanpuoleisimman merkin x etäisyys mallimerkkijonon viimeiseen merkkiin, jos x esiintyy (m 1):n ensimmäisen merkin joukossa Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 21/40
Esimerkki Mallimerkkijono: a c a b d Pituus m = 5, merkkien lukumäärä k = 4 Siirtymätaulukko: a b c d s 2 1 3 5 Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 22/40
Horspoolin algoritmi 1. Muodostetaan siirtymätaulukko s 2. Asetetaan mallimerkkijono P merkkijonon T alkua vasten 3. Toistetaan kunnes kaikki P:n merkit täsmäävät, tai kun P:tä ei enää voi siirtää eteenpäin: Verrataan P:n ja T :n merkkejä alkaen P:n viimeisestä merkistä Jos jokin merkeistä ei täsmää, haetaan siirtymätaulukosta s vastaava siirtymä Siirtymän määrää se T :n merkki, joka on P:n viimeisen merkin kohdalla Siirretään P:tä oikealle siirtymän verran Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 23/40
Esimerkki Merkkijono: a a b b a a b a b Mallimerkkijono: a b a b Siirtymätaulukko: a b s 1 2 Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 24/40
Esimerkki jatkuu a a b b a a b a b a b a b a a b b a a b a b a b a b a a b b a a b a b a b a b a a b b a a b a b a b a b Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 25/40
Horspoolin algoritmi Merkkijono T, pituus n Mallimerkkijono P, pituus m Merkistön merkkien lukumäärä k Siirtymätaulukko s, pituus k Siirtymätaulukon muodostaminen: for (i = 0; i < k; i++) s[i] = m; for (j = 0; j < m-1; j++) s[p[j]] = m - 1 - j; Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 26/40
Horspoolin algoritmi i = m - 1; while (i < n) { j = 0; while (j < m && T[i-j] == P[m-1-j]) j++; if (j == m) return i-m+1; // löytyi else i = i + s[t[i]]; } return -1; // ei löytynyt Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 27/40
Horspoolin algoritmi Pahimman tapauksen aikavaativuus Θ(nm) (sama kuin raa an voiman menetelmässä) Satunnaisilla merkkijonoilla huomattavasti tätä nopeampi Käytännössä toimii lähes lineaarisesti n:n suhteen Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 28/40
Ositus Tehtävän esiintymä ositetaan useammaksi pienemmäksi esiintymäksi Osatehtävät ratkaistaan, yleensä rekursiivisesti Osatehtävien ratkaisuista kootaan alkuperäisen tehtävän ratkaisu Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 29/40
Rekursio Algoritmi kutsuu itseään ratkaisun aikana Oltava lopetusehto, jotta rekursio päättyy Usein rekursiivinen ratkaisu on hyvin helppo löytää Mutta aina rekursio ei ole paras mahdollinen ratkaisu Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 30/40
Rekursion toteutus Algoritmin kutsu annetulla ongelmalla: Jos pieni yksinkertainen ongelma Ratkaistaan se ja palautetaan ratkaisu Muuten jaetaan ongelma pienempiin vastaavanlaisiin ongelmiin Ratkaistaan ne rekursiivisilla kutsuilla Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 31/40
Esimerkki: Taulukon summa Tehtävä: Laske taulukon lukujen summa Osittava ratkaisu: Jos taulukossa vain yksi luku, summa on tuo luku Jos taulukossa n kpl lukuja, missä n > 1 Lasketaan (n 1):n ensimmäisen luvun summa Lisätään siihen viimeinen luku Saadaan kaikkien n:n luvun summa Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 32/40
Rekursiivinen ratkaisu laskesumma(t, n) { if (n == 1) return t[0]; else return (laskesumma(t, n-1) + t[n-1]); } Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 33/40
Rekursiivinen ratkaisu laskesumma(t, n) { if (n == 1) return t[0]; else { alkusumma = laskesumma(t, n-1); summa = alkusumma + t[n-1]; return summa; } } Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 34/40
Toteutus ohjelmointikielellä public static int laskesumma(int[] t, int n) { if (n == 1) return t[0]; else { int alkusumma = laskesumma(t, n-1); int summa = alkusumma + t[n-1]; return summa; } } Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 35/40
Algoritmin toiminta Ensimmäisessä kutsussa n on koko taulukon pituus Siirrytään else-osaan Summaa ei voi laskea ennen kuin alkusumma on laskettu Tämän vaiheen suoritus jää toistaiseksi kesken Rekursiokutsu taulukon pituudella n-1 Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 36/40
Algoritmin toiminta jatkuu Saman algoritmin kutsu pituudella n-1 Siirrytään else-osaan Summaa ei voi laskea ennen kuin alkusumma on laskettu Tämän vaiheen suoritus jää toistaiseksi kesken Rekursiokutsu taulukon pituudella n-2 Jne. Huom: Kaikki suoritukset jäävät kesken odottamaan rekursion päättymistä Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 37/40
Algoritmin toiminta jatkuu Rekursio päättyy kun n pienenee arvoon 1 Jolloin palautetaan taulukon ensimmäinen luku Edellinen kesken jäänyt suoritus jatkuu Alkusumma saadaan paluuarvona Summa voidaan laskea Palautetaan summa Algoritmin tämän vaiheen suoritus päättynyt Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 38/40
Algoritmin toiminta jatkuu Edellinen kesken jäänyt suoritus jatkuu Alkusumma saadaan paluuarvona Summa voidaan laskea Palautetaan summa Algoritmin tämän vaiheen suoritus päättynyt Jne. Huom: Kesken jääneet suoritukset päättyvät päinvastaisessa järjestyksessä Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 39/40
Algoritmin toiminta jatkuu Algoritmin viimeinenkin kesken jäänyt suoritus viety loppuun Palataan sinne missä ensimmäinen kutsu tehtiin Algoritmin suoritus päättynyt Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019 40/40