Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pa:laboratoare:laborator-12 [2013/05/17 03:30]
andrei.sfrent [K-means++]
pa:laboratoare:laborator-12 [2020/05/31 20:27] (current)
darius.neatu
Line 1: Line 1:
-====== Laborator 12 : Algoritmi ​aleatori ​======+====== Laborator 12 : Algoritmi ​euristici de explorare a grafurilor. A* ====== 
 +Responsabili:​ 
 +  * [[neatudarius@gmail.com|Darius Neațu]] 
 +  * [[stefanpopa2209@gmail.com | Ștefan Popa]]
  
 ===== Obiective laborator ===== ===== Obiective laborator =====
  
-  *Înțelegerea noțiunilor ​de bază legate de algoritmii aleatori – Algoritmi Las Vegas și Monte Carlo; +In cadrul acestui laborator se va discuta despre modelarea problemelor sub forma grafurilor ​de stari si despre ​algoritmi ​specializati in gasirea solutiilor pentru acest tip de grafuri. De asemenea, se vor discuta modalitatile care pot fi folosite in analiza complexitatii si pe baza acestor metode se vor prezenta avantajele si limitarile acestei clase de algoritmi.
-  *Familiarizarea cu rezolvarea folosind ​algoritmi ​aleatori a problemelor clasice; +
-  *Diversificarea perspectivei ​de analiză și rezolvare a problemelor.+
  
-===== Aplicații practice =====+===== Importanţă – aplicaţii practice =====
  
-Algoritmii ​aleatori se împart în principal în 2 clase:+Algoritmii ​de cautare euristica sunt folositi in cazurile care implica gasirea unor solutii pentru probleme pentru care fie nu exista un model matematic de rezolvare directa, fie acest model este prea complicat pentru a fi implementat. In acest caz e necesara o explorare a spatiului starilor problemei pentru gasirea unui raspuns. Intrucat o mare parte dintre problemele din viata reala pornesc de la aceste premise, gama de aplicatii a algoritmilor euristici este destul de larga. Proiectarea agentilor inteligenti [1], probleme de planificare,​ proiectare circuitelor VLSI [3], robotica, cautare web, algoritmi de aproximare pentru probleme NP-Complete [10], teoria jocurilor ​ sunt doar cateva dintre domeniile in care cautarea informata este utilizata.
  
-  *Algoritmi care rezolvă probleme de optim: soluția calculată de algoritm este garantat corectă, dar este aproximativă (nu este optimală). În acest caz, soluția suboptimală este considerată acceptabilă având o marjă de aproximare controlată probabilistic – **algoritmi de aproximare, algoritmi genetici șalgoritmi aleatori de tip Las Vegas**; +===== Descrierea problemei şrezolvărilor =====
-  *Algoritmi care rezolvă ​o problema ce acceptă o singură soluție: se renunță la exactitatea rezolvării preferându-se o soluție rapidă care se apropie cu o probabilitatea suficient de mare de soluția exactă – corectitudinea **nu** este garantată – **algoritmi aleatori de tip Monte Carlo și stocastici (Markov)**.+
  
-Printre implicațiile practice ale algoritmilor aleatori se numără:+==== Prezentare generală a problemei ====
  
-  *optimizarea diverșilor ​algoritmi, în general în vederea asigurării dispersiei corespunzătoare ​valorilor;​ +Primul pas in rezolvarea unei probleme folosind ​algoritmi ​euristici de explorare este definirea exacta ​problemei, prin tuplul ​(Si, O, Sf– stare initiala, operatori, stari finaleIncercam sa cunoastem urmatorii parametri:
-  *diverse inițializări ​(ex. Algoritmi Genetici pentru indivizisau selecții de date după o distribuție prestabilită (în general Gaussiană);​ +
-  *reducerea complexității unor probleme specifice.+
  
-===== Descrierea ​problemei ​și rezolvărilor =====+  ***Starea initiala a problemei** – reprezinta configuratia de plecare. 
 +  ***Functie de expandare ​nodurilor** – in cazul general este o lista de perechi (actiune, stare_rezultat). Astfel, pentru fiecare stare se enumera toate actiunile posibile precum si starea care va rezulta in urma aplicarii respectivei actiuni.  
 +  ***Predicat pentru starea finala** – functie care intoarce adevarat daca o stare este stare scop si fals altfel 
 +  ***Functie de cost** – atribuie o valoare numerica fiecarei cai generate in procesul de explorare. De obicei se foloseste o functie de cost pentru fiecare actiune/​tranzitie,​ atribuind, astfel, o valoare fiecarui arc din graful starilor.
  
-Primele aspecte care trebuie clarificate sunt caracteristicile ​algoritmilor ​aleatori:+In functie de reprezentarea problemei, sarcina ​algoritmilor ​de cautare este de a gasi o cale din starea initiala intr-o stare scop. Daca algoritmul gaseste o solutie atunci cand multimea solutiilor este nevida spunem ca algoritmul este complet. Daca algoritmul gaseste si calea de cost minim catre starea finala spunem ca algoritmul este optim.
  
-  *necesitatea micșorării timpului de rezolvare a problemei prin relaxarea restricțiile impuse soluțiilor;​ +In principiu, orice algoritm pe grafuri discutat in laboratoarele si cursurile anterioare ​poate fi utilizat pentru gasirea solutiei unei probleme astfel definite. In practica, insa, multi dintre acesti algoritmi nu sunt utilizati in acest context, fie pentru ca exploreaza mult prea multe noduri, fie pentru ca nu garanteaza ​solutie pentru grafuri definite implicit (prin stare initiala si functie ​de expandare).
-  *este suficientă o singură soluție care se apropie cu o probabilitate măsurabilă de soluția exactă; +
-  *în final se poate obține ​soluție suboptimală cu o marjă ​de eroare garantată prin calcul probabilistic.+
  
-Generatorul ​de numere aleatorii se află la baza construcției și funcționării algoritmilor aleatori. Astfelpentru rulări diferite există șansa ca algoritmul să se comporte diferite, chiar dacă datele ​de intrare, respectiv rezultatele sunt aceleașiAstfelpentru același set de date de intrare, algoritmii familiei se comportă diferit, chiar dacă rezultatele sunt aceleași.+Algoritmii euristici ​de cautare sunt algoritmi care lucreaza pe grafuri definite ca mai sus si care folosesc o informatie suplimentaranecontinuta in definirea problemei, prin care se accelereaza procesul ​de gasirea a unei solutii. 
 +In cadrul explorarii starilor fiecare algoritm genereaza un arborecare in radacina va contine starea initialaFiecare nod al arborelui va contine urmatorele informatii:
  
-==== Algoritmi Las Vegas ==== +  - **Starea continuta** - stare(nod) 
-     +  - **Parintele nodului** – π(nod) 
-**Caracteristici:​**+  ​- ​**Cost cale** – costul drumului de la starea initiala pana la nod – g(nod)
  
-  *Determină soluția corectă a problemeiînsă timpul ​de rezolvare nu poate fi determinat ​cu exactitate;​ +De asemeneapentru fiecare nod definim si o functie ​de evaluare **f** care indica cat de promitator este un nod in perspectiva gasirii unui drum catre solutie. (De obicei, ​cu cat **f** este mai mic, cu atat nodul este mai promitator). 
-  ​*Creșterea timpului ​de rezolvare implică creșterea probabilității ​de terminare a algoritmului;​ +Am mentionat mai sus ca algoritmii ​de cautare euristica utilizeaza o informatie suplimentara referitoare la gasirea solutiei problemei. Aceasta informatie este reprezentata ​de o functie ​**h**, unde h(nod) reprezinta drumul estimat ​de la nod la cea mai apropiata stare solutieFunctia h poate fi definita in orice mod, existand o singura constrangere:​
-  ​*După un timp infinit se ajunge la soluția optimă și algoritmul se termină sigur; +
-  ​*Probabilitatea ​de găsire a soluției crește extrem de repede încât să se determine soluția corectă într-un timp suficient de scurt.+
  
-**Complexitate teoretică:​** + h(n)=0 pt ∀n,solutie(n)=adevarat ​
- +
- f(n)=O(g(n)) daca ∃c>0, n0 > 0 a.i.:  +
- +
-  *∀n>n0 0 < f(n) < cαg(n) cu o probabilitate de cel puțin 1 - n<​sup>​-α</​sup>​ , α fixat și suficient de mare.+
    
-**Implicații:​**+==== Algoritmi de cautare informata ====
  
-Procentul algoritmilor Las Vegas care consumă cel mult cαg(nresurse de calcul ​din totalul unei familii ​de algoritmi de complexitate O(g(n)) este 1 - n<​sup>​-α</​sup>​Pentru α suficient ​de mare există șanse foarte mici să se folosească un algoritm al familiei care nu respectă limita de complexitate.+Intrucat functioneaza prin alegerea, la fiecare pas, a nodului pentru ​care f(nodeste minim, algoritmii prezentati mai jos fac parte din clasa algoritmilor ​de cautare informata ​(nodul cel mai promitator ​este explorat mereu primul)Best-First tine cont doar de istoric (informatii sigure), pe cand A* estimeaza costul pana la gasirea unei solutii. 
 +De notat ca BFS si DFS (desi sunt algoritmi de cautare neinformata) sunt particularizari ale Best-First: ​
  
-**Problemă:**+  ​*pentru BFS: f = adancime (S) 
 +  ​*pentru DFSf = - adancime (S)
  
-  *Capitolele unei cărți sunt stocate într-un fișier text sub forma unei secvențe nevide de linii; +Vom prezenta in continuare cativa dintre cei mai importanti algoritmi ​de cautare euristica. Vom folosi pentru exemplificare,​ urmatoarea problema: data fiind harta rutiera a Romanieisa se gaseasca o cale (de preferinta ​de cost minimintre Arad si Bucuresti
-  *Fiecare secvență este precedată ​de o linie contor ce indică numărul de linii din secvențăiar specificul indică fiecare astfel ​de secvență este lungă; +
-  *Fiecare linie din fișier este terminată prin CR,LF; +
-  *Toate liniile din secvență au aceeași lungime; +
-  *Fiecare secvență ​de linii conține o linie (titlul capitoluluice se repetă și care apare în cel puțin q = 10% din numărul de linii al secvenței.+
  
-**Cerință:​**+Pentru aceasta problema starea initiala indica faptul ca ne aflam in orasul Arad, starea finala este data de predicatul Oras_curent == Bucuresti, functia de expandare intoarce toate orasele in care putem ajunge dintr-un oras dat, iar functia de cost indica numarul de km al fiecarui drum intre doua orase, presupunand ca viteza de deplasare este constanta. Ca euristica vom utiliza pentru fiecare oras distanta geometrica(in linie dreapta) pana la Bucuresti.
  
-  *Pentru fiecare secvență de linii să se tipărească titlul capitolului (linia care se repetă). +{{ :pa:​laboratoare:​111.png?​400 |}}
-Complexitate variantă iterativăO(n<​sup>​2</​sup>​) în cazul cel mai defavorabil+
  
-**Rezolvare aleatoare:​**+==== Greedy Best-First ====
  
 +In cazul acestui algoritm se considera ca nodul care merita sa fie expandat in pasul urmator este cel mai apropiat de solutie. Deci, in acest caz, avem:
 + 
 + f(n) = h(n), pt. oricare n
 +
 + Pseudocodul acestui algoritm:
 <code cpp> <code cpp>
-selectie_linii(n,Secv// Pp n = dim secv > 100 + 
-    ​while (1+Greedy Best-First(sinitial ​expand, h, solution
-        i = random(0,n-1// selectez o linie +    ​closed ← {} 
-        j = random(0,n-1) // si inca una +    n ← new-node() 
-        if (i !j && linie(i,Secv) = linie(j,Secv)) // le compar +    state(n) ← sinitial 
-            ​return linie(i,Secv// am gasit linia+    π(n) ← nil 
 +    open ← { n } 
 +    ​// Bucla principala 
 +    repeat 
 +        if open = Ø then return failure 
 +        n ← get_best(open) with f(n) h(n) = min 
 +        open ← open - {n} 
 +        if solution(state(n)) then return build-path(n) 
 +        else if n not in closed then 
 +            ​closed ← closed U {n} 
 +            for each s in expand(n) 
 +                n' ← new-node() 
 +                state(n'​) ← s 
 +                π(n') ← n 
 +                open ← open U {n'} 
 +            end-for 
 +    end-repeat
 </​code>​ </​code>​
  
-Complexitate variantă aleatoareO(lg<​sup>​-1</​sup>​(1/​a)lg(n))=O(lg(n)), unde = 1 - q(q-1)/10000, q=10 – probabilitatea de regăsire ​titlului capitolului.+In cadrul algoritmului se folosesc doua multimiclosed – indica nodurile deja explorate si expandate si open – nodurile descoperite dar neexpandate. Open este intializata cu nodul corespunzator starii intiale. La fiecare pas al algoritmului este ales din open nodul cu valoarea ​   f(n) = h(n) cea mai mica (din acest motiv e de preferat ca open  sa fie implementata ca o coada cu prioritati). Daca nodul se dovedeste ​fi o solutie a problemei atunci este intoarsa ca rezultat calea de la starea initiala pana la nod (mergand recursiv din parinte in parinte). Daca nodul nu fost deja explorat atunci se expandeaza iar nodurile corespunzatoare starilor rezultate sunt introduse in multimea open. Daca multimea open ramane fara elemente atunci nu exista niciun drum catre solutie si algoritmul intoarce esec.
  
-**Observații:​**+Greedy Best-First urmareste mereu solutia care pare cea mai aproape de destinatie. Din acest motiv nu se vor analiza stari care desi par mai departate de solutie produc o cale catre solutie mai scurta (vezi exemplul de rulare). De asemenea, intrucat nodurile din closed nu sunt niciodata reexplorate se va gasi calea cea mai scurta catre scop doar daca se intampla ca aceasta cale sa fie analizata inaintea altor cai catre aceiasi stare scop. Din acest motiv, algoritmul nu este optim. De asemenea, pentru grafuri infinite e posibil ca algoritmul sa ruleze la infinit chiar daca exista o solutie. Rezulta ca algoritmul nu indeplineste nici conditia de completitudine.
  
-De exemplu pentru n=100 și q=10%, după 3500 de iterațiiprobabilitatea ​ca soluția să fie corectă poate fi considerată 1; dacă q=30%, atunci numărul ​de iterații devine 500Aproprierea probabilității de 1 este atât de mare încât precizia de calcul cu 12 zecimale ​nu mai asigură obținerea valorii exacte șipractic, terminarea algoritmului devine certă.+In figura ​de mai jos se prezinta rularea algoritmului Greedy Best-First pe exemplul dat mai sus. In primul pas algoritmul expandeaza nodul Aradiar ca nod urmator ​de explorat se alege Sibiu, intrucat are valoarea h(n) minimaSe alege in contiuare Fagaras dupa care urmeaza Bucuresti, care este un nod final. Se observa insa ca acest drum nu este minimal. Desi Fagaras este mai aproape ca distanta geometrica de Bucurestiin momentul in care starea curenta este Sibiu alegerea optimala este Ramnicu-Valcea. In continuare ar fi urmat Pitesti si apoi Bucuresti obtinandu-se un drum cu 32 km mai scurt.
  
-Algoritmul se comportă foarte bine chiar și atunci când în condițiile teoretice nu sunt respectate întrucât avem de-a face cu numere pseudo-aleatorii și secvența de linii nu este formată aleator. + {{ :​pa:​laboratoare:​112.png?400 |}}
-  +
-==== Algoritmi Monte Carlo ====+
  
-**Caracteristici:​** 
  
-  ​*Determină o soluție a problemei care e garantat corectă doar după un timp infinit de rezolvare – soluție aproximativă;​ +==== A* (A star====
-  *Presupun un număr finit de iterații după care răspunsul nu este garantat corect; +
-  *Creșterea timpului de rezolvare implică creșterea probabilității ca soluția găsită să fie corectă; +
-  *Soluția găsită într-un timp acceptabil este aproape sigur corectă ​(există o probabilitate mică ca soluţia să nu fie corectă).+
  
-**Complexitate teoretică:**+Areprezinta cel mai cunoscut algoritm de cautare euristica. El foloseste, de asemenea o politica Best-First, insa nu sufera de aceleasi defecte pe care le are Greedy Best-First definit mai sus. Acest lucru este realizat prin definirea functiei de evaluare astfel:
  
- f(n)=O(g(n)) daca ∃c>0n0 > 0 a.i.: + f(n) = g(n) + h(n) , ptoricare n ∈ Noduri
  
-n>n0 0 < f(n) < cαg(n) cu o probabilitate de cel puțin 1 - n<​sup>​-α</​sup>​ , α fixat și suficient de mare. +A* evalueaza nodurile combinand distanta deja parcursa pana la nod cu distanta estimata pana la cea mai apropiata stare scop. Cu alte cuvinte, pentru un nod oarecare, **f(n) reprezinta costul estimat al celei mai bune solutii care trece prin n**. Aceasta strategie se dovedeste a fi completa si optimala daca euristica h(n) este admisibila:
-  *Probabilitatea ca soluția determinată de algoritm să fie corectă ​este de cel puțin 1 - n<​sup>​-α</​sup>​.+
  
-**Implicații:​**+ 0 ≤ h(n) ≤ h*(n) , pt. oricare n ∈ Noduri
  
-Procentul algoritmilor Monte Carlo care consumă cel mult cαg(n) resurse ​de calcul din totalul unei familii de algoritmi de complexitate O(g(n))  pentru a găsi soluție corectă cu o probabilitate de cel puțin 1 - n<​sup>​-α</​sup>​ este 1 - n<​sup>​-α</​sup>​. Pentru α suficient de mare există șanse foarte mici să se folosească un algoritm al familiei care nu respectă limita de complexitate și nu se termină cu soluție corectă.+unde h*(n) este distanta exacta ​de la nodul n la cea mai apropiata solutie. Cu alte cuvinte A* intoarce mereu solutia optima daca o solutie exista atat timp cat ramanem optimisti si nu supraestimam distanta pana la solutie. Daca h(n) nu este admisibila ​solutie va fi in continuare gasita, dar nu se garanteaza optimalitatea. De asemenea, pentru a ne asigura ca vom gasi drumul optim catre solutie chiar daca acest drum nu este analizat primul, A* permite scoaterea nodurilor din closed si reintroducerea lor in open daca o cale mai buna pentru un nod din closed (g(n) mai mic) a fost gasita.
  
-**Problemă:**+Algoritmul evolueaza in felul urmator: initial se introduce in multimea open (organizata ca o coada de prioritati dupa f(n)) nodul corespunzator starii initiale. ​**La fiecare pas se extrage din open nodul cu f(n) minim**. Daca se dovedeste ca nodul n contine chiar o stare scop atunci se intoarce calea de la starea initiala pana la nodul n. Altfel, daca nodul nu a fost explorat deja se expandeaza. Pentru fiecare stare rezultata, daca nu a fost generata de alt nod inca (nu este nici in open nici in closed) atunci se introduce in open. Daca exista un nod corespunzator starii generate in open sau closed se verifica daca nu cumva nodul curent produce o cale mai scurta catre s. Daca acest lucru se intampla se seteaza nodul curent ca parinte al nodului starii s si **se corecteaza distanta g**. Aceasta corectare implica reevaluarea tuturor cailor care trec prin nodul lui s, deci acest nod va trebui reintrodus in open in cazul in care era inclus in closed. ​
  
-  ​*Testarea dacă un număr dat n este prim.+Pseudocodul pentru A* este prezentat in continuare:
  
-Complexitate variantă clasică: O(n)=O(<​sup>​k/2</sup>​) ​ unde k nr. de biți ocupați de n+<code cpp> 
 +// s_i      = stare initiala 
 +// expand ​  = functie de expandare care returneaza toti succesorii unei stari 
 +// h        = functie euristica (h(n) = aproximarea drumului minim de la n la o destinatie) 
 +// is_goal ​ ​= ​is_goal(n) returneaza true daca n este o destinatie (stare goal/​finala) 
 +// w        = w[x][y] reprezinta costul muchiei directe intre starile x si y 
 +A*(s_i, expand, h, is_goal) 
 + //​initializari 
 +    closed ← {}     // multimea nodurilor expandate 
 +    open   ← { }    // multimea nodurilor in curs de explorare
  
-Rezolvare aleatoare folosind teorema lui Fermat ​(Dacă n este prim atunci pentu ∀ 0 < x < n, x<​sup>​n-1<​/sup> mod n = 1):+    // pentru fiecare stare s 
 +    for each s 
 +        g(s) ← Infinity ​// initializare distante 
 +        π(s← Infinity // initializare parinti
  
-<code cpp> +    ​// pentru s_i avem distanta ​si parinte NULL 
-prim1(n,​α) ​// detectează daca n e număr prim +    ​g(s_i← 
-    if (n <= 1 || n mod 2 == 0) return false +    ​π(s_i← NULL 
-    ​limit = limita_calcul(n,α//nr min pași pt sol corectă cu P=1-n^-α +    ​open   ← open U { s_i }
-    for (i = ; i < limit ; i++) +
-        x = random(1,​n-1) // aleg un număr oarecare  +
-        if (pow_mod(x,​n) != 1) return false // T. Fermat +
-    ​return true +
-  +
-pow_mod(x,n// calculează xn-1 mod n +
-    ​r = 1 +
-    for (m = n – 1 ; m > 0 ; m = m / 2) +
-        if (m mod 2 != 0) // testez daca m e par sau nu +
-            r = x*r mod n  +
-        x = (x*x) mod n +
-    return r; +
-</​code>​+
  
-Problema acestei abordări constă în faptul că nu putem stabili cu exactitate care este limita de calcul.+    // parcurgerea continua cat timp avem noduri in open 
 +    while !open.empty() 
 +        // extrage nodul s cu f(s) minim 
 +        s ← get_best(open) with minimum f(s) = g(s) + h(s) 
 +        open ← open - { s }
  
-Pornind de la următoarea teoremă: Pentru orice număr prim ecuația x<​sup>​2<​/sup> mod n = 1 are exact 2 soluții: x<​sub>​1<​/sub> egal 1 și x<​sub>​2<​/sub> egal n – 1obținem următoarea definiție pentru X = martor al divizibilității lui n : Fie n > 1 și 0 < x < n două numere astfel încât x<​sup>​n-1<​/sup> mod n != 1 sau x<​sup>​2<​/sup> mod n != 1, x != 1 si x != n – 1.+        ​// daca s este stare finala 
 +        if is_goal(s)  
 +            ​// reconstituie drumul de la s la s_i 
 +            return build_path(ss_i) 
 +         
 +        ​// daca nodul nu este deja expandat  
 +        if s not in closed 
 +            // il adaug in closed 
 +            closed ← closed U { s }
  
-<code cpp> +            // pentru fiecare copil c al starii s 
-prim2(n,α+            for each c in expand(s
-    if(<= 1 || n mod 2 == 0) return false +                if g(s) + w[s][c] ​g(c
-    limit = limita_calcul(n,α+                    // actualizez distanta si parintele 
-    ​for ​(i = 0 ; i < limit ; i++) +                    g(c← g(s+ w[s][c] 
-        x = random(1, n-1+                    π(c← s 
-    ​if ​(martor_div(x,​n)) return false + 
-    ​return true; +                    if not (c in closed U open) // daca nodul c nu a mai fost intalnit 
-     +                        ​open ​  ← open U { c }   // c intra in open 
-martor_div(x,n) // determina ​daca X=martor al divizibilitatii lui n +                    ​else ​if c in closed ​        // daca nodul c a mai fost expandat 
-    r = 1; y = x; +                        ​closed ← closed – { c } // c trece din closed in open 
-    for(m = n – 1 ; m > 0 ; m = m 2) // puterea ​ +                        ​open ​  ← open U { c } 
-        if (m mod 2 != 0) // putere impara ​ + 
-            r = y * r mod n +    ​// nu a fost gasita o cale de la s_i la o stare goal s 
-        z = y // salvez valoarea lui y +    return ​failure
-        y = y * y mod n // calculez y2 mod n +
-        if (y == 1 && z != 1 && z != n-1)//verific teorema anterioară +
-            return 1 +
-    return ​r != 1 // teorema Fermat+
 </​code>​ </​code>​
  
-Complexitate:​ O(lg<​sup>​2</​sup>​n)=O(k<​sup>​2</​sup>​)+Algoritmul prezentat mai sus va intoarce calea optima catre solutie, daca o solutie exista. Singurul incovenient fata de Greedy Best-First este ca sunt necesare reevaluarile nodurilor din closed. Si aceasta problema poate fi rezolvata daca impunem o conditie mai tare asupra euristicii h, si anume ca euristica sa fie **consistenta** (sau **monotona**):​ 
 + 
 + h(n) ≤ h(n') + cost(n,​n'​) , pt. oricare n' ∈ expand(n) 
 +  
 +Daca o functie este consistenta atunci ea este si admisibila. Daca euristica h indeplineste si aceasta conditie atunci algoritmul A* este asemanator cu Greedy Best-First cu modificarea ca functia de evaluare este f = g + h, in loc de f = h. 
 +In imaginea de mai jos se prezinta rularea algoritmului pe exemplul laboratorului. Se observa ca euristica aleasa (distanta in linie dreapta) este consistenta si deci admisibila. Se observa ca in pasul (e), dupa expandarea nodului Fagaras desi exista o solutie in multimea open aceasta nu este aleasa pentru explorare. Se va alege Pitesti, intrucat f(nod(Bucuresti)) = 450 > f(nod(Pitesti)) = 417, semnificatia acestei ​ inegalitati fiind ca e posibil sa existe prin Pitesti un drum mai bun catre Bucuresti decat cel descoperit pana acum. 
 +  
 +{{ :​pa:​laboratoare:​113.png?​400 |}} 
 + 
 +==== Complexitate ​algoritmului A* ==== 
 + 
 +Pe langa proprietatile de completitudine si optimalitate A* mai are o calitate care il face atragatorpentru o euristica data orice algoritm de cautare complet si optim va explora cel putin la fel de multe noduri ca A*, ceea ce inseamna ca A* este optimal din punctul de vedere al eficientei. In practica, insa, A* poate fi de multe ori imposibil de rulat datorita dimensiunii prea mari a spatiului de cautare. Singura modalitate prin care spatiul de cautare poate fi redus este prin gasirea unei euristici foarte bune – cu cat euristica este mai apropiata de distanta reala fata de stare solutie cu atat spatiul de cautare este mai strans (vezi figura de mai jos). S-a demonstrat ca spatiul de cautare incepe sa creasca exponential daca eroarea euristicii fata de distanta reala pana la solutie nu are o crestere subexponentiala:​ 
 + 
 + |h(n) - h*(n)| ≤ O(logh*(n)
 + 
 +Din pacate, in majoritatea cazurilor, eroarea creste liniar cu distanta pana la solutie ceea ce face ca A* sa devina un algoritm mare consumator de timp, dar mai ales de memorie. Intrucat in procesul de cautare se retin toate nodurile deja explorate (multimea closed), in cazul unei dimensiuni mari a spatiului de cautare cantitatea de memorie alocata cautarii este in cele din urma epuizata. Pentru acest incovenient au fost gasite mai multe solutii. Una dintre acestea este utilizarea unor euristici care sunt mai stranse de distanta reala pana la starea scop, desi nu sunt admisibile. Se obtin solutii mai rapid, dar nu se mai garanteaza optimalitatea acestora. Folosim aceasta metoda cand ne intereseaza mai mult sa gasim o solutie repede, indiferent de optimalitatea ei.  
 + 
 +{{ :​pa:​laboratoare:​114.png?​400 |}} 
 + 
 +Volumul spatiului de cautare in functie de euristica aleasa 
 + 
 +Alte abordari presupun sacrificarea timpului de executie pentru a margini spatiul de memorie utilizat [3]. Aceste alternative sunt prezentate in continuare. 
 + 
 +==== IDA*, RBFS, MA* ==== 
 + 
 +=== IDA* === 
 + 
 +Iterative deepening A* [5] utilizeaza conceptul de adancire iterativa[1][8] in procesul de explorare a nodurilor – la un anumit pas se vor explora doar noduri pentru care functia de evaluare are o valoare mai mica decat o limita data, limita care este incrementata treptat pana se gaseste o solutie. IDA* nu mai necesita utilizarea unor multimi pentru retinerea nodurilor explorate si se comporta bine in cazul in care toate actiunile au acelasi cost. Din pacate, devine ineficient in momentul in care costurile sunt variabile. 
 + 
 +=== RBFS === 
 + 
 +Recursive Best-First Search [6] functioneaza intr-un mod asemanator cu DFS, explorand la fiecare pas nodul cel mai promitator fara a retine informatii despre nodurile deja explorate. Spre deosebire de DFS, **se retine in orice moment cea mai buna alternativa sub forma unui pointer catre un nod neexplorat**. Daca valoarea functiei de evaluare ​(f = g + h) pentru nodul curent devine mai mare decat valoarea caii alternative,​ drumul curent este abandonat si se incepe explorarea nodului retinut ca alternativa. RBFS are avantajul ca spatiul de memorie creste doar liniar in raport cu lungimea caii analizate. Marele dezavantaj este ca se ajunge de cele mai multe ori la reexpandari si reexplorari repetate ale acelorasi noduri, lucru care poate fi dezavantajos mai ales daca exista multe cai prin care se ajunge la aceiasi stare sau functia expand este costisitoare computational (vezi problema deplasarii unui robot intr-un mediu real). RBFS este optimal daca euristica folosita este admisibila. 
 + 
 +=== MA* === 
 + 
 +Memory-bounded A* este o varianta a A* in care se limiteaza cantitatea de memorie folosita pentru retinerea nodurilor. Exista doua versiuni – MA* [7]si SMA* [4] (Simple Memory-Bounded A*), ambele bazandu-se pe acelasi principiu. SMA* ruleaza similar cu A* pana in momentul in care cantitatea de memorie devine insuficienta. In acest moment spatiul de memorie necesar adaugarii unui nod nou este obtinut prin stergerea celui mai putin promitator nod deja explorat. In cazul in care exista o egalitate in privinta valorii functiei de evaluare se sterge nodul cel mai vechi. Pentru a evita posibilitatea in care nodul sters este totusi un nod care conduce la o cale optimala catre solutie valoarea f a nodului sters este retinuta la nodul parinte intr-un mod asemanator felului in care in RBFS se retine cea mai buna alternativa la nodul curent. Si in acest caz vor exista reexplorari de noduri, dar acest lucru se va intampla doar cand toate caile mai promitatoare vor esua. Desi exista probleme in care aceste regenerari de noduri au o frecventa care face ca algoritmul sa devina intractabil,​ MA* si SMA* asigura un compromis bun intre timpul de executie si limitarile de memorie.
  
 ===== Concluzii și observații ===== ===== Concluzii și observații =====
  
-Metodele descrise pot fi aplicate și se adresează unei plaje largi de probleme, ​iar abordările prezentate pot duce la scăderi drastice a timpilor ​de execuție.+Deseori singura modalitate de rezolvare a problemelor dificile este de e explora graful starilor acelei probleme. Algoritmii clasici pe grafuri nu sunt intotdeauna potriviti pentru cautarea in aceste grafuri fie pentru ca nu garanteaza un rezultat fie pentru ca sunt ineficienti.  
 +Algoritmii euristici sunt algoritmi care exploreaza astfel de grafuri folosindu-se de o informatie suplimentara despre modul in care se poate ajunge la o stare scop mai rapid. A* este, teoretic, cel mai eficient algoritm de explorare euristica. In practica, insa, pentru ​probleme ​foarte dificileA* implica un consum prea mare de memorie. In acest caz se folosesc variante de algoritmi care incearca sa minimizeze consumul de memorie in defavoarea timpului ​de executie
  
-===== Referințe ​=====+===== Referinte ​=====
  
-[1] CGiumale – Introducere în Analiza Algoritmilor ​– cap. 6.1+[1] SRussel, P. Norvig - Artificial Intelligence:​ A Modern Approach - Prentice Hall, 2nd Edition ​– cap. 4
  
-[2] TH. Cormen & all – Introducere ​în algoritmi – cap. 8.3, 1990+[2] C.A Giumale ​– Introducere ​in Analiza Algoritmilor, ​cap. 7
  
-[3] [[http://​www.soe.ucsc.edu/classes/cmps102/Spring04/TantaloAsymp.pdf]]+[3] [[http://​www.cs.cmu.edu/afs/cs/project/pscico-guyb/​294/​class-notes/​all/​18.ps|Mehul Shah - Algorithms in the real world (Course Notes) -  Introduction to VLSI routing]]
  
-[4] [[http://​www.mersenne.org/]]+[4] [[http://​citeseerx.ist.psu.edu/​viewdoc/​download?​doi=10.1.1.54.6489&​rep=rep1&​type=pdf|S. Russel - Efficient memory-bounded search methods]] 
 + 
 +[5] R. Korf - Depth-first iterative-deepening:​ an optimal admissible tree search 
 + 
 +[6] [[http://​www.ailab.si/​gregorl/​Students/​mui/​Recursive%20Best-First%20Search.ppt|Recursive Best-First Search - Prezentare]] 
 + 
 +[7] P. Chakrabati, S. Ghosh, A. Acharya, S. DeSarkar – Heuristic search in restricted memory 
 + 
 +[8] [[http://​en.wikipedia.org/wiki/​Iterative_deepening_depth-first_search|Wikipedia - Iterative deepening]] 
 + 
 +[9] [[http://​dli.iiit.ac.in/​ijcai/​IJCAI-91-VOL2/​PDF/​017.pdf|A. E. Prieditis - Machine Discovery of Effective Admissible Heuristics]] 
 + 
 +[10] [[http://​en.wikipedia.org/​wiki/​Travelling_salesman_problem#​Heuristic_and_approximation_algorithms|Wikipedia - Travelling salesman problem - Heuristic and approximation algorithms]] 
 + 
 +[11] [[http://​en.wikipedia.org/​wiki/​A*_search_algorithm|Wikipedia – A*]] 
 + 
 +[12] [[http://​www.policyalmanac.org/​games/​aStarTutorial.htm|Tutorial A*]] 
 + 
 +[13] [[http://​aaaipress.org/​Papers/​AAAI/​1994/​AAAI94-209.pdf|H. Kaindl, A. Khorsand - Memory Bounded Bidirectional Search, AAAI-94 Proceedings]]
  
  
 ===== Probleme ===== ===== Probleme =====
  
-==== K-means++ ​====+În acest laborator vom rezolva o singură problemă: [[https://​www.hackerrank.com/​challenges/​pacman-astar/​problem | PACMAN]] pe hackerrank. Puteți porni implementarea pe hackerrank de la următorul schelet: {{pa:​new_pa:​skel-lab12-hr.zip | skel-lab12.zip}}. 
 + 
 + 
 +<​hidden>​ 
 + 
 + 
 +Pentru acest laborator vom folosi urmatorul schelet: {{pa::​laboratoare::​lab12.zip}}. 
 + 
 +==== Labirint ==== 
 + 
 +Fie un labirint dat sub forma unei matrici în care 0 înseamnă obstacol şi 1 înseamnă liber. Se cere să se determine un drum între două poziţii din labirint folosind algoritmi de căutare informată. Să se implementeze algoritmul A* pentru rezolvarea problemei folosind o euristică admisibilă. 
 + 
 +</​hidden>​ 
 +===== Bonus ===== 
 +==== Problema misionarilor şi a canibalilor ==== 
 + 
 +Trei misionari şi trei canibali ajung la malul estic al unui râu. Aici se află o barcă cu două locuri cu care se poate traversa râul (râul nu se poate traversa înot). Dacă pe unul dintre maluri numărul de canibali este mai mare decât numărul de misionari, atunci misionarii de pe acel mal vor fi mâncaţi de canibali. Se cere sa determinaţi cum pot trece toţi râul fără ca misionarii să fie mâncaţi de canibali. 
 + 
 +Să se rezolve această problemă folosind algoritmul A* cu: 
 + 
 +a) O euristica care nu este admisibilă 
 + 
 +h(S) nE(S) 
  
-Fie n puncte într-un spațiu bidimensional. Se dorește o grupare a acestora în k clustere - un grup de puncte situate într-o vecinătate spațială care să maximizeze coeziunea intra-cluster și să asigure o cuplare slabă inter-clustere.+b) Doua euristici admisibile
  
-Spre exemplu, pentru setul de puncte:+h1(S) = nE(S)/2
  
-''​(2, 5), (2, 9), (3, 2), (3, 3), (3, 4), (3, 10), (4, 1), (5, 1), (8, 2), (8, 3), (9, 4), (10, 5), (10, 6), (10, 7)''​+h2(S=
  
-Se poate observa o grupare naturală în 3 clustere:+* nE(S) + 1 daca barca pe malul vestic si nE(S) diferit de 0
  
-{{ :​pa:​laboratoare:​l12.jpg |}}+* nE(S) - 1 daca barca pe malul estic si nE(S) diferit de 0
  
-Coeziunea internă este determinată drept 1 / media distanțelor către clustroid (punctul din cluster cel mai apropiat de toate celelalte noduri), iar cuplarea inter-clustere este 1 / distanța dintre clustere (distanța dintre clustroizii aferenți). Pașii algoritmului k-Means sunt următorii (pentru N și k date):+* 0 altfel
  
-  ​Se selectează k puncte random din spațiu care vor fi centroizii inițiali ai clusterelor. +nE numar oameni est
-  - Se efectuează iterativ următorii pași cât timp atribuirile fiecărui nod la un cluster rămân neschimbate:​ +
-    - Asignarea fiecărui nod unui cluster (distanța minimă euclidiană către centroizii din pasul curent este minimă); +
-    - Recalcularea centroidului drept media aritmetică a coordonatelor punctelor asignate.+
  
-Pentru un set de date și un k stabilit se vor determina clusterele aferente. 
-Se va implementa și o optimizare a selecției inițiale de puncte pornind de la principiul că acestea ar trebui să fie geografic cât mai dispersate (se dorește maximizarea distanței între centroizii inițiali; mai multe detalii la [1]). 
  
-[1] http://​en.wikipedia.org/​wiki/​K-means%2B%2B#​Initialization_algorithm+Comparati numarul de pasi necesar pentru a ajunge la solutie in functie de euristica
pa/laboratoare/laborator-12.1368750619.txt.gz · Last modified: 2013/05/17 03:30 by andrei.sfrent
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0