Algoritmit 1 Luento 13 Ma 26.2.2018 Timo Männikkö
Luento 13 Suunnittelumenetelmät Taulukointi Kapsäkkiongelma Ahne menetelmä Verkon lyhimmät polut Dijkstran menetelmä Verkon lyhin virittävä puu Kruskalin menetelmä Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 2/33
Algoritmien suunnittelu Suunnittelumenetelmiä: Raaka voima Osittaminen Taulukointi Ahne menetelmä Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 3/33
Taulukointi Taulukointi (dynaaminen optimointi): Tehtävä ratkaistaan vaiheittain, osatehtävä kerrallaan Pyrkimyksenä välttää sitä, että jo laskettuja tuloksia laskettaisiin toistuvasti uudestaan Suurempi ja monimutkaisempi tehtävä hajotetaan pienempiin ja yksinkertaisempiin osatehtäviin Osatehtävien ratkaisut taulukoidaan Taulukon avulla muodostetaan alkuperäisen tehtävän ratkaisu Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 4/33
Binomikertoimien laskeminen Binomikertoimet määritellään ( ) n n! = k k!(n k)!, kun 0 k n Voidaan laskea palautuskaavalla ( ) { n 1, kun k = 0 tai k = n = ) ( k + n 1 ), kun 0 < k < n ( n 1 k 1 k Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 5/33
Binomikertoimien laskeminen Palautuskaava Rekursiivinen algoritmi: int bin(int n, int k) { if (k == 0 k == n) return 1; else return bin(n-1, k-1) + bin(n-1, k); } Mutta: Laskee samoja arvoja moneen kertaan Aikavaativuus eksponentiaalinen Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 6/33
Binomikertoimien laskeminen Kaksiulotteinen taulukko c[0..n][0..k]: Luku c[i][j] = binomikerroin ( ) i j c[i][0] = 1 ja c[i][i] = 1 Muut arvot lasketaan palautuskaavan mukaan Luku c[n][k] = binomikerroin ( ) n k Huom: Jos halutaan tietää vain viimeinen arvo c[n][k], ei tarvita kaksiulotteista taulukkoa Yksiulotteinen taulukko c[0..k] riittäisi Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 7/33
Binomikertoimien laskeminen Taulukoiva, ei-rekursiivinen algoritmi: int bin(int n, int k) { for (i = 0; i <= n; i++) { c[i][0] = 1; if (i <= k) c[i][i] = 1; for (j = 1; j <= min(i-1, k); j++) c[i][j] = c[i-1][j-1] + c[i-1][j]; } return c[n][k]; } Aikavaativuus O(nk) Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 8/33
Kapsäkkiongelma Valittavana n kpl erilaisia tavaroita Tavaralle i tunnetaan hyötyarvo p i ja paino w i Tavaraa otetaan mukaan joko 0 tai 1 kpl Annettu kokonaispainoraja W Tehtävänä valita reppuun R tavarat siten, että niiden hyötyarvo on mahdollisimman suuri, mutta painoraja ei ylity max i R p i kun i R w i W Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 9/33
Kapsäkkiongelman ratkaiseminen Taulukoiva ratkaisu: Oletetaan, että hyötyarvot ja painot ovat positiivisia kokonaislukuja Numeroidaan tavarat 1, 2,..., n Osaongelmat: Repun hyötyarvo s(k, r), missä Tavarat valitaan osajoukosta 1, 2,..., k Kokonaispaino korkeintaan r Taulukoidaan arvot s(k, r), kun k = 0, 1,..., n ja r = 0, 1,..., W Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 10/33
Kapsäkkiongelman ratkaiseminen Kun mitään tavaraa ei oteta mukaan, on hyötyarvo 0 kaikilla sallituilla painorajoilla s(0, r) = 0 kaikilla r = 0, 1,..., W Kun painoraja on 0, on hyötyarvo 0 riippumatta valittavien tavaroiden osajoukosta s(k, 0) = 0 kaikilla k = 0, 1,..., n Kokeillaan ottaa aina yksi uusi tavara mukaan Lasketaan arvot s(k, r), kun tunnetaan aikaisemmat arvot s(k 1, r) Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 11/33
Kapsäkkiongelman ratkaiseminen Jos uusi tavara k ei enää mahdu kokoa r olevaan reppuun, sitä ei oteta mukaan s(k, r) = s(k 1, r) Jos uusi tavara mahtuu, tarkistetaan kannattaako sitä ottaa mukaan s(k, r) = max{s(k 1, r), p k + s(k 1, r w k )} Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 12/33
Kapsäkkiongelman ratkaiseminen Yleisesti kaikilla k = 1, 2,..., n ja r = 1, 2,..., W s(k 1, r), jos w k > r s(k, r) = max{s(k 1, r), p k + s(k 1, r w k )}, jos w k r Hyötyarvot ja painot taulukoissa p[1..n] ja w[1..n] Lasketaan osaongelmien ratkaisut taulukkoon s[0..n][0..w] Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 13/33
Kapsäkkiongelman ratkaiseminen 1. for (r = 0; r <= W; r++) s[0][r] = 0; 2. for (k = 0; k <= n; k++) s[k][0] = 0; 3. for (k = 1; k <= n; k++) { for (r = 1; r <= W; r++) { if (w[k] > r) s[k][r] = s[k-1][r]; else s[k][r] = max(s[k-1][r], p[k] + s[k-1][r-w[k]]); } } 4. return s[n][w]; Aikavaativuus O(nW ) Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 14/33
Ahne menetelmä Ratkaisu rakennetaan peräkkäisistä, paikallisesti parhaan näköisistä (lokaalisesti optimaalisista) valinnoista Joskus lokaalisesti optimaaliset valinnat johtavat globaalisti optimaaliseen ratkaisuun Joskus lokaalisesti optimaaliset valinnat johtavat huonoon lopputulokseen Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 15/33
Esimerkki Esitettävä 17 rahayksikön summa mahdollisimman vähillä kolikoilla Ahne menetelmä: Valitaan aina suurin kolikko, joka vielä sopii jäljellä olevaan summaan Käytettävissä 10, 5 ja 1 yksikön kolikoita 17 = 10 + 5 + 1 + 1 (4 kpl, optimaalinen) Käytettävissä 13, 10, 5 ja 1 yksikön kolikoita 17 = 13 + 1 + 1 + 1 + 1 (5 kpl, ei optimaalinen) Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 16/33
Ahne menetelmä vastaus ahne(tapaus x) { y = tyhjä osittaisvastaus; while (y ei ole täydellinen vastaus) { valitaan y:n mahdollisista täydennyksistä e[1],..., e[m] sellainen e[i], että osittaisvastaus y täydennettynä e[i]:llä antaa "suurimman arvon"; if (y:n täydentäminen ei ole mahdollista) return virhe; else täydennetään y täydennyksellä e[i]; } return y; } Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 17/33
Verkon lyhimmät polut Suunnattu verkko G = (V, E) Solmujen joukko V, kaarien joukko E Etäisyysfunktio l kertoo kaarien pituudet Oletetaan, että l(e) 0 kaikilla kaarilla e E Lähtösolmu v 0 V kiinnitetty Tehtävänä etsiä lyhimmät polut lähtösolmusta kaikkiin muihin solmuihin Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 18/33
Verkon lyhimmät polut Dijkstran menetelmä: Ylläpidetään joukkoa niistä solmuista, joiden lyhimmän polun pituus jo tunnetaan Laajennetaan joukkoa solmu kerrallaan ahneeseen tyyliin 1. Asetetaan S = {v 0 } 2. Lisätään joukkoon S se joukon V \ S solmu, joka näyttää olevan seuraavaksi lähinnä lähtösolmua v 0 3. Toistetaan kohtaa 2 kunnes S = V Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 19/33
Dijkstran menetelmä tulos Dijkstra(L, v0) // L on verkon etäisyysmatriisi // L[u,v] = ääretön, jos ei kaarta (u,v) { S = {v0}; V = {muut solmut paitsi v0}; D[v0] = 0; for each (v in V) D[v] = L[v0,v]; while (V ei ole tyhjä joukko) { valitaan jokin u in V, jolla D[u] on pienin; lisätään u joukkoon S ja poistetaan se joukosta V; for each (v in V) D[v] = min(d[v], D[u] + L[u, v]); } return D; } Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 20/33
Dijkstran menetelmä Kaksi sisäkkäistä silmukkaa, joiden suorituskertojen lukumäärä riippuu solmujen lukumäärästä Aikavaativuus O(n 2 ) Tehokkaita tietorakenteita käyttämällä aikavaativuutta voidaan parantaa harvoille verkoille Tehokkain tunnettu toteutus O(n log n + m), missä m on kaarien lukumäärä Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 21/33
Dijkstran toiminta Algoritmin suorituksen aikana jokaisella u S on voimassa: D[u] on lyhimmän polun pituus solmusta v 0 solmuun u Todistetaan väite matemaattisella induktiolla joukon S koon suhteen: Perusaskel: Alkutilanteessa on S = {v 0 } ja D[v 0 ] = 0, joten väite tosi, kun S = 1 Induktio-oletus: Väite tosi jollain S = k Induktioaskel: Osoitetaan, että väite edelleen tosi, kun joukkoon S lisätään jokin uusi solmu u Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 22/33
Dijkstran toiminta jatkuu Olkoon u / S se solmu, joka lisätään seuraavaksi joukkoon S Tunnetaan etäisyys D[u] jotain polkua pitkin Olkoon P jokin toinen polku v 0 x y u, missä x S ja sen välitön seuraaja y / S Solmu u valitaan siten, että D[u] pienin D[u] D[y] Kun x lisättiin S:ään, päivitettiin D[y] D[y] D[x] + L[x, y] Induktio-oletus D[x] on lyhin etäisyys x:ään D[x] + L[x, y] P:n pituus (sillä kaarien pituudet ei-negatiivisia) Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 23/33
Dijkstran toiminta jatkuu D[u] D[y] D[y] D[x] + L[x, y] D[x] + L[x, y] P:n pituus D[u] P:n pituus Väite tosi Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 24/33
Verkkoihin liittyviä termejä Suuntaamaton verkko G = (V, E) Verkon G aliverkko G = (V, E ), missä V V ja E E Aliverkko G virittää G:n, jos V = V Olkoon G yhtenäinen Jos G:n virittävä aliverkko G ei sisällä silmukoita, on G tällöin G:n virittävä puu Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 25/33
Verkon virittävä puu Virittävä puu: Sisältää kaikki verkon solmut ja osan sen teistä siten, että nuo tiet yhdistävät kaikki solmut toisiinsa ilman silmukoita Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 26/33
Verkkoihin liittyviä termejä Virittävä puu aina yhtenäinen Jos G ei ole yhtenäinen, sillä ei voi olla virittävää puuta Mutta jokaisella verkon G yhtenäisellä komponentilla voi olla oma virittävä puunsa Jos aliverkko G virittää verkon G ja se koostuu useammasta erillisestä virittävästä puusta, G on G:n virittävä metsä Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 27/33
Verkon lyhin virittävä puu Etäisyysfunktio l kertoo teiden pituudet Aliverkon G = (V, E ) pituus on siihen kuuluvien teiden yhteispituus l(g ) = e E l(e) Virittävän puun pituus tarkoittaa aliverkon pituutta silloin kun aliverkko on myös virittävä puu Tehtävänä etsiä sellainen yhtenäisen verkon virittävä puu, jonka pituus on mahdollisimman pieni Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 28/33
Verkon lyhin virittävä puu Triviaaliratkaisu: Käydään läpi kaikki virittävät puut Mutta aikavaativuus eksponentiaalinen Monet algoritmit perustuvat tulokseen: Jaetaan verkon solmut kahteen erilliseen epätyhjään joukkoon V 1 ja V 2 Olkoon e lyhin kaikista teistä, joiden toinen päätesolmu on V 1 :ssä ja toinen V 2 :ssa Silloin on olemassa lyhin virittävä puu, jossa e on mukana yhtenä virittävän puun tienä Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 29/33
Verkon lyhin virittävä puu Tuloksen todistus: Olkoon T verkon jokin lyhin virittävä puu Jos e T, tulos pitää paikkansa Jos e / T, on olemassa jokin toinen tie f T, jonka toinen päätesolmu on V 1 :ssä ja toinen V 2 :ssa Tie e on tällaisista teistä lyhin l(e) l(f ) Poistetaan f puusta T ja lisätään e sen tilalle Saadaan virittävä puu, jonka pituus on alkuperäisen T :n pituus Uusi puu on myös lyhin virittävä puu Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 30/33
Verkon lyhin virittävä puu Kruskalin menetelmä: Aloitetaan triviaalilla virittävällä metsällä: Metsä (V, T ), missä T = Siis jokainen solmu muodostaa oman erillisen puunsa Yhdistetään puita teillä ahneeseen tyyliin, kunnes tuloksena on yksi yhtenäinen puu Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 31/33
Kruskalin menetelmä joukko Kruskal(V,E) // Oletetaan, että verkko on yhtenäinen { T = tyhjä joukko; while (metsä <V,T> ei ole puu) { valitaan jokin e in E, jolla l(e) on pienin; poistetaan e teiden joukosta E; if (e:n päät kuuluvat T:n eri puihin) lisätään e joukkoon T; } return T; } Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 32/33
Kruskalin menetelmä Aikavaativuus riippuu lyhimmän tien valintatavasta ja joukko-operaatioiden toteutuksesta Tehokkaita tietorakenteita käyttäen voidaan muodostaa toteutus, jonka vaativuus on O(m log m), missä m on teiden lukumäärä Algoritmit 1 Kevät 2018 Luento 13 Ma 26.2.2018 33/33