310 likes | 590 Views
Algoritmid ja andmestruktuurid. Ahned ( greedy ) algoritmid. Ahned algoritmid. Annavad efektiivse lahenduse mitmetele keerulisena näivatele probleemidele Ei leidu (usutavasti) kõigile keerulistele probleemidele Keerukana näiva probleemi korral:
E N D
Algoritmid ja andmestruktuurid Ahned (greedy) algoritmid
Ahned algoritmid • Annavad efektiivse lahenduse mitmetele keerulisena näivatele probleemidele • Ei leidu (usutavasti) kõigile keerulistele probleemidele • Keerukana näiva probleemi korral: • tasub alustada ahne algoritmi olemasolu otsimisest • püüda leida kontranäidet, mida ahne algoritmi kandidaat ei suuda lahendada • tõestada, et algoritm jõuab alati lahenduseni
Vahetusraha probleem • Tagasi tuleb anda mingi juhuslik summa • Kuidas leida millistest müntidest summa koostada, et kokku tuleks minimaalne arv münte? • Kasutusel on näiteks 1, 5, 10 ja 25 sendised mündid
Ahne algoritm ei tööta alati • Sama algoritmi ei saa kasutada mõne teise baasmüntide hulga korral. Näiteks asendades 25- sendise mündi 26-sendisega.
Ahned algoritmid Lahenduseni jõutakse tehes igal sammul hetke parim valik. • Kasutatakse optimaalse lahenduse leidmise ülesannetes • Kõik valikud on lokaalselt optimaalsed • Tahetakse jõuda globaalselt optimaalse tulemuseni
Ahne algoritmi tsükkel 1. Valik • järgmise elemendi valik hulgast • tehakse lokaalsest optimaalsusest lähtuvalt N: valitakse kõige suurem olemasolev münt 2. Sobivuse kontroll • kontrollitakse kas selle elemendi valimisel on võimalik lahenduseni jõuda N: kontrollitakse, et selle mündi lisamisega ei mindaks üle lõppsumma, kui minnakse, siis võetakse järjekorras järgmine 3. Lahenduseni jõudmise kontroll • kontrollitakse kas ollaks juba lahenduseni jõudnud
Lokaalne optimaalsus Kriteeriumit nimetatakse lokaalseks kui otsuse tegemine ei nõua tagasivõtmist (backtracking) ja ammendavat otsingut. Lokaalne optimaalsus ei taga alati globaalset optimaalsust, seda tuleb tõestada iga konkreetse probleemi kohta eraldi!
Seljakoti pakkimise probleem • Igal elemendil on kaal (maht) ja väärtus • Ette on antud maksimaalne kaal (maht) • Tuleb leida maksimaalse väärtusega paigutus • Täisosaline (0-1) ülesanne: elemente saab valida tüki kaupa • Murdosaline ülesanne: elemente saab valida ka murdosades i pi wi pi/wi 1 $40 2 $20 2 $30 5 $6 3 $50 10 $5 4 $60 15 $4 5 $10 5 $2 W = 16
Graafiteooria mõisteid • Graaf koosneb tippudest ja kaartest. • Kaared võivad olla suunaga ja suunata. • Kaared võivad olla kaaludega ja kaaludeta. • Tee on tippude jada, nii et olemas kaar, mis ühendab iga kahte järgnevat tippu. • Tsükkel on tee tipust iseendasse. • Graaf on sidus, kui igast tipust on olemas tee igasse teise tippu • Puu on sidus graaf, mis ei sisalda tsükleid.
Graafiteooria mõisteid • Graaf G = ( V, E ) • Tippude hulk V • Kaarte hulk E = { ( vi, vj ) } • Tee p = < v0 , v1 , v2 , ... , vk >, ( vi ,vi+1 ) E • Tsükkel tee kus v0 = vk
Graafi minimaalne kattev puu • Graafi G kattev puu (spanning tree) on kaarte hulk suurusega |V| -1, mis ühendab kõikki tippe • Minimaalne kattev puu on see, mille kõigi kaartega seotud kaalude summa on minimaalne On antud graaf, mille kaartel on kaalud • Minimaalse katva probleemi lahendus on oluline kaabelduse, torustike, raudteede jms planeerimisel
Minimaalse katva puu probleemi ahne algoritm while (ülesanne pole lahendatud) { vali mingis mõttes lokaalselt parim kaar kontrolli, et selle lisamine ei moodustaks tsüklit kui tulemus on kattev puu, siis on lahendatud }
Prim’i algoritm - idee F = ; // kaarte hulk Y = {v1}; // tippude hulk while (pole lahendatud) { vali tipp hulgast V-Y mis on lähim Y-le; lisa tipp Y-le; lisa kaar F-le; if (Y == V) lahendatud; } http://students.ceid.upatras.gr/~papagel/project/prim.htm
Prim’i algoritm - andmestruktuur kaare kaal kui (vi, vj) E W[i][j] = kui (vi, vj) E 0 kui i = j nearest[i] vi-le lähim tipp Y-s distance[i] kaugus vi ja nearest[i] vahel
Prim’i algoritm void prim (int n, const number W[][], set_of_edges& F) { index i, vnear; number min; edge e; index nearest[2...n]; number distance[2...n]; F = ; for (i=2; i <= n; i++) { nearest[i] = 1; distance[i] = W[1][i]; }
Prim’i algoritm repeat (n-1 times) { min = ; for (i=2; i <= n; i++) if (0 <= distance[i] < min) { min = distance[i]; vnear = i; } e = edge(vnear, nearest[vnear]); add e to F; distance[vnear] = -1; for (i=2; i <= n; i++) if (W[i][vnear] < distance[i]) { distance[i] = W[i][vnear]; nearest[i] = vnear; }}}
Kruskal’i algoritm • Disjoint Sets • http://ciips.ee.uwa.edu.au/~morris/Year2/PLDS210/mst.html
Mittelõikuvad hulgad (disjoint sets) • initial (n) loob n üheelemendilist hulka • p = find (i ) annab viida hulgale, milles on i • merge (p, q) ühendab kaks hulka üheks • equal (p,q) true kui p ja q on sama hulk
Kruskal’i algoritm void kruskal(int n, int m, set_of_edges E, set_of_edges F) { index i, j; set_pointer p, q; edge e; Sort the m edges in E by weight; F = ; initial(n); while( number of edges in F is less than n-1) { e = next edge (with the least weight) from sorted E; i, j = indicies of vertices connected by e; p = find(i); q = find(j); if (! equal(p,q)) { merge(p, q); add e to F; }}}
Prim’i ja Kruskal’i keerukus • Prim T(n) = 2(n-1)(n-1) O(n2) • Kruskal Kaarte sorteerimine W(m) O(m lg m) Initsialiseerimine T(n) O(n) While loop W(m) O(m lg m) W(m, n) O(m lg m) täielikus graafis m = n(n - 1) O(n2) W(m, n) O(n2 lg n)
Dijkstra lühimate teede algoritm • Leiab lühimad teed ühest väljavalitud tipust igasse teise tippu (eeldusel, et graaf on sidus) • Sarnane Prim’i katva puu algoritmile • Keerukus O(n2)
Dijkstra algoritm - idee F = ; // kaarte hulk Y = {v1}; // tippude hulk while (pole lahendatud) { vali tipp hulgast V-Y mis on lähim v1-le kasutades ainult tippe Y-st; lisa tipp Y-le; lisa kaar F-le; if (Y == V) lahendatud; } http://carnap.ss.uci.edu/java/dijkstra/DijkstraApplet.html
Dijkstra algoritm void dijkstra (int n, const number W[][], set_of_edges& F) { index i, vnear; edge e; index touch[2...n]; number distance[2...n]; F = ; for (i=2; i <= n; i++) { touch[i] = 1; distance[i] = W[1][i]; }
Dijkstra algoritm repeat (n-1 times) { min = ; for (i=2; i <= n; i++) if (0 <= distance[i] < min) { min = distance[i]; vnear = i; } e = edge(touch[vnear], vnear); add e to F; for (i=2; i <= n; i++) if (distance[vnear]+W[vnear][i] < distance[i]) { distance[i] = distance[vnear]+W[vnear][i]; touch[i] = vnear; } distance[vnear] = -1; }}
Ahnete algoritmide tihti kasutatav struktuur Greedy (M, w) A = sorteeri S [M] kaalu w järgi for (xS [M] vastavalt järjestusele w järgi) ifA {x} I[M] thenA = A {x} returnA
Kokkuvõtteks • Ahne algoritm võimaldab efektiivselt lahendada mitmeid optimiseerimisülesandeid • Kui ülesandel on olemas ahne algoritm, siis on see üldjuhul efektiivsem kui teised algoritmid • Ahne algoritm teeb lõplikke valikuid hetkeseisust lähtudes • Ahne algoritmi kandidaadi toimimist tuleb tõestada, st näidata et lokaalsest optimaalsuskriteeriumist järeldub globaalne optimaalsus.
18 28 1 3 5 6 7 5 10 3 4 29 9 2 4 6 Kodused ülesanded • Näita samm-sammult kuidas Prim’i algoritm leiab minimaalse katva puu • Näita samm-sammult kuidas Kruskal’i algoritm leiab minimaalse katva puu • Tõesta, et ahne algoritm annab optimaalse lahenduse seljakoti murdosalise pakkimise probleemile