Hry dvou hráčů (např. šachy) Uvažujeme jen hry s nulovým součtem, tj. zisk jednoho znamená ztrátu druhého hráče. Střídá se náš tah, kde maximalizujeme svůj zisk, s tahem soupeře, který se snaží náš zisk imalizovat, neboť to je jeho ztráta. Náš graf prohledávání bude mít dva typy uzlů: MAX a MIN.
7 A MAX B C MIN 7 9 D 11 G MAX 7 9 E 1 F 9 4 11 MIN 2 5 1 9 4 11 9 2 5 1 9 listy
Algoritmus Minimax function MINIMAX DECISION(game) returns an operator for each op in Operators(game) do Value[op]=MINIMAX VALUE(Apply(op, game), game) end return the op with the highest Value[op] function MINIMAX VALUE(state, game)returns a utility value if TERMINAL TEST[game](state) then return Utility[game](state) else if MAX is to move in state then return the hightest MINIMAX VALUE of Successors(state) else return the lowest MINIMAX VALUE of Successors(state)
Negamax
7 A MAX B C MIN 7 9 D G MAX 7 9 (2,5,1)= max( 2, 5, 1) 1 E F 9 4 11 MIN 2 5 1 9 4 11 9 2 5 1 9 listy
max(7,) 7 A MAX max( 7, 9, ) B max(, 11) C MAX 7 9 max(1,) D 11 max(9,4,11) G MAX 7 9 1 max( 2, 5, 1) E 2 5 1 9 4 11 max(, 9, ) F 9 4 11 9 MAX 2 5 1 9 listy
Prořezávání v dané hloubce (Cutoff) Potřebujeme ohodnocovací funkci na stavech, např. šachy, dáma, mlýnek: materiál jednoho hráče mínus materiál protivníka piškvorky: ohodnocení pozice volné trojice, čteřice, apod. v předem dané hloubce nevoláme MINIMAX, ale odhadneme ohodnocení pozice. Uklidnění: pokud zrovna může protivník brát, je odhad nestabilní je vhodné jít ještě pár tahů dopředu, než se situace uklidní. Problém horizontu: mohu sebrání dámy odkládat za horizont, ale ne navěky není univerzální řešení.
7 A MAX B alpha=7 C MIN 7 9 D 11 G MAX 7 9 E F 9 4 11 MIN 2 5 1 9 4 11 9 2 5 1 9 listy
α β prořezávání α je nejlepší skore MAX uzlu na cestě od kořene do stavu u MAX uzlu případně zvětšená prohledanými dětmi β je nejnižší skore MIN uzlu na cestě od kořene do stavu u MIN uzlu případně zmenšená prohledanými dětmi tj. pokud MAX uzel překročí β nebo MIN uzel překročí α, někdo z předků přetočí směr hry do jiného podstromu, než právě jsem.
α β prořezávání <alpha,beta> < I,I> alpha max I A if alpha > beta then prune < I,I> I beta B beta C D max alpha G 7 9 beta E beta F 9 4 11 2 5 1 9
α β prořezávání <alpha,beta> < I,I> alpha max I 7 < I,I> 7 A <7,I> if alpha > beta then prune I beta 7 9 B beta C 7 9 D max alpha G 7 9 beta E beta F 9 4 11 2 5 1 9
α β prořezávání I 7 <alpha,beta> < I,I> alpha max I 7 7 < I,I> beta 7 7<I B 9 7<I 9 7 9 A alpha max 7 9 7 <7,I> <7,I> <7,I> D I beta if alpha > beta then prune C alpha max 7 G <7,I> 9> beta E I 2 2<7 2 beta I F 9 4 11 2 5 1 9
α β prořezávání I 7 <alpha,beta> < I,I> alpha max I 7 7 < I,I> beta 7 7<I B 9 7<I 9 7 9 2 A alpha max 7 9 7 <7,I> <7,I> beta E I 2 2<7 <7,I> D I beta C <7,I> beta I 9 F alpha max 7 G 9 9> 2 5 1 9 9 <7,> 9 9 4 11
Algoritmus alfa beta prořezávání function MAX VALUE(state, game, α, β) returns the imax value of state if CUTOFF TEST(state) then return Eval(state) for each s in SUCCESSORS(state) do α = MAX(α, MIN VALUE(s, game, α, β)) if α β then return β end return α function MIN VALUE(state, game, α, β) returns the imax value of state if CUTOFF TEST(state) then return Eval(state) for each s in SUCCESSORS(state) do β = MIN(β, MAX VALUE(s, game, α, β)) if β α then return α end return β
Transpoziční tabulky Pamatuji si stavy, neboť se často opakují v jiných větvích.
Transpoziční tabulky Lasker position Sigma Chess bílý na tahu
Vyhrávající tah je Ka1 b1!! Ka1 b2 vede k remíze je třeba prohledat aspoň 20 tahů dopředu bez paměti hodiny či dny, s pamětí méně než sekundu díky tomu, že pěši jsou blokovaní, je stavový prostor malý Za chvíli bude α β prořezávání s pamětí.
Nulové okno Test Pokud α β pustíme místo, s oknem k ɛ, k + ɛ, ptáme se, zda má MAX hráč zaručenu výhru k. Při takovémto testu prořezávám víc, než,, proto se často vyplatí zavolat několik testů místo,. Platím za to tím, že dostanu jen dolní či horní mez, nikoli přesnou hodnotu až se meze rovnají, mám přesnou hodnotu.
Nulové okno Test <alpha,beta> <1.5,1.6> max I <1.5,1.6> alpha A 7 7 7 > 1.6 7 dolní odhad if alpha > beta then prune I beta 7 9 B beta C 7 9 D max alpha G 7 9 beta E beta F 9 4 11 2 5 1 9
Memory-enhanced Test Driver function MTDF(root : node_type; f : integer; d : integer) : integer; g := f; upperbound := +INFINITY; lowerbound := -INFINITY; repeat if g == lowerbound then beta := g + 1 else beta := g; g := AlphaBetaWithMemory(root, beta - 1, beta, d); if g < beta then upperbound := g else lowerbound := g; until lowerbound >= upperbound; return g;
První odhad pomůže Pokud se trefím, tak jen dva průchody. function iterative_deepening(root : node_type) : integer; firstguess := 0; for d = 1 to MAX_SEARCH_DEPTH do firstguess := MTDF(root, firstguess, d); if times_up() then break; return firstguess;
α β prořezávání s pamětí function AlphaBetaWithMemory(n : node_type; alpha, beta, \\ depth : integer) : integer; if retrieve(n) == OK then /* Transposition table lookup */ if n.lowerbound >= beta then return n.lowerbound; if n.upperbound <= alpha then return n.upperbound; alpha := max(alpha, n.lowerbound); beta := (beta, n.upperbound); if depth == 0 then g := evaluate(n); /* leaf node */
else if n == MAXNODE then g := -INFINITY; c := firstchild(n); while (g < beta) and (c!= NOCHILD) do g := max(g, AlphaBetaWithMemory(c, alpha, beta, d - 1)); alpha := max(alpha, g); c := nextbrother(c); else /* n is a MINNODE */ g := +INFINITY; c := firstchild(n); while (g > alpha) and (c!= NOCHILD) do g := (g, AlphaBetaWithMemory(c, alpha, beta, d - 1)); beta := (beta, g); c := nextbrother(c);
/* Traditional transposition table storing of bounds */ /* Fail low result implies an upper bound */ if g <= alpha then n.upperbound := g; store n.upperbound; /* Found an accurate imax value - will not occur if called with zero window */ if g > alpha and g < beta then n.lowerbound := g; n.upperbound := g; store n.lowerbound, n.upperbound; /* Fail high result implies a lower bound */ if g >= beta then n.lowerbound := g; store n.lowerbound; return g;
Zájem UI o hry ukázat schopnosti inteligence počítačů stanovit hodnotu (game theoretic value) hry první hráč vyhraje, prohraje, remizuje pokud všichni hráči hrají optimálně My: hry s plnou informací a s nulovým součtem.
Stupně vyřešení hry Silně vyřešená je známá optimální strategie pro všechny pozice Slavě vyřešená je známá optimální strategie pro počáteční pozici Ultra slabě vyřešená je známá hodnota počáteční pozice, ale ne strategie, jak jí dosáhnout
Velikost stavového prostoru Složitost her velikost herního stromu (pro MINIMAX atd.)
Mlýnek (Nine men s morris)
Vyřešil Gasser 1995 Mlýnek (Nine men s morris) Počet stavů hry je: 7,673,759,269 (vyloučené symetrie) vytvořil databázi všech pozic pro střední a koncovou hru (od okamžiku, kdy je položen poslední kámen), tj. 2 w b databází, kde w a b jsou počty bílých a černých kamenů za použití této databáze prohledal strom pro 1 tahů od počátku hodnota hry je remíza
Checkers (Dáma, trochu jiná) CHINOOK se stal prvním mistrem světa v herní soutěži lidí a počítačů 1994 ještě nebyla (r. 2002) slabě vyřešená databáze koncovek pro osm a méně kamenů, tj. 443,74,401,247 pozic, zkomprimovaných na 6GB databáze střední hry jakmile se podaří určit hodnotu pozice ve střední hře, uloží se do databáze v praxi umožnilo určit hodnotu mnoha pozic s 22 kameny do databáze střední hry přidané pozice, získané pokusem řešit počáteční postupy popsané v literatuře do hloubky
Staletá pozice (197 letá) 100 1900 diskuse o hodnotě pozice, závěr bílý vítězí CHINOOK 1997: během sekundy odpověděl, že je to remíza
Hex
Hex Ultra slabě vyřešeno 1. remíza není možná z tvaru hrací plochy 2. tah nikdy není na škodu 3. kdyby existovala vyhrávací stragetie pro druhého, pak první položí první kámen náhodně a pokračuje podle druhého strategie.
Connect four, Kokosové ořechy,...