CMD + K

Kapittel 6Begreper & formler · Motstandersøk: minimax og alfa-beta
Referanseside · Kapittel 6

Begreper & referanser

Alle nøkkelbegrepene, formlene og referansene fra Motstandersøk: minimax og alfa-beta, samlet på én side. Bruk denne som oppslag når du leser, øver flashcards eller tar quiz.

Øv med flashcards23 kort fra dette kapittelet

Begreper

Sentrale begreper fra kapittelet med korte definisjoner.

01Nullsumspill

Et spill der summen av spillernes nytte er den samme i alle sluttilstander, så det én spiller vinner, taper den andre (zero-sum game).

02Spilltre

Treet der roten er starttilstanden, kantene er lovlige trekk og bladene er terminaltilstander med nytte (game tree).

03Halvtrekk

Ett trekk av én spiller. To halvtrekk er én runde der begge har trukket én gang (ply).

04Nyttefunksjon

Funksjonen som gir tallverdien av terminaltilstanden for spilleren , for eksempel for seier og for tap (utility function).

05Minimax-verdi

Nytten MAX får fra en node når begge spiller optimalt derfra: nytten i et blad, den største barneverdien i en MAX-node og den minste i en MIN-node (minimax value).

06Alfa-beta-beskjæring

Minimax-søk som holder to grenser, α og β, langs stien og kutter barn som ikke kan endre valget høyere opp. Rotverdien og trekket blir de samme som med minimax (alpha–beta pruning).

07Alfa

Grensen α er den beste verdien MAX allerede har sikret et sted langs stien fra roten, og den starter på . En MIN-node kutter når (alpha).

08Beta

Grensen β er den beste verdien MIN allerede har sikret langs stien, og den starter på . En MAX-node kutter når (beta).

09Trekkordning

Rekkefølgen søket prøver trekkene i. Kommer det beste trekket først, kutter alfa-beta mest og evaluerer omtrent blader (move ordering).

10Transposisjonstabell

En hashtabell med verdiene til stillinger som allerede er evaluert, slik at en stilling som nås via en annen trekkrekkefølge, ikke regnes ut på nytt (transposition table).

11Evalueringsfunksjon

Et raskt anslag på nytten fra en stilling som ikke er terminal, ofte en vektet sum av egenskaper ved stillingen (evaluation function).

12Cutoff-test

Testen som avgjør om søket skal stoppe i en node og bruke Eval i stedet for å søke videre, typisk ved en fast dybde eller i en terminaltilstand (cutoff test).

13Horisonteffekt

Et søk med fast dybde ser ikke et uunngåelig tap som ligger rett bak dybdegrensen, og kan velge trekk som bare skyver tapet ut av syne (horizon effect).

14Rosøk

Et ekstra søk fra urolige stillinger, der et slag eller en trussel henger i lufta, til stillingen er rolig nok til at evalueringsfunksjonen er til å stole på (quiescence search).

15Foroverbeskjæring

Å droppe trekk som ser dårlige ut, uten å søke dem, for eksempel ved å bare søke de beste trekkene i hver node. Det sparer tid, men kan kutte det beste trekket (forward pruning).

Formler

Hver formel: hva den heter, hvordan den ser ut, og hva symbolene betyr.

minimax

Minimax-verdien

Regnes nedenfra og opp: blader har nytten sin, MAX-noder tar det største barnet og MIN-noder det minste. En vanlig feil er å ta det største bladet i hele treet, som om MIN hjalp MAX.

MM(s)minimax-verdien til tilstanden s
Utility(s, MAX)nytten for MAX i en terminaltilstand
Result(s, a)tilstanden etter trekket a
alfa-beta-kutt

Kuttregelen i alfa-beta

Brukes i hver node etter at et barn har returnert: oppdater , sjekk kuttet, og oppdater så α i en MAX-node eller β i en MIN-node. Det kuttes også ved likhet; å bare kutte ved streng ulikhet er den vanligste feilen.

vbeste verdi funnet så langt i noden
αbeste verdi MAX har sikret langs stien
βbeste verdi MIN har sikret langs stien
alfa-beta-kompleksitet

Tidsbruken til alfa-beta

Sammenlign med for minimax. Med perfekt ordning er den effektive forgreningsfaktoren , så søket rekker omtrent dobbelt så dypt på samme tid. Tallet for tilfeldig ordning er et omtrentlig anslag.

bforgreningsfaktor (antall trekk per stilling)
msøkedybde i halvtrekk
eval-lineaer

Lineær evalueringsfunksjon

Brukes i nodene der søket stopper. Hver egenskap teller noe ved stillingen, og vekten sier hvor mye det betyr. Formen antar at egenskapene virker hver for seg, noe som ofte ikke stemmer.

fᵢ(s)egenskap nummer i ved stillingen s
wᵢvekten til egenskap i
h-minimax

Minimax med cutoff

Som minimax, men søket stopper når cutoff-testen slår til (fast dybde eller terminaltilstand) og bruker Eval der. Dybden øker med 1 per halvtrekk.

ddybden i halvtrekk fra roten
Is-Cutoff(s, d)sann når søket skal stoppe i s
Eval(s, MAX)anslått nytte for MAX

Kodesnutter

Kodesnutter fra kapittelet, vist literal.

Kode

Alfa-beta med ett justerbart blad

Python
blad_F = 3  # @param -10..10 # Roten A er MAX. B og C er MIN-noder, og bladene leses fra venstre mot høyre.barn = {"A": ["B", "C"], "B": ["D", "E"], "C": ["F", "G", "H"]}blad = {"D": 3, "E": 7, "F": blad_F, "G": 8, "H": 6}er_max = {"A": True, "B": False, "C": False}evaluert, kuttet = [], [] def alfabeta(node, alfa, beta):    if node in blad:        evaluert.append(node)        return blad[node], None    v, valgt = (float("-inf") if er_max[node] else float("inf")), None    for i, b in enumerate(barn[node]):        w, _ = alfabeta(b, alfa, beta)        if (er_max[node] and w > v) or (not er_max[node] and w < v):            v, valgt = w, b        if (er_max[node] and v >= beta) or (not er_max[node] and v <= alfa):            kuttet.extend(barn[node][i + 1:])  # kutt også ved likhet            break        if er_max[node]:            alfa = max(alfa, v)        else:            beta = min(beta, v)    return v, valgt verdi, trekk = alfabeta("A", float("-inf"), float("inf"))print(f"Minimax-verdi i roten: {verdi}")print(f"Valgt trekk: {trekk}")print(f"Blader evaluert med alfa-beta: {len(evaluert)} av {len(blad)}")print(f"Kuttede noder: {', '.join(kuttet) if kuttet else 'ingen'}")

Prøv: sett blad_F fra 3 til 4, og se at linja Kuttede noder: går fra G, H til ingen, mens Minimax-verdi i roten: først endrer seg ved 4.

Kode

Trekkordning og antall blader

Python
import random b = 3  # @param 2..5d = 4  # @param 2..6random.seed(4)blader = [random.randint(0, 99) for _ in range(b ** d)]nivaa = [blader]  # eksakte minimax-verdier nivå for nivå, MAX på partall dybdefor k in range(d - 1, -1, -1):    nivaa.insert(0, [(max if k % 2 == 0 else min)(nivaa[0][i * b:(i + 1) * b]) for i in range(b ** k)]) def alfabeta(k, i, alfa, beta, orden, teller):    if k == d:        teller[0] += 1        return blader[i]    barn = [i * b + j for j in range(b)]    if orden == "perfekt":  # beste trekk først, slik de eksakte verdiene sier        barn.sort(key=lambda x: nivaa[k + 1][x], reverse=(k % 2 == 0))    elif orden == "tilfeldig":        random.shuffle(barn)    for x in barn:        w = alfabeta(k + 1, x, alfa, beta, orden, teller)        alfa, beta = (max(alfa, w), beta) if k % 2 == 0 else (alfa, min(beta, w))        if alfa >= beta:  # kutt, også ved likhet            break    return alfa if k % 2 == 0 else beta tilfeldig, perfekt = [0], [0]alfabeta(0, 0, -1, 100, "tilfeldig", tilfeldig)alfabeta(0, 0, -1, 100, "perfekt", perfekt)print(f"Blader uten beskjæring: {b ** d}")print(f"Blader, tilfeldig ordning: {tilfeldig[0]}")print(f"Blader, perfekt ordning: {perfekt[0]}")print(f"Teoretisk b^(d/2): {b ** (d / 2):.0f}")

Prøv: sett b til 5 og d til 6, og se at linja Blader, perfekt ordning: blir 249, nær to ganger Teoretisk b^(d/2):, mens tilfeldig ordning trenger nesten ti ganger så mange.

Pseudokode

Pseudokode som forklarer fremgangsmåten steg for steg.

Pseudokode

Alfa-beta i pseudokode

alfabeta(node, alfa, beta):    hvis node er terminal:        returner nytte(node)    hvis cutoff(node):        returner eval(node)    hvis MAX trekker i node:        v = -uendelig        for barn i barna(node):                  # venstre mot høyre            v = max(v, alfabeta(barn, alfa, beta))            hvis v >= beta:                returner v                       # kutt: MIN over vil aldri slippe hit            alfa = max(alfa, v)    ellers:        v = +uendelig        for barn i barna(node):            v = min(v, alfabeta(barn, alfa, beta))            hvis v <= alfa:                returner v                       # kutt: MAX over har noe minst like godt            beta = min(beta, v)    returner v # start: alfabeta(rot, -uendelig, +uendelig)

Samme rekursjon som minimax, men med to grenser som sendes nedover. Kuttet skjer også ved likhet, og verdien som returneres etter et kutt, er en grense.

Læringsmål

Hva du skal kunne etter å ha lest kapittelet.

  1. 01Formaliser et tospillers nullsumspill med starttilstand, trekk, terminaltest og nyttefunksjon
  2. 02Regn ut minimax-verdien til hver indre node i et spilltre og finn trekket MAX velger
  3. 03Spor alfa-beta-beskjæring og oppgi de øverste ikke-besøkte nodene med begrunnelse for hvert kutt
  4. 04Forklar hvorfor trekkordning avgjør hvor mye alfa-beta kutter, og regn med
  5. 05Forklar evalueringsfunksjoner, cutoff, horisonteffekten og rosøk
  6. 06Bruk nyttevektorer til å regne ut verdier i spill med flere enn to spillere