Heurystyczne przeszukiwanie grafów w gier dwuosobowych Wykład Informatyka Studia InŜynierskie Teoria gier w dziedzinie SI Liczba graczy jednoosobowe, dwuosobowe oraz wieloosobowe Suma wypłat gry o sumie zerowej (zyski i straty uczestników bilansują się) gry o sumie niezerowej (wygrane i przegrane nie muszą się bilansować) Dostępna wiedza gry z pełną informacją (precyzyjna wiedza o sytuacji i celach przeciwnika) gry z niepełną informacją (brak wiedzy na temat przeciwnika, czynnik losowy źródłem niepewności) 1
Gry dwuosobowe - przeszukiwanie heurystyczne Dwóch przeciwników w posiadających pełną informację o stanie gry i wszystkich moŝliwych ruchach Jeden gracz nosi nazwę Max,, bo: maksymalizuje rezultat końcowy kaŝdy wzrost wartości oznacza poprawę dla tego gracza i równowar wnowaŝną stratę dla przeciwnika Drugi gracz nosi nazwę Min,, bo: imalizuje rezultat końcowy kaŝdy spadek wartości oznacza poprawę dla tego gracza i równowar wnowaŝną stratę dla przeciwnika Zasada - 5 7 9 5 9 7 7 9 3 5 2 3 9 4 1 7 2
Min- wynik! 5 7 9 5 9 7 7 9 3 5 2 3 9 4 1 7 Algorytm - wywołanie: result = MinMax(s,, MAXDEPTH, MAX) int MinMax(state s, int depth, int type) { if( is_teral_node(s) ) depth==0 ) return(eval(s)); if( type == MAX ){ best = - ; for(child=1; child<=numofsucc(s); child++) { val = MinMax(Succ(s,child), depth-1, MIN); if( val > best ) best = val; } //endfor } else { // type == MIN best = ; for(child=1; child<=numofsucc(s); child++) { val = MinMax(Succ(s,child), depth-1, MAX); if( val < best ) best = val; } //endfor } return best; } 3
Przykład - - gra NIM - korzeń MAX 7-1 6-1 -1-1 5-2 4-3 -1 MAX MIN 1 5-1-1 4-2-1-1 1 3-2-2 3-3-1-1 MAX 1-1 1 4-1-1-1 3-2-1-1 2-2-2-1 Ocena: mniejsza wartość 3-1-1-1-11 2-2-1-1-1-1 bo wygrał wygrana MIN MIN większa wartość bo wygrał wygrana MAX 2-1-1-1-1-1 1 MAX MIN MAX MIN Przykład - - gra NIM - korzeń MIN 1 7 MIN 6-11 1 5-2 1 4-3 -1 5-1-1 4-2-1 1-1 3-2-2 1 3-3-1 MAX MIN -1 1-1 4-1-1-1 3-2-1-1 2-2-2-1 Ocena: mniejsza wartość -1 3-1-1-1-1 2-2-1-1-1 1 bo wygrał wygrana MIN MAX większa wartość bo wygrał wygrana MAX 2-1-1-1-1-1-1 MIN MAX MIN MAX 4
Zasada nega 5 7 - -5-7 - -9-5 -9 - -7 9 5 9 7 (y) y = - = (x) x = - (z) 7 9 3 5 2 3 9 4 1 7 z Algorytm neg- wywołanie: result = NegMax(s,, MAXDEPTH) int NegMax(state s, int depth) { if( is_teral_node(s) ) depth==0 ) return(eval(s,depth Eval(s,depth)); ); best = - ; for(child=1; child<=numofsucc(s); child++) { val = -NegMax(Succ(s,child), depth-1); if( val > best ) best = val; } //endfor return best; } Funkcja heurystycznej oceny stanu musi uwzględnia dniać,, kto wykonywałby ruch w ocenianym stanie. JeŜeli eli gracz MAX to ocena jest w postaci prostej, jeśli gracz MIN - w postaci zanegowanej. 5
Przykład nega- - gra NIM - ruch MIN 7-1 -MIN 6-1 1 5-21 4-3 1 1 5-1-1 4-2-1-1 1 3-2-2-1 3-3-1 MAX -MIN Ocena: MIN wartość zanegowana MAX wartość prosta 4-1-1-1 -1 3-2-1-1 1 2-2-2-1 -1-1 3-1-1-1-11 przegrał MIN 2-2-1-1-1 wartość zaneg. przegrał MAX 2-1-1-1-1-1-1 wartość prosta MAX -MIN MAX Przykład nega- - gra NIM - ruch MAX 7-1 MAX 6-1 1 5-21 4-3 1 1 5-1-1 4-2-1-1 1 3-2-2-1 3-3-1 -MIN MAX Ocena: MIN wartość zanegowana MAX wartość prosta 4-1-1-1 -1 3-2-1-1 1 2-2-2-1 -1-1 3-1-1-1-11 przegrał MAX 2-2-1-1-1 wartość prosta przegrał MIN 2-1-1-1-1-1-1 wartość zanegowana -MIN MAX -MIN 6
Kółko i krzyŝyk yk - heurystyka Funkcja oceny heurystycznej stanu gry - róŝnica liczby moŝliwych wygranych gracza X i gracza O Gracz X ma 6 moŝliwych wygranych Gracz O ma 5 moŝliwych wygranych E(n) = 6-5 = 1 Gracz X ma 4 moŝliwych wygranych Gracz O ma 6 moŝliwych wygranych E(n) = 4-6 = -2 Gracz X ma 5 moŝliwych wygranych Gracz O ma 4 moŝliwych wygranych E(n) = 5-4 = 1 Kółko i krzyŝyk yk - przykład gry(1) -1 1 Ruch MAXa 1-2 6-5=1 5-5=05=0 6-5=1 5-5=05=0 4-5= 5=-1 5-4=1 6-4=2. głęg łębokość=2 5-6= 6=-1 5-5=05=0 5-6= 6=-1 6-6=06=0 4-6= 6=-2 7
. głęg łębokość=2 Kółko i krzyŝyk yk - przykład gry(2) 1 1 4-2=2 3-2=1 5-2=3 3-2=1 4-2=2 3-2=1 0 Ruch MAXa 4-3=1 3-3=03=0 5-3=2 3-3=03=0 4-3=1 4-3=1 1 0 4-2=2 4-2=2 5-2=3 3-2=1 4-2=2 4-2=2 4-3=1 4-3=1 3-3=03=0 Kółko i krzyŝyk yk - przykład gry(3) 1 1 - Ruch MAXa 2-1=1 3-1=2 2-1=1 3-1=2-2-1=1 2-1=1 2-1=1 - - - - 3-2=1 2-2=02=0 3-2=1-2-1=1 3-1=2 3-1=2. głęg łębokość=2-2-2=02=0 2-2=02=0 3-2=1
Algorytm - (lub nega) Przyjmując c określony branching factor (b)) oraz stałą głębokość przeszukiwania (d)( ZłoŜoność pamięciowa O(bd) ZłoŜoność czasowa O(b d ) Czy moŝna ten wynik poprawić? Tak! Branch&bound Ograniczenie dolne - odcięcieα 5... 5 3 5 7 3 9 odcięcie cie α... Analiza lewego poddrzewa pokazała, a, Ŝe e MAX ma ruch o wartości 5. Po sprawdzeniu lewego liścia środkowego poddrzewa widać, Ŝe e wartość drugiego ruchu będzie b mniejsza lub równa r 3 (w stanie tym decyduje MIN!). Analiza pozostałych ruchów MINa nie ma zatem sensu, gdyŝ decyzja MAXa w korzeniu grafu nie moŝe e juŝ ulec zmianie niezaleŝnie od ich wartości. 9
Ograniczenie górne g - odcięcieβ 6... 6 9 odcięcie cie β... 6 3 9 2 Analiza lewego poddrzewa pokazała, a, Ŝe e MIN ma ruch o wartości 6. Po sprawdzeniu lewego liścia środkowego poddrzewa widać, Ŝe e wartość drugiego ruchu MINa będzie większa lub równa r 9 (w stanie tym decyduje MAX!). Analiza pozostałych ruchów MAXa nie ma zatem sensu, gdyŝ decyzja MINa w korzeniu grafu nie moŝe e juŝ ulec zmianie niezaleŝnie od ich wartości. : : przykład 7 9 3 5 2 3 9 4 1 7 10
7 9 3 5 2 3 9 4 1 7 7 9 3 5 2 3 9 4 1 7 11
7 9 3 5 2 3 9 4 1 7 9 7 9 3 5 2 3 9 4 1 7 12
9 9 β 7 9 3 5 2 3 9 4 1 7 9 9 β 7 9 3 5 2 3 9 4 1 7 13
9 9 β 7 9 3 5 2 3 9 4 1 7 9 5 9 β 7 9 3 5 2 3 9 4 1 7 14
9 5 9 5 β 7 9 3 5 2 3 9 4 1 7 9 5 9 5 β 5 7 9 3 5 2 3 9 4 1 7 15
9 5 9 5 β 5 α 7 9 3 5 2 3 9 4 1 7 9 5 9 5 β 5 5 α 7 9 3 5 2 3 9 4 1 7 16
9 5 9 5 β 5 5 α 7 9 3 5 2 3 9 4 1 7 9 5 9 5 β 5 5 α 7 9 3 5 2 3 9 4 1 7 17
5 5 α 9 5 9 5 β 7 9 3 5 2 3 9 4 1 7 5 5 α 9 5 9 5 β 7 9 3 5 2 3 9 4 1 7 1
5 5 α 9 5 9 5 β α 7 9 3 5 2 3 9 4 1 7 5 5 α 9 5 9 5 β α 7 9 3 5 2 3 9 4 1 7 19
5 5 α 9 5 9 5 β α 7 9 3 5 2 3 9 4 1 7 5 5 α 9 5 9 5 β α 7 9 3 5 2 3 9 4 1 7 20
Mechanizm odcięć alfa-beta Dwa ograniczenia: α dolne ograniczenie dla wierzchołków Max (najwyŝsza wartość jaką dotychczas osiągn gnął gracz Max) β górne ograniczenie dla wierzchołków Min (najniŝsza wartość jaką dotychczas osiągn gnął gracz Min) Wartość ograniczenia α ustalana jest w wierzchołku Max,, a wartość ograniczenia β - w wierzchołku Min Odcięcie cie α wykonywane jest w wierzchołku Min, a odcięcie cie β - w wierzchołku Max Kiedy tylko zachodzi warunek α β, nie ma potrzeby analizowania dalszych następnik pników w danego stanu Algorytm AlfaBeta (zapis -) ) wywołanie: result = AlphaBeta(s, MAXDEPTH, -,, MAX) int AlphaBeta(state s,int depth,int alpha,int beta,int type) { if( is_teral_node(s) depth == 0 ) return(eval(s)); if( type == MAX){ for(child=1; child<=numofsucc(s); child++) { val = AlphaBeta(Succ(s,child),depth-1, 1,alpha,beta,,beta,MIN); alpha = (val val,, alpha); if( alpha >= beta ) return beta; //cutoff } //endfor return alpha; } else { // type == MIN for(child=1; child<=numofsucc(s); child++) { val = AlphaBeta(Succ(s,child),depth-1,alpha, 1,alpha,beta,MAX); beta = (val val,, beta); if( alpha >= beta ) return alpha; //cutoff } //endfor return beta; } } 21
C 3 3 = 3 2 = 3 3 3 = 3 0 A 3 D 0 E 0 α 2 5 = 0 = 2 B 5 0 2 β 2 2 α 2 3 5 9 0 5 3 2 1 1 7 A ma próg β = 3 (A nie będzie b większe niŝ 3) B odcięcie cie dla β,, bo 5 > 3 C ma próg α = 3 (C nie będzie b mniejsze niŝ 3) D odcięcie cie dla α,, bo 0 < 3 E odcięcie cie dla α,, bo 2 < 3 C ma wartość 3 Sformułowanie owanie neg- dla AlfaBeta Sformułowanie owanie - wymaga przemiennych wywołań rekurencyjnych dwóch graczy (raz dla gracza MAX, dwa dla gracza MIN, itd.) Sformułowanie owanie neg- opiera się tylko na graczu MAX (jedna funkcja rekurencyjna) Przy wyjściu z rekurencji negujemy zwracaną wartość Czy to wystarczy? Nie! Przy zagnieŝdŝeniu eniu rekurencyjnym w wersji neg- negujemy ograniczenia i zamieniamy miejscami 22
Algorytm AlfaBeta (zapis neg-) wywołanie: result = AlphaBeta(s, MAXDEPTH, -, ) int AlphaBeta(state s, int depth, int alpha, int beta) { if( is_teral teral_node(s) depth==0 ) return(eval Eval(s, (s,depth)); for(child=1; child<=numofsucc(s); child++) { val = -AlphaBeta(Succ(s,child),depth-1, 1,-beta,-alpha); if( val > alpha ) alpha = val; // alpha=(val,alpha); if( alpha >= beta ) return beta; // cutoff } //endfor return alpha; } Cechy algorytmu AlfaBeta ŚcieŜka krytyczna (ang. principal variation) ścieŝka w grafie przeszukiwania od korzenia do najlepszego liścia Wartości zwracane: w wersji : : ze względu na gracza w korzeniu w wersji neg- : : ze względu na tego czyj jest ruch w liściu Bardzo zawikłany any kod ewentualny błęb łędy pozostają długo ukryte (problemy moŝna zauwaŝyć tylko wtedy, gdy niepoprawne wartości zostaną przepropagowane do korzenia grafu) Efektywność algorytmu zaleŝy y w ogromnym stopniu od kolejności następnik pników w i występowania odcięć 23
Analiza algorytmu AlfaBeta Sytuacja idealna jeśli odcięcie cie ma się pojawić,, to powinno wystąpi pić jak najszybciej, czyli najlepiej zaraz po sprawdzeniu pierwszego następnika 5 5 5 3 5 7 3 9 odcięcie cie α 5 9 5 7 9 3? zmieniona kolejność (mniej odcięć ęć!) = = = 9 3 = 9 9 = 5 5 3? 5 = 9 = 5 = 9 5 α? 7 3 9 3 9 5 2 4 1 7 zmieniona kolejność 24
ZłoŜoność algorytmu AlfaBeta Dla danej głęg łębokości (d)( ) i stałego braching factor (b) Najlepszy przypadek: O(b d/2 ) Najgorszy przypadek: brak odcięć (czyli jak MinMax) Średni przypadek: O(( ((b/log b) b d ) Słabości algorytmu AlfaBeta Efekt horyzontu (ang. horizont effect) Niewidoczny spadek wartości stanu tuŝ za wyznaczoną głębokością przeszukiwania Występuje we wszystkich odmianach algorytmu Wykrywanie stanów w naraŝonych na wystąpienie efektu horyzontu i prowadzenia przeszukiwania za tym stanami - problem otwarty 25
Rozszerzenia algorytmu AlfaBeta Doskonalenie funkcji oceny stanu (funkcji heurystycznej) Modyfikacje sposobu przeszukiwania grafu zastosowanie pamięci (np. tablica przejść ść) porządkowanie następnik pników manipulowanie zakresem α-β zmienna głęg łębokość przeszukiwania przeszukiwanie eksploracyjne Rozwiązania zania sprzętowe (np. obliczenia równolegr wnoległe) e) Wariant fail-soft algorytmu AlfaBeta Klasyczna postać algorytmu wartości zwracane zawsze z przedziału u [α,[ β] Wariant fail-soft algorytmu AlfaBeta [Fishburn 1] zwraca dowolne wartości niezaleŝnie od początkowego zakresu [α,[ β] Wariant fail-soft algorytmu AlfaBeta stanowi podstawę do wszelkich jego modyfikacji, wykorzystujących manipulacje zakresem [α, β] 26
Algorytm AlfaBeta fail-soft (zapis neg-) wywołanie: result = AlphaBetaFS FS(s, MAXDEPTH, -, ) int AlphaBetaFS FS(state s, int depth, int alpha, int beta) { if( is_teral teral_node(s) depth==0 ) return(eval Eval(s)); best = - ; for(child=1; child<=numofsucc(s); child++) { val = -AlphaBetaFS(Succ(s,child),depth-1, 1,-beta, beta,-alpha); alpha); if( val > best ) best = val; if( best >= beta ) break; // cutoff if( best > alpha) alpha = best; } //endfor return best; } Znaczenie zakresu α-β ZałóŜmy, Ŝe e dla wierzchołka n o faktycznej wartości f procedura AlfaBetaFS(n (n, α, β) zwraca wartość g. MoŜemy wyróŝni nić trzy następuj pujące sytuacje: α < g < β (sukces) g jest równe r faktycznej wartości f g α (failing low) g jest górnym ograniczeniem dla f (oznaczane jako f + ), tzn. f g g β(failing high) - g jest dolnym ograniczeniem dla f (oznaczane jako f ), tzn. f g 27
Zakresy α-β: : sytuacja failing low (g α) f + =41 α = -1, β = f + =41 f + =36 f + =41 f + =36 f + =41 f + =12 f + =34 f + =36 41 5 12 90 101 0 20 30 34 0 36 35 50 36 25 3 Zakresy α-β: failing low Wywołanie procedury alfa-beta dla wierzchołka n z parametrami AlfaBetaFS(n (n, -1, ) (wszystkie liście mają wartości mniejsze) spowoduje: we wszystkich wierzchołkach MIN wystąpienie odcięć ęćα, bo wartości wszystkich następnik pników w sąs g α= -1 we wszystkich wierzchołkach MAX brak jakichkolwiek cięć ęćβ,, bo wartości wszystkich następnik pników w sąs g < β = Otrzymane drzewo przeszukiwania będzie b zawierać po jednym potomku dla kaŝdego wierzchołka MIN i wszystkie potomne dla kaŝdego wierzchołka MAX. 2
Failing low dlaczego górne g ograniczenie? all... one all............ one............ Zakresy α-β: : sytuacja failing high (g β ) f - =5 α = -, β = - +1 f - =5 f - =5 f - =0 f - =5 f - =0 41 5 12 90 101 0 20 30 34 0 36 35 50 36 25 3 29
Zakresy α-β: failing high Wywołanie procedury alfa-beta dla wierzchołka n z parametrami AlfaBetaFS(n (n, -, - +1) (wszystkie liście mają wartości większe) spowoduje: we wszystkich wierzchołkach MAX wystąpienie odcięć β,, bo wartości wszystkich następnik pników w sąs g β=- +1 we wszystkich wierzchołkach MIN brak jakichkolwiek cięć ęćα,, bo wartości wszystkich następnik pników w sąs g > α = - Otrzymane drzewo przeszukiwania będzie b zawierać po jednym potomku dla kaŝdego wierzchołka MAX i wszystkie potomne dla kaŝdego wierzchołka MIN. Failing high dlaczego dolne ograniczenie? one all... one all............ 30
AlfaBeta jako przeszukiwanie w głąg łąb Jak określi lić właściwą głębokość przeszukiwania? Czym moŝna przeszukiwać do wierzchołków teralnych? Najczęś ęściej nie! (Zbyt duŝa a przestrzeń) Przeszukiwanie do ustalonej głęg łębokości: Niewłaściwa kolejność następnik pników w (ruchów) moŝe doprowadzić do ogromnego grafu przeszukiwania Co w sytuacji, gdy głęg łębokość jest za mała? a? Co w sytuacji, gdy głęg łębokość jest za duŝa? Iteracyjne pogłę łębianie int iterative_deepening(state s) { depth = 0; { depth++; value = AlfaBeta(s, depth, -, ); if( rescources_up() ) break; // stop } while( depth < MAXDEPTH ) return(value value); } 31
Iteracyjne pogłę łębianie Zalety Osiąganie maksymalnej moŝliwej głęg łębokości przeszukiwania przy aktualnie dostępnych zasobach (obliczenia w systemach czasu rzeczywistego!) Gwarancja znalezienia najlepszego rozwiązania zania do określonej głęg łębokości przeszukiwania Wady Wielokrotne przeszukiwanie tych samych obszarów przestrzeni stanów Iteracyjne pogłę łębianie Potencjalne korzyści z poprzednich iteracji Przed przejściem do przeszukiwania na głęg łębokości d+1 moŝna uporządkowa dkować ruchy na podstawie wyników uzyskanych dla głęg łębokości d W większo kszości gier słuszne s jest załoŝenie, iŝi najlepszy pierwszy ruch w przeszukiwaniu na głęg łębokość d stanowi dobre przybliŝenie najlepszego ruchu w przeszukiwaniu na głęg łębokość d+1 Wzrasta prawdopodobieństwo wybrania właściwego w pierwszego ruchu im bliŝej ostatniej (najkosztowniejszej) iteracji 32
Iteracyjne pogłę łębianie: zmiana kolejności A B C 15 23 12 B A C 30 17 19 głębokość d głębokość d+1 Badania eksperymentalne wykazały, y, iŝi koszty wielokrotnego przeszukiwania przestrzeni stanów w sąs niewspółmiernie niskie w stosunku do zysków wynikających z porządkowania ruchów w w wierzchołkach grafu. Sterowanie zakresem α-β Metody manipulowania zakresem odcięć Aspiration Search [Slate&Atkin 77] Metody z imalnym zakresem * NegaScout (PVS) [Reinefeld 3] * Rodzina algorytmów w MTD [Plaat 96] 33
Zakresy α-β: Aspiration Search Tradycyjny zakres przeszukiwania (,( ) Co w sytuacji, gdy jesteśmy w pewnym stopniu przewidzieć rezultat przeszukiwania? Przeszukiwanie z zakresem (v(, v + ), gdzie: v spodziewany rezultat zakładane adane odchylenie od tej wartości ( ( >0) Mniejszy zakres alfa-beta oznacza więcej odcięć i mniejszy graf przeszukiwania Kiedy przewidywania się nie sprawdziły (failing-lowlow lub failing-high high), konieczność powtórzenia przeszukiwania z większym zakresem Zakresy α-β: : Algorytm Aspiration Search int IDAspirationSearch(state s, deviation ) { guess = 0; for(depth=1;!resources_up up(); depth++) { alpha = guess- ; ; beta = guess+ ; score = AlphaBetaFS FS(s, depth, alpha, beta); if( score >= beta ) { // failing high alpha = score; beta = ; score = AlphaBetaFS FS(s, depth, alpha, beta); } else if( score <= alpha ) { // failing low alpha = - ;; beta = score; score = AlphaBetaFS FS(s, depth, alpha, beta); } guess = score; } //endfor return(guess); } 34
Zakresy α-β: : WłasnoW asności Aspiration Search Nietrywialny problem wyboru początkowej wartości zakresu alfa-beta (wartości guess oraz ) Iteracyjne pogłę łębianie automatyzuje proces manipulowania zakresem α-β wartość korzenia wyznaczona w poprzedniej iteracji jest najlepszym przybliŝeniem środka przedziału u w następnej iteracji Podwójna kontrola przebiegu przeszukiwania: sterowanie głębokością oraz manipulowanie przedziałem em alfa-beta Jeśli nie Aspiration Search,, to co? AspirationSearch nie moŝe e korzystać ze zbyt małego zakresu α-β,, bo koszty powtórze rzeń przeszukiwania byłyby yby zbyt duŝe! AspirationSearch ogranicza się tylko do manipulacji zakresem w korzeniu grafu, dlaczego nie robić tego w kaŝdym wierzchołku grafu? Bardziej efektywne metody operują na imalnym zakresie α-β, tj. β = α+1 ( algorytmy NegaScout oraz MTD(f) ), ale wymagają dodatkowej pamięci do porządkowania ruchów 35