Mesterséges intelligencia 2. laborgyakorlat Keresési módszerek A legtöbb feladatot meg lehet határozni keresési feladatként: egy ún. állapottérben, amely tartalmazza az összes lehetséges állapotot fogjuk keresni a megoldást. A keresést úgy fogjuk tekinteni mint egy keresési fa építését. Az algoritmus minden egyes lépésben valamilyen stratégia szerint kiválaszt egy levelet, amelyet kifejt, és az így kapott csúcsokat gyerekként beteszi a kifejtett csúcs alá. A fában a gyökér a kiinduló állapot, a levelek azok a csúcsok amelyek kibontásra várnak. A keresés addig tart, amíg vagy meg nem kaptuk a keresett csúcsot, vagy nincs több kibontható levél. A kibontásra váró leveleket rendszerint egy sorban tároljuk. Az a mód, ahogyan ide újabb csúcsokat teszünk be, illetve távolítunk el képezi a keresési stratégia lényegét. Minden keresési módszernél a következő tulajdonságokat kell figyelembe venni: 1. teljesség - a stratégia megtalálja-e a megoldást? 2. időigény 3. tárigény 4. optimalitás - ha több megoldás van, akkor a legjobbat adja-e vissza? Nem informált (vak - blind) keresési módszerek Ebben az esetben semmiféle információnk nincs az aktuális állapotból a célállapotba vezető út lépésszámáról, vagy útköltségéről. Az ilyen keresési algoritmusok csak arra képesek, hogy meg tudják különböztetni a célállapotokat a nem célállapotoktól. Szélességi keresés 1 NODE * breadth_first_search(node * root) 7 NODE * act = QUEUE_pop_front(queue);
Tulajdonságok: teljes, exponenciális memóriaigény, exponenciális időigény. Egyenletes költségű keresés Az egyenletes költségű keresés (EKK) a szélességi keresés módosított változata. Az EKK nem a legelső elemet veszi ki a kibontásra váró csúcsok sorából, hanem azt, amely minimizál egy g ( ) útköltség függvényt. Az útköltség függvény a gyökérből az illető csúcsig való eljutás költségét jelenti. Ha ez a költség a csúcs mélységével egyenlő, akkor visszakapjuk a szélességi keresést. 1 NODE * uniform_cost_search(node * root) 7 NODE * act = QUEUE_pop_min(queue, g); Tulajdonságok: bizonyos feltételek mellett (g (child i (X )) g (X ) i ) optimális, exponenciális tárigény, exponenciális időigény. Mélységi keresés 1 NODE * depth_first_search(node * root) 4 QUEUE_push_front(queue, root); 7 NODE * act = QUEUE_pop_front(queue); 14 QUEUE_push_front(queue, NODE_next_child(act)); Tulajdonságok: lineáris memóriaigény, exponenciális időigény.
Mélységkorlátozott keresés 1 NODE * depth_limited_search(node * root, int max_depth) 4 QUEUE_push_front(queue, root); 5 int depth = 1; 6 while(!queue_is_empty(queue)) 7 { 8 NODE * act = QUEUE_pop_front(queue); 9 if (is_solution(act)) 10 { 11 QUEUE_free(queue); 12 return act; 13 } 14 if (NODE_is_last_child(act)) depth--; 15 if (depth < max_depth) 1 17 while(node_has_more_child(act)) 18 QUEUE_push_front(queue, NODE_next_child(act)); 19 depth++; 20 } 21 } 22 QUEUE_free(queue); 23 return NULL; 24 } Tulajdonságok: nem teljes, nem optimális, lineáris memóriaigény, exponenciális időigény. Iteratívan mélyülő keresés 1 NODE * iterative_deepening_search(node * root) 3 int i; 4 NODE * res; 5 for (i = 0; i < INFINITY; i++) 6 if (res = depth_limited_search(root, i)) return res; 7 } Tulajdonságok: nem optimális, bizonyos feltételek mellett teljes, lineáris memóriaigény, exponenciális időigény. Informált keresési módszerek Ebben az esetben problémaspecifikus információkat is figyelembe veszünk. Mohó módszer Legyen h(n) egy olyan függvény, amely megbecsüli egy n állapotnak a célállapotba vezető út költségét. A kifejtésre váró csomópontok közül azt választjuk ki mindig, amelyre a h minimális. Megkötés: h(n) = 0, ha n egy célállapot.
Mohó keresés 1 NODE * greedy_search(node * root) 7 NODE * act = QUEUE_pop_min(queue, h); A* algoritmus Az A* algoritmus ötvözi az egyenletes költségű keresés és a mohó módszer előnyeit. Az egyenletes költségű keresés teljes, és optimális, a mohó módszer pedig a becsült távolságot minimizálja. Legyen g (n) az a függvény, amely a start állapotból az n állapotig tartó út valódi költségét adja meg h(n) egy olyan heurisztikus függvény, amely megbecsüli az n állapotnak a célállapotba vezető út költségét. f (n) = g (n) + h(n) Az A* algoritmus egy legjobbat először típusú keresés, ahol a csomópontok közül azt választjuk ki mindig, amelyre f minimális. Az A* a legjobb megoldást találja meg, feltéve, hogy h nem ad pesszimista becslést. Ezt elfogadható heurisztikának hívják. A heurisztikus függvénnyel kontrollálhatjuk az A* viselkedését: ha h(n) = 0, akkor csak g (n) játszik szerepet, tehát visszakapjuk az egyenletes költségű keresést ha h(n) mindig kisebb vagy egyenlő mint n-ből a célba vezető optimális út valódi költsége (h elfogadható heurisztika), akkor A* garantáltan megtalálja a legrövidebb utat ha h(n) pontosan egyenő az n-ből a célba vezető optimális út költségével, akkor A* csak a legrövidebb úton levő csomópontokat fogja kibontani, ezért rendkívül gyors lesz ha h(n) nagyobb mint a mint n-ből a célba vezető optimális út valódi költsége, akkor az A* nem biztos, hogy a legrövidebb utat találja meg ha h(n) g (n), akkor csak a heurisztikus függvény fog szerepet játszani a keresésben, és A* visszaalakul mohó kereséssé. Heurisztikák rácsszerkezetű állapotterekre: Manhattan távolság: h(n) := λ(abs(n.x cél.x) + abs(n.y cél.y)) Euklideszi távolság: h(n) := λ (n.x cél.x) 2 + (n.y cél.y) 2
1 Initialize OPEN list 2 Initialize CLOSED list 3 Create goal node; call it node_goal 4 Create start node; call it node_start 5 Add node_start to the OPEN list 6 while the OPEN list is not empty 7 { 8 Get node n off the OPEN list with the lowest f(n) 9 Add n to the CLOSED list 10 if n is the same as node_goal 11 then return Solution(n) 12 13 Generate each successor node n of n 14 for each successor node n of n 15 { 16 Set the parent of n to n 17 Set h(n ) to be the heuristically estimate distance to node_goal 18 Set g(n ) to be g(n) plus the cost to get to n from n 19 Set f(n ) to be g(n ) plus h(n ) 20 if n is on the OPEN list and the existing one is as good or better 21 then discard n and continue 22 23 if n is on the CLOSED list and the existing one is as good or better 24 then discard n and continue 25 26 Remove occurrences of n from OPEN and CLOSED 27 Add n to the OPEN list 28 } 29 } 30 31 return failure Feladatok 1. Az A* algoritmust használva oldja meg a 8-as (n-es) kirakójátékot. GUI nem szükséges. Beküldési határidő: március 17, 23:59. 2. EC +1 pont. Módosítsa a rabló-pandúr játékot úgy, hogy a pályán véletlenszerű akadályokat helyez el, és a rendőrök stratégiájának részét képezi az A* algoritmus. Könyvészet 1. Russel&Norvig Mesterséges intelligencia modern megközelítésben 2. http://theory.stanford.edu/~amitp/gameprogramming/astarcomparison.html#s3 3. http://www.briangrinstead.com/files/astar/