Differences

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

Link to this comparison view

pa:laboratoare:laborator-12 [2019/05/21 11:42]
gabriel.bercaru [A* (A star)]
pa:laboratoare:laborator-12 [2020/05/31 20:27] (current)
darius.neatu
Line 1: Line 1:
 ====== Laborator 12 : Algoritmi euristici de explorare a grafurilor. A* ====== ====== 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 =====
Line 84: Line 87:
 In cadrul algoritmului se folosesc doua multimi: closed – 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 a 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 a 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. In cadrul algoritmului se folosesc doua multimi: closed – 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 a 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 a 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.
  
-Greedy Best-First urmareste mereu solutia care pare cea mai aproape de sursa. 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.+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.
  
 In figura de mai jos se prezinta rularea algoritmului Greedy Best-First pe exemplul dat mai sus. In primul pas algoritmul expandeaza nodul Arad, iar ca nod urmator de explorat se alege Sibiu, intrucat are valoarea h(n) minima. Se 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 Bucuresti, in 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. In figura de mai jos se prezinta rularea algoritmului Greedy Best-First pe exemplul dat mai sus. In primul pas algoritmul expandeaza nodul Arad, iar ca nod urmator de explorat se alege Sibiu, intrucat are valoarea h(n) minima. Se 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 Bucuresti, in 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.
Line 108: Line 111:
  
 <code cpp> <code cpp>
-A-Star(s initial ​, expand, h, solution)+// 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  //​initializari
-    closed ← {} +    closed ← {}     // multimea nodurilor expandate 
-    n ← new-node() +    open   ​← { }    // multimea nodurilor in curs de explorare
-    state(n) ← s initial +
-    g(n) ← 0 +
-    π(n) ← nil +
-    open ← { }+
  
-    //Bucla principala +    // pentru fiecare stare s 
-    ​repeat +    ​for each s 
-        ​if open = Ø then return failure +        ​g(s) ← Infinity // initializare distante 
-        ​← get_best(open) with f(n) = g(n)+h(n= min +        π(s) ← Infinity // initializare parinti 
-        open ← open - {n+ 
-        if solution(state(n)then return ​build-path(n+    // pentru s_i avem distanta 0 si parinte NULL 
-        ​else if not in closed ​then +    g(s_i) ← 0 
-            closed ← closed U {n+    π(s_i) ← NULL 
-            for each in expand(n+    ​open   ← open U { s_i } 
-                ​cost_from_n ← g(n) + cost(state(n), ​s+ 
-                if not (s in closed U openthen +    // parcurgerea continua cat timp avem noduri in open 
-                    ​n' ← new-node() +    while !open.empty() 
-                    ​state(n') ← s +        ​// extrage nodul s cu f(s) minim 
-                    π(n') ← n +        s ← get_best(open) with minimum ​f(s) = g(s) + h(s
-                    ​g(n'← cost_from_n +        open ← open - { } 
-                    open ← open U { n'} + 
-                else +        // daca s este stare finala 
-                    n' ← get(closed U open, s) +        if is_goal(s 
-                    if cost_from_n < g(n') then +            // reconstituie drumul de la s la s_i 
-                        π(n') ← n +            ​return ​build_path(s, s_i
-                        g(n') ← cost_from_n +        ​ 
-                        if n' ​in closed ​then +        // daca nodul nu este deja expandat  
-                            closed ← closed – { n'+        ​if not in closed 
-                            open ← open U { n'+            // il adaug in closed 
-     end-for +            closed ← closed U { } 
-    ​end-repeat+ 
 +            // pentru fiecare copil c al starii s 
 +            for each in expand(s
 +                ​if g(s) + w[s][c] < g(c
 +                    ​// actualizez distanta si parintele 
 +                    ​g(c) ← g(s) + w[s][c] 
 +                    π(c) ← 
 + 
 +                    ​if not (c in closed U open// daca nodul c nu a mai fost intalnit 
 +                        open   ​← open U {   // c intra in open 
 +                    ​else if in closed ​        // daca nodul c a mai fost expandat 
 +                        closed ← closed – { // c trece din closed in open 
 +                        open   ​← open U { 
 + 
 +    ​// nu a fost gasita o cale de la s_i la o stare goal s 
 +    return failure
 </​code>​ </​code>​
  
Line 217: Line 236:
  
 ===== Probleme ===== ===== Probleme =====
 +
 +Î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}}. Pentru acest laborator vom folosi urmatorul schelet: {{pa::​laboratoare::​lab12.zip}}.
  
Line 223: Line 249:
 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ă. 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 ===== ===== Bonus =====
 ==== Problema misionarilor şi a canibalilor ==== ==== Problema misionarilor şi a canibalilor ====
Line 232: Line 259:
 a) O euristica care nu este admisibilă a) O euristica care nu este admisibilă
  
-<​hidden>​ 
 h(S) = nE(S) h(S) = nE(S)
-</​hidden>​+
  
 b) Doua euristici admisibile b) Doua euristici admisibile
  
-<​hidden>​ 
 h1(S) = nE(S)/2 h1(S) = nE(S)/2
  
Line 251: Line 276:
 nE - numar oameni est nE - numar oameni est
  
-</​hidden>​ 
  
 Comparati numarul de pasi necesar pentru a ajunge la solutie in functie de euristica Comparati numarul de pasi necesar pentru a ajunge la solutie in functie de euristica
pa/laboratoare/laborator-12.1558428146.txt.gz · Last modified: 2019/05/21 11:42 by gabriel.bercaru
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