Enkel introduksjon av Minimax

Minimax er en søkealgoritme som benyttes i “adversarial search” problemer som også kalles “spill”. Algoritmen og varianter av algoritmen kan benyttes i en rekke type spill, og vi skal nå utforske den i kontekst av spill som oppfyller følgende krav:

  • Spillet er deterministisk og zero-sum.
  • Spillerne har perfekt informasjon.
  • Spillerne alternerer om hvem som utfører neste handling.
  • Det er kun 2-spillere.
  • Begge spiller optimalt.

Et eksempel på slike spill kan være tre-på-rad, dam eller sjakk. Spillene kan sees på som søke-problemer da hvert trekk resulterer i en ny state i spillet, disse gir igjen opphav til nye mulige trekk, basert på foregående trekk osv. Dette kan enkelt modelleres som et søketre.

Videre definerer vi 2 spillere, Max og Min. Max ønsker å maksimere verdien av en state mens Min ønsker å minimere den.

For spill som tre-på-rad vil spiller 1 (Max) først ha 9 mulige valg, ut ifra valget vil spiller 2 (Min) ha 8 valg osv. Dette kan modelleres med et komplett tre som vil ha under 9 fakultet (362,880) terminalnoder (mange av disse like), og vi kan ved å analysere disse konkludere med at et hvert spill skal resultere i uavgjort så lenge begge spiller optimale trekk.
For et spill som sjakk består derimot det komplette treet av 10^40 forskjellige noder. Det er med andre ord helt utenkelig å konstruere det komplette treet. I slike spill blir man nødt til å bestemme seg for en gitt dybde man ønsker å søke til, for så å benytte en heuristisk evalueringsfunksjon for å definere verdien i daværende tilstand av spillet.

Så, med denne bakgrunnskunnskapen kan vi ta en titt på hvordan Minimax fungerer. Den starter med å gjøre en form for rekursiv dybde-først søk. For å illustrere hvordan algoritmen jobber la oss definere et enkelt spill:

  • Det er to spillere, Min og Max.
  • Spillet består av en runde, hvor hver spiller gjør ett trekk.
  • I hvert trekk har spilleren tre muligheter.
  • Max starter og ønsker maksimal verdi.

Algoritmen starter med å utforske nodene til venstre. Når den treffer en løv-node bruker den en evalueringsfunksjon for å finne verdien i staten denne noden representerer. Etter å ha funnet de tre løv-nodene til venstre vil det se lik ut:

Siden disse er knyttet til en Min node, vil den minste verdien bli valgt:

Algorimen går tilbake til toppen, her ser vi at flere av barne-nodene enda ikke er utforsket og søket forsetter i det miderste sub-treet. Evalueringsfunksjonen blir kalt på løv-nodene og den laveste blant dem valgt:

Vi returnerer til rot-noden før høyresiden utforskes:

Da har alle barne-nodene til rot-noden blitt utforsket og det er Max sin tur. Max ønsker å maksimere verdien og velger 5:

.

Hele treet er nå undersøkt og minimax verdien 5 er funnet. Dette er den høyeste verdien Max kan oppnå da han vet Min spiller optimalt og ønsker å minimere denne verdien. Spillet vil bli utført som følgende:

Så, kan en såpass enkel algoritme brukes for å løse komplekse problemer? Hvis vi går til dybde N og på hver node har X mulige trekk vil tidskompleksiteten være lik O(X^N). Med andre ord vil algoritmen være for ineffektiv til de aller fleste sanntidsapplikasjoner hvor beregningstid er en begrensende faktor. Men algoritmen danner en basis for analyse av en rekke spill og ikke minst er den et utgangspunkt for flere mer praktisk-anvendbare algoritmer. En av disse er Minimax med Alpha-Beta-pruning. Ved å gjøre et par smarte triks, klarer den å halvere N slik at tidskompleksiteten reduseres til O(X^(N/2)).

Fortsettelse følger…

2 Likes

Fett, en algoritme jeg ikke har hørt beskrevet før! (ikke at jeg er voldsomt belært i algoritmer, by any stretch, men har vært borti endel, syntes det er fryktelig morsomt å optimalisere ting, som gjør at jeg får behov for å lære noen algoritmer)

Nå kom jeg på en ny form for sudoku som jeg enda ikke har sett før, hva om man lager en puzzle som har flere mulige løsninger (vanligvis skal de ikke ha mer enn 1), og hver gang man setter inn en digit så setter datamaskinen inn en som fjerner de enkle løsningene, helt til det bare er en mulig løsning igjen.
Dette er vel kanskje en use-case for minmax?

Gleder meg til fortsettelsen! :smiley:

1 Like

Det her var veldig interessant, og meget bra skrevet! Har gjort en sånn dybde-først med en maks dybde da jeg lage en solver for sokoban, men der var det litt enklere siden det bare er én spiller. Gleder meg til å lese neste!

1 Like

Oi, det høres ut som en spennende idé, men usikker på om jeg helt klarer å se for meg hvordan det skulle bli gjort. Hva skiller en enkel løsning fra en vansklig en? Er det en løsning hvor en tallplassering gjør resten mer “triviell” enn hva den hadde vært om tallet ble plassert et annet sted? Og med triviell mer jeg vell (tror jeg) at søketreet blir mindre dypt enn det ville vært med en annen plassering, slik at maskinen sin rolle blir begrense din mulighet til å redusere dybden på søketreet?
Her er jeg på dypt vann :sweat_smile:

Enig!

Tja her er det nok mange faktorer, det finnes ekstremt mange ulike teknikker og konsepter i sudoku (overraskende mange), f.eks er det for folk flesk vanskeligere å finne tall basert på rader og kolonner fremfor bokser (man ser liksom først på hvilket tall som mangler i boksene). Også blir det vanskeligere jo flere nivå ut man må søke for finne et tall, feks. vil 2 eller 3 mulige posisjoner til ett tall i en boks hindre noen muligheter i neste, som videre hindrer i en annen boks, osv helt til disse restriksjonene gjør at man får et tall i en boks. Eller at 4 tall har de samme 4 mulighetene i en boks og den 5’e ledige cellen i boksen da er en “naked single” som kun kan være ett tall, selvom dette tallet ikke er hindret til å være i en av de andre cellene i boksen. tilsvarende for rader og kolonner (som er enda vanskeligere å se).

Det finnes noen sudoku puzzle vanskelighetsgrads-graderer, som rangerer vanskelighetsgraden basert på hvilke teknikker man må bruke for å finne et tall, men vet ikke om det er en nøyaktig vitenskap :stuck_out_tongue:

tenker at man måtte generert noen løsninger X som har Y antall overlappende tall, plukke ut Z antall start-tall (subsett av Y eller Y), også vil jo tall som brukeren putte inn videre begrense hvilken av løsningene som er mulige av X, slik at neste tall som velges av maskinen må være et tall som er unikt for de resterende X løsningene og som også er det tallet som gir minst restriksjoner på brettet

1 Like

Det blir på en måte “generér din egen sudoku” hvor det du putter inn blir en slags random seed. Du kunne valgt vanskelighetsgrad også evt. Alternativt: Du har en sudoku som er én digit unna en løsning. Du løser den. Datamaskinen tar vekk en digit eller to. Evig sudoku! (men ikke minmaks)

Nja, spørsmålet blir jo om man som spiller klarer å se en «minste motstands vei», altså det vil jo være mange mulige tall man setter inn, det som hjelper deg som spiller mest blir jo da å sette inn de talla som gir mest mulig restriksjoner på brettet. Så det blir mer enn en generator, man må jo tenke litt strategisk

Sykt bra skrevet og forklart =D
Gleder meg til forklaringen av alpha-beta pruning!

I forbindelse med Sudoku så kan det formuleres som en CSP (Constraint Satisfaction Problem) som igjen kan løses ved bruk av den rekursive algoritmen backtracking search, enda en veldig interessant algoritme som kan brukes til en hel del! Kanskje det kommer en artikkel om backtracking etterhvert og? :smiley:

2 Likes

Leser gjerne om backtracking også!!

1 Like