• No results found

Frysstopp

N/A
N/A
Protected

Academic year: 2021

Share "Frysstopp"

Copied!
37
0
0

Loading.... (view fulltext now)

Full text

(1)

Institutionen för naturvetenskap och teknik

Frysstopp

Självständigt arbete i matematik

Miika Pasma

(2)

Örebro universitet

Institutionen för naturvetenskap och teknik Självständigt arbete i matematik

Frysstopp

Självständigt arbete i matematik

Miika Pasma Juni 2016

Handledare: Niklas Eriksen Examinator: Holger Schellwat

(3)

Sammanfattning

I detta projekt har jag kollat på ett spel som kallas för Frysstopp. Syftet var att hitta den bästa strategin för att vinna spelet med så stor sannolikhet som möjligt.

Projektet är uppdelat i två större delar. Den första delen består av mate-matiska definitioner och resonemang för att kunna begränsa problemet. Den andra delen består utav simuleringar som använder sig av resonemanget från den första delen, för att kunna visa andra hypoteser.

(4)

Innehåll

1 Problemformulering 4

2 Definitioner till problemet 5

2.1 Komposition av heltal . . . 5

2.2 Strategi . . . 5

2.3 Markovkedja . . . 7

2.4 Strategimatris . . . 8

2.5 Väntevärde . . . 8

3 Simulering och beräkning 13 3.1 Sten Sax Påse . . . 15

3.2 Förlängning av spelet . . . 16

4 Optimering och kontinuerlig variant 17 4.1 Optimering av sökning . . . 17

4.2 Kontinuerlig variant . . . 18

5 Diskussion 19 A Simuleringskod 21 A.1 CompareStrats . . . 21

A.2 Script för strategier . . . 22

A.3 Finns Sten Sax Påse . . . 24

A.4 DuelStrats . . . 25

A.5 Top10percent . . . 26

A.6 Optimeringsprogram . . . 26

A.7 fmincon script . . . 28

B Stödprogram 29 B.1 StrategyMatrix . . . 29 B.2 AddOnes . . . 29 B.3 AddZeroes . . . 29 B.4 IncreasingVector . . . 30 B.5 EstRolls mat . . . 30

(5)

B.6 FindRolls . . . 30 B.7 EstRolls . . . 31 B.8 StepStrat . . . 31 B.9 VectorFix . . . 31 B.10 SendBackIfMov . . . 32 B.11 ReduceSteps . . . 32

(6)

Kapitel 1

Problemformulering

När vi var små barn så brukade vi ofta leka olika typer av lekar, många hade enkla regler och gick ofta ut på att vara snabb och smart. Frysstopp är en av dessa lekar. I leken Frysstopp så stod en person vänd emot en vägg och väntade en godtycklig tid, medan de andra i leken sakta men säkert vandrade fram mot personen. Personen vid väggen kunde när som helst vända sig om, och om hen såg en av de andra spelarna röra sig, så skickades den personen tillbaka till startpunkten. Den person som lyckades komma fram till personen vid väggen vann. Sedan började man om igen, fast personen som vann den förra matchen fick stå vid väggen och skicka tillbaka de andra.

I detta examensarbetet har jag betraktat en mera matematisk modell av leken. Då kollar vi på spelet Frysstopp. I spelet Frysstopp så står ett visst antal (typiskt 3-5) spelare på led (gruppen), bredvid varandra. 30 steg bort står en spelare (stopparen) med ryggen mot gruppen. Hen slår en 6-sidig tärning, och vänder sig om efter tärningsresultatet antal sekunder. Målet med spelet är att gruppens deltagare skall vandra fram till stopparen, 1 steg per sekund. Den spelare som först kommer fram vinner. Om en i gruppen befinner sig i rörelse i tillfället då stopparen vänt sig om så måste den spelaren gå tillbaka till startposition innan stopparen slår tärningen igen.

Uppgiften är att hitta rätt strategi för att komma fram till stopparen så snabbt som möjligt, med störst sannolikhet.

(7)

Kapitel 2

Definitioner till problemet

En omgång av spelet är när alla spelare börjar på startposition och tar slut när en person nått fram till stopparen. En spelare i gruppen väljer själv hur många steg hen skall gå innan tärningen har kastats. Om spelaren valt lika många steg eller färre än vad tärningen visar, så kommer denna person att fortsätta spelet från den nya positionen. Om spelaren valt att gå fler steg än vad tärningen visar, så kommer hen att hamna i startposition innan spelet fortsätter med ett nytt tärningsslag. Därmed är man alltid säker från att hamna i startpositionen om man väljer att gå 1 steg.

2.1

Komposition av heltal

En komposition av ett heltal är ett sätt att dela upp talet i mindre heltals-delar.

Exempel 2.1.1. Talet 4 kan delas upp i följande kompositioner 4

3 + 1; 2 + 2; 1 + 3

2 + 1 + 1; 1 + 2 + 1; 1 + 1 + 2 1 + 1 + 1 + 1

För varje positivt heltal n så finns det 2n−1 antal kompositioner. [4]

2.2

Strategi

Varje spelare i gruppen har en egen strategi för hur de på snabbaste sätt ska komma fram till stopparen. En strategi är en komposition av det totala antalet steg som krävs för en spelare att komma i mål, det vill säga 30. Kompositionen får inte innehålla några element större än tärningens största värde, det vill säga 6. En position i en strategi är dess index. Det vill säga

(8)

efter 3 lyckade tärningsslag står vi i position 4 i strategin. Om vi valt ett för högt antal steg att gå, så får vi gå tillbaka position 1 i strategin.

Exempel 2.2.1. : En spelare A väljer att gå 6, 5, 3, 2, 6, 5, 2, och sedan 1 steg representeras i vektorn

A = (6,5,3,2,6,5,2,1)

Siffersumman i vektorn är densamma som totala antalet steg spelet kräver innan man är i mål. Spelare A kan som tidigast vara framme efter 8 tärnings-slag, samma antal tärningsslag som element i vektorn. En annan spelare B, väljer den säkra strategin att alltid gå 1 steg per tärningsslag.

B = (1,1, . . . ,1)

Siffersumman för vektorn är fortfarande 30, men det är även 30 element, så spelare B kommer som tidigast att vara framme efter 30 tärningsslag.

Med ett större antal steg så kommer en lägre sannolikhet att man får avancera strategimässigt. Sannolikheten att få gå till nästa steg är

7 − λi

6

där λi är den i:te position i en given strategi λ.

Definition 2.2.1. En speciell variant av kompositioner kallas för heltals-partitioner (mer teori finns i Combinatorics and Graph Theory[1]). Dessa kompositioner beskriver uppdelningen av ett tal, i fallande storleksordning.

I en godtycklig strategi λ = (λ1, λ2, . . . , λ`) skall λ1 ≥ λ2, . . . , ≥ λ`> 0, samt ` X i=1 λi = n,

där n är spelets totala steglängd. I problemformuleringen så är spelets totala längd 30. En variant på heltalspartitioner är begränsad heltalspartition, där ingen del av uppdelningen får vara större än begränsningen. Begränsningen i projektet är 6, som är tärningens största utfall.

(9)

2.3

Markovkedja

Markovkedjor (se till exempel Norris [2]) är en tidsdiskret stokastisk process med den stora fördelen av att den saknar minne, detta gör att den kan användas i många olika typer av sannolikhetsmodeller. En annan fördel är att de är väldigt enkla, vilket gör att det blir lättare att förutspå deras beteende.

Med Markovkedjor så kan vi beskriva sannolikheten att avancera från och till olika noder i en graf med hjälp av en matris. Denna matris kallas för övergångsmatris, i den representerar varje rad i matrisen sannolikheten att vandra till motsvarande nod, siffersumman av en rad måste vara lika med 1.

Figur 2.1: Grafisk representation för P . Källa:[2]

Exempel 2.3.1. Betrakta en Markovkedja med två tillstånd 1 och 2, där sannolikheten att vandra från tillstånd 1 till tillstånd 2 är α ≤ 1 och sanno-likheten att gå från tillstånd 2 till tillstånd 1 är β ≤ 1. En grafisk beskrivning ges i figur 2.1. Så kan vi beskriva det förhållandet i en matris

P =1 − α α β 1 − β



Exempel 2.3.2. I en mer komplex markovkedja P0 så förhåller sig tillstån-den enligt figur 2.2. Den representeras med följande övergångsmatris

P0 =   0 1 0 0 1/2 1/2 1/2 0 1/2  

Frysstopp är en typisk Markovkedja. Vi står i en position i strategin och har en sannolikhet att avancera och en sannolikhet att hamna i startposition.

2.4

Strategimatris

För varje strategi finns en motsvarande strategimatris. Denna matris be-skriver sannolikheten att en spelare tar nästa steglängd. Första kolumnen

(10)

Figur 2.2: Grafisk representation för P0. Källa:[2]

i denna matris är sannolikheten att man får återvända till startposition. Överdiagonalen i matrisen innehåller sannolikheterna för att spelaren skall avancera strategimässigt. Den sista raden är fylld med 0, förrutom på den sista positionen som är 1, detta representerar att man är i mål och kan inte komma längre.

Om vi har den godtyckliga strategin λ = (λ1, . . . ,λ`) så kan dess

strate-gimatris beskrivas på följande sätt:

Mλ =                 1 −7−λ1 6 7−λ1 6 0 . . . 0 1 −7−λ2 6 0 7−λ2 6 . . . 0 .. . 0 . .. ... 1 −7−λ` 6 0 . . . 0 7−λ` 6 0 . . . 1                 .

(11)

(4, 3, 2, 1), så kan denna strategi representeras med följande matris: Mλ =                 1 2 1 2 0 0 0 1 3 0 2 3 0 0 1 6 0 0 5 6 0 0 0 0 0 1 0 0 0 0 1                 .

2.5

Väntevärde

Väntevärdet, det vill säga väntat antal tärningsslag för en strategi, kan be-skrivas i varje position med hjälp de stokastiska variablerna λ1, λ2, . . . , λ`.

Definition 2.5.1. En strategi λ har värdet val(λ) = E1(λ). Lemma 2.5.1. Värdet av strategin λ ges av

val(λ) = ` X k=1 γ1,k, där (I − Mλ0)−1 = (γi,k).

Bevis. För varje position i så kallar vi sannolikheten att få gå tillbaka till start µioch sannolikheten att få avancera för σi. Då kan vi ställa upp följande

ekvationer för att beskriva väntevärdet i varje position i spelet. E1(λ) = 1 + µ1E1(λ) + σ1E2(λ) E2(λ) = 1 + µ2E1(λ) + σ2E3(λ) .. . E`(λ) = 1 + µ`E1(λ) + σ`E`(λ`+1) E`+1(λ) = 0.

Så varje position är i slutändan beroende av den första positionen. Positionen ` + 1 är man redan i mål, så då behöver man inte fler tärningsslag. Därmed så behöver man inte σ`E(λ`+1) i näst sista ekvationen.

Så med denna typ av uppställning så kan vi beskriva en godtycklig stra-tegi λ, dess väntevärdesekvation blir då

(12)

Vi kallar (1, 1, . . . ,1)T för 1. Vi vill lösa ut E(λ) som en vektor som beskriver väntevärdet för varje position istället för en matris. Vi börjar med att flytta över MλE(λ) till vänsterled.

E(λ) − MλE(λ) = 1

Bryt ut E(λ) till höger, i vänsterledet.

(I − Mλ)E(λ) = 1

Multiplicera sedan med (I − Mλ)−1 från vänster.

E(λ) = (I − Mλ)−11.

Nu har vi fått väntevärdena i en kollumnvektor, där varje rad i vektorn är väntevärdet för motsvarande position i strategivektorn.

Om vi tittar på I − Mλ så har vi följande matris

(I − Mλ) =                      1 − (1 −7−λ1 6 ) − 7−λ1 6 0 0 . . . 0 −(1 − 7−λ2 6 ) 1 − 7−λ2 6 0 . . . 0 −(1 − 7−λ3 6 ) 0 1 − 7−λ3 6 0 .. . .. . . .. . .. −(1 −7−λ`−1 6 ) 0 . . . 0 1 − 7−λ`−1 6 −(1 −7−λ` 6 ) 0 . . . 0 1                      Tidigare såg vi att vi inte var intresserad av sannolikheten att avancera in i mål, eftersom den inte genererar ytterligare tärningsslag. Så när vi beräknar (I −Mλ)−1, så har vi tagit bort den sista raden och kolumnen. Vi kallar denna

matris för Mλ0. Självaste matrisen (I − Mλ0)−1 kommer innehålla massor med tal, och vi väljer att kalla dessa tal för γrad,kolumn.

(I − Mλ0)−1=      γ1,1 γ1,2 . . . γ1,` γ2,1 γ2,2 . . . γ2,` .. . ... γ`,1 γ`,2 . . . γ`,`     

Från våran ekvation tidigare E(λ) = (I − Mλ0)−11, så kan man räkna ut väntevärdet i en given position genom att summera den rad man vill ve-ta väntevärder för, eftersom matrisen multipliceras med 1 vektorn. För att räkna ut väntevärdet i den startpositionen så har vi följande ekvation

E(λ1) = `

X

k=1

(13)

För att kunna beräkna väntevärdet behöver vi bestämma den översta raden i (I − Mλ0)−1.

Lemma 2.5.2. Om (I − Mλ0)−1= (γi,k) så gäller

γ1,k = ` Y i=k 6 7 − λk .

Bevis. Om vi gör en radvektor med första raden i vår inversmatris, och multiplicerar den med (I − Mλ0) får vi

(γ1,1,γ1,2, .., γ1,`)(I − Mλ0) = (1,0,..,0)

Uppdelat på respektive komponet får vi fölhande ekvationer

γ1,1− ` X k=1 γ1,k(1 − 7 − λk 6 ) = 1 och γ1,k−1(− 7 − λk−1 6 ) + γ1,k = 0 för 2 ≤ k ≤ `, det vill säga

γ1,k = γ1,k−1(

7 − λk

6 ).

Vi verifierar nu att de angivna värdena stämmer med dessa ekvationer. Vi börjar med den första ekvationen.

γ1,k 7 − λk 6 = {insättning avγ1,k = ` Y i=k 6 7 − λi } = ` Y i=k 6 7 − λi ! 7 − λk 6 = 6 7 − λk 6 7 − λk+1 ... 6 7 − λ` 7 − λk 6 = ` Y i=k+1 6 7 − λi = γ1,k+1.

(14)

För den andra ekvationen gäller γ1,1− ` X k=1 γ1,k  1 −7 − λk 6  = ` Y i=1 6 7 − λi − ` X k=1 ` Y i=k 6 7 − λi  1 −7 − λk 6  = ` Y i=1 6 7 − λi − ` Y i=1 6 7 − λi − ` Y i=2 6 7 − λi ! − ` Y i=2 6 7 − λi − ` Y i=3 6 7 − λi ! − · · · − ` Y i=` 6 7 − λi − ` Y i=`+1 6 7 − λi ! = ` Y i=1 6 7 − λi + ` Y i=2 6 7 − λi + · · · + 6 7 − λ` + 1 − ` Y i=1 6 7 − λi − ` Y i=2 6 7 − λi − · · · − 6 7 − λ` = 1. Eftersom γ1,k = ` Y i=k 6 7 − λk

uppfyller samtliga ekvationer så är dessa värden korrekta. Korollarium 2.5.1. Vi har att

val(λ) = ` X k=1 ` Y i=k 6 7 − λi .

Vi kan nu ange vissa egenskaper som en minimal strategi måste ha. Sats 2.5.1. En minimal strategi λ är en heltalspartition.

Bevis. Vi väljer två godtyckliga strategier λ och λ0, där enda skillnaden mellan de två är att i λ0 har vi bytit plats på λj och λj+1, där λj > λj+1

λ = (λ1, λ2, . . . , λj, λj+1, λj+2, . . . , λ`)

och

(15)

Vi vill visa att val(λ) < val(λ0). Vi väljer att kolla på differensen mellan de två strategierna genom val(λ0) − val(λ) = − ` Y i=j+1 6 7 − λi + 6 7 − λj ` Y i=j+2 6 7 − λj = ` Y i=j+2 6 7 − λj+1  − 6 7 − λj+1 + 6 7 − λj  = 6 ` Y i=j+2 6 7 − λi  7 − λj+1− (7 − λj) (7 − λj)(7 − λj+1)  = 6 ` Y i=j+2 6 7 − λi  −λ j+1+ λj (7 − λj)(7 − λj+1)  > 0

Eftersom 6 ≥ λj > λj+1≥ 1, så kommer denna ekvation att vara ett positivt

tal. Det betyder det att λ0 har ett högre väntevärde än λ i startpositionen. Den enda skillanden mellan strategierna var att vi hade ett större tal följande ett mindre i λ0.

Om två element i en strategi är arrangerade i stigande ordning kan vi alltså få en bättre strategi genom att byta plats på dem. Med hjälp av bub-belsortering [3] ser vi att på detta sätt alltid får bättre strategier genom att sortera elementen i avtagande ordning. Vi har nu visat att en heltalsparti-tion är bättre än en strategi som innehåller samma siffror i blandad ordning, vilket betyder att vi endast behöver titta på begränsade heltalspartitioner.

(16)

Kapitel 3

Simulering och beräkning

För att kunna hitta den bästa strategin i spelet så valde jag att skriva en handfull olika program i Matlab. På detta sätt kunde jag ta reda på all den information jag ville veta om varje separat strategi. Det kanske viktigaste programmet som jag skrev kallas för CompareStrats A.1. Programmets syfte är att ta in två vektorer som representerar de olika strategierna, spelets längd, och antalet matcher/simulationer av spelet vi vill testa. Genom att välja ett stort antal matcher, så kan man tydligare se vilken strategi som vinner flest gånger. För att kunna testa alla strategier mot varandra, så måste vi generera en datamängd som innehåller alla strategierna. Detta gjordes genom att ha en vektor, som alltid fylls på med ettor, så att summan är spelets längd. Sedan fyller vi på vektorn med 2:or ända tills vi inte kan göra det längre. Då går vi tillbaka baklänges i vektorn och hittar första positionen där en skillnad på två element finns och ökar den längst till höger med 1, om man inte kommer till första elementet för då skall den ökas med 1 istället. Om hela vektorn består av samma tal, så kommer man gå till den första positionen och öka den med 1, för att sedan börja fylla på med 2:or. När programmet vill öka en position i strategin till 7, så avbryts genereringen. Exempel 3.0.1. Vektorn är alltid fylld med ettor, så att summan av

(17)

ele-menten i vektorn är n. Så testvektorn får följande beteende. 1 2 2,2 2,2,2 .. . 3 3,2 3,2,2 .. . 6,6,6, . . .

Med hjälp av detta program så kunde vi se att det totala antalet begrän-sade heltalspartitioner var 1242. Om nu varje test tar ungefär 3 sekunder, så skulle ett test där man testar alla möjliga kombinationer mot varandra ta drygt 27 dygn. Möjligen något arbiträrt så valde jag att strunta i strategier som har ett väntevärde mer än 5, från sin föregångare, när vi lägger till 2:or. På detta sätt så har vi en undre begränsning och det totala antalet strate-gier som vi vill kolla på gick drastiskt ner till 164 stycken. När vi hittade listan med alla heltalspartitioner så gjorde jag en uttömmande sökning på väntevärdet för varje strategi.

Men för att kunna avgöra vilken strategi som faktiskt var den bästa måste alla strategier möta alla andra i denna listan. Så jag skrev ihop ett program som tar in denna lista och testar dem parvis och sparar ner vinnaren i samma matris som vi använde tidigare. Om en strategi endast vann med en marginal om 5% så sparades detta ner som en match som spelats lika och båda strategierna fick det nersparat i en separat kolumn. Reslutatet från datamängden visade att en helt annan strategi än den med bäst väntevärde fick flest vinster.

Eftersom själva testet tog en del tid, så gjordes endast två. Datamängden representeras grafiskt i figur 3.1 samt 3.2. De båda testen har nästan samma resultat, så fler tester behöver inte utföras. Vi kan då se att flera strategier har nästan samma antal vinster. Intressant var även att den strategi som vunnit mest inte var den som hade bästa väntevärdet, detta kan bero på att vi lade till den undre begränsningen.

För att se korrelationen mellan antalet vinster och väntevärde så lade jag upp antalet vinster en strategi får tillsammans med dess väntevärde, som kan ses i figur 3.3.

Vi kan se hur väntevärdena för respektive strategi endast ökar och ökar, men när man når en viss nivå på väntevärdet så sjunker antalet vinster proportionellt.

(18)

Figur 3.1: Test nummer 1, antalet vinster i rött (nedre), nära lika match i blått (ovan).

Figur 3.2: Test nummer 2, antalet vinster i rött (nedre), nära lika match i blått (ovan).

(19)

Figur 3.3: Test nummer 2, antal vinster i rött och väntevärde i grönt. Dessutom är de strategier som tar väldigt mycket risk på de första posi-tionerna i stategin mycket sämre än de som tar en medelstor risk, även om deras väntevärden inte är speciellt mycket sämre. Det är möjligt att detta kan uppstå på grund av att vi inte har med alla begränsade heltalspartitioner i testet.

3.1

Sten Sax Påse

En önskvärd egenskap för en strategi är transitivitet, det vill säga att för strategierna gäller A > B, B > C =⇒ A > C.

Något som man kan se i simuleringen är att ingen strategi vinner emot alla andra strategier. Det intressanta är då vilka strategier det är som den förlorar emot, samt vilka strategier förlorar de i sin tur mot?

Om vi betraktar spelet sten sax påse. Ett spel där två spelare väljer i hemlighet antigen sten, sax, eller påse. Spelarna visar sedan samtidigt för varandra vad den har valt. En spelare med sten vinner mot en spelare med sax. En spelare med sax vinner mot en spelare med påse. En spelare med påse vinner över en spelare med sten. Om spelarna valt samma så spelar man om igen.

Det finns mycket som pekar på ett scenario där strategierna beteer sig som i spelet sten sax påse. Det vill säga att om vi har en strategi A, så finns det en strategi B som är bättre än A. Men det finns även en strategi C som är bättre än B, men förlorar emot A, det vill säga raka motsatsen mot transitivitet. Det jag gjordet då var att skriva ihop ett sökningsprogram som

(20)

letar efter detta mönster. Det kan gå i många fler steg än det typiska sten sax påse. Programmet fungerar så att det först hittar den strategi med flest vinster, sedan söker den efter en ny strategi som vinner emot den nuvarande strategin. Detta gör den om och om igen tills den hittar en strategi som förlorar emot den första strategin vi valde. A.3 Med hjälp av programmet kan man se att strategin (3,3) förlorar emot (2,2,2,2,2), som förlorar mot (2,2,2,2,2,2), som förlorar mot (2,2,2,2,2,2,2) som i sin tur förlorar mot (3,3), den första strategin.

3.2

Förlängning av spelet

Hitills har vi endast kollat på om spelets längd är 30 steg. Men om vi kollar på en variant av spelet som är mycket längre, så kan vi fortfarande använda oss av samma funktioner som tidigare. Intressant är då att samma strategi som för spelet med 30 steg har lägsta väntevärdet. Detta tyder på att om man har ett sannolikt försprång så hinner inte andra strategier ikapp.

(21)

Kapitel 4

Optimering och kontinuerlig

variant

4.1

Optimering av sökning

Uttömmande sökningar är väldigt ineffektiva att utföra för större problem. Så jag valde att skriva ihop ett program som gör en sökning efter strategi med bästa väntevärde. Genom att börja med en startvektor, så gör programmet att den testar alla möjliga ändringar på vektorn genom att höja och sänka värden A.6.

För att kunna kolla alla möjliga ändringar av en vektor så har jag nästlat ihop två for-loopar där i den ytte loopen väljer vi värdet vi skall höja med 1 och i den inre så väljer vi värdet vi skall sänka med 1. Undantag göres om talet vi skall sänka är 1 högre än den vi ökar, eftersom det skulle betyda att man får samma strategi igen. I den inre loopen så beräknas även väntevärdet för just den ändringen som gjorts.

(22)

Figur 4.2: Optimering från en mer passiv strategi.

Om väntevärdet var bättre än föregående så sparas det ner som det bästa möjliga just nu. Sedan börjar vi om med for-looparna igen, med den bästa möjliga förändrade vektorn som inkommande argument. Om ingen ändring har varit en förbättring så har vi nått den strategi som har det lägsta vän-tevärdet.

Jag testade med 15 distinkta strategier, även de som inte var begränsade heltalspartitioner och alla landade i samma strategi (4,3), vilket skulle tyda på att de inte finns några lokla minimum som man kan fastna i. I figur 4.1 och 4.2, kan vi se hur det konvergerar från två olika håll.

4.2

Kontinuerlig variant

En variant av spelet är när tiden samt steglängden är kontinuerlig. Om vi bestämmer oss för att stopparen uniformt slumpat väljer en tid mellan 1 till 6 sekunder, så gäller fortfarande formeln för väntevärdet. Genom att använda mig av matlabs inbyggda optimeringsrutin fmincon [5], så kunde vi finna bästa väntevärdet genom låta funktionen jobba sig igenom maximalt antal element i vektorn och finna bästa väntevärdet för respektive längd A.7. I figur 4.3, kan vi se resultatet från denna variant. Strategierna skrivs utan 1:or. Den sista optimeringen som sker är när optimeringen tvingas bestå utav minst 30 positioner, därmed är den endast fylld med ettor och väntevärdet är då givetvis 30.

Intressant var att resultatet från denna optimeringsfunktion nästan var detsamma som från den tidsdiskreta modellen.

(23)

Figur 4.3: Kontinuerlig optimering med fmincon, en strategi per rad (utan ettor), med väntevärde på sista positionen, bästa strategi märkt i rött.

(24)

Kapitel 5

Diskussion

Tyvärr så hade inte problemet en helt klart bästa strategi, eftersom strategier ofta förlorar emot liknande strategier som är lite mera aggressiva. Men om man väljer en strategi i hemlighet så bör man välja den med bästa väntevärde. Något som jag var intresserad av att kolla på var om spelet inte hade regeln: gå tillbaka till ruta 0 som straff. Utan att man fick gå tillbaka de senaste 2 steglängderna, eller möjligen en variant där man får gå tillbaka 5 steg. Efter att ha kollat på den första varianten, så insåg jag att det var mycket svårt att beräkna ett väntevärde. Eftersom väntevärdet i första posi-tionen blir beroende av alla de positioner som inte skickar tillbaka spelaren till start, som i sin tur är beroende av väntevärdet från första positionen. Den andra varianten är nog också svår att lösa, eftersom den också fastnar i en liknande position. Dessutom måste en strategi vara definerad för varje steg-position i spelet.

Jag började även kolla på variant där minsta steglängd ökas till 2 istället för 1. Denna variant gör att spelarna alltid har en sannolikhet att få börja om från början. Detta kan fungera för kortare spel. Om spelet blir för långt i denna variant så är sannolikheten stor att man fastnar i en oändlig loop där ingen spelare har en möjlighet att avsluta spelet. Detta lämnas öppet för fortsatta undersökningar.

(25)

Litteraturförteckning

[1] J.M Harris, J.L Hirst, M.J Mossinghoff, Combinatorics and Graph Theory Second Edition, Springer, 2000

[2] J.R Norris, Markov Chains, Cambridge University Press, 1997

[3] Bubbelsortering, 2015-06-26, https://sv.wikipedia.org/wiki/Bubbelsortering

[4] Composition (combinatorics), 2015-10-13,

https://en.wikipedia.org/wiki/Composition_(combinatorics)

(26)

Bilaga A

Simuleringskod

A.1

CompareStrats

function [ winner_by ] =

CompareStrats( Strat_1, Strat_2, n, NumOfGames )

%fyll ut med ettor i strategierna, så att vi har en summa av total %steglängd.

%fyll även ut med 0:or, så att vektorerna är lika långa, %så vi kan sätta dem i en matris (Strategies)

Strat_1 = AddOnes(Strat_1,n); Strat_1 = AddZeroes(Strat_1,n); Strat_2 = AddOnes(Strat_2,n); Strat_2 = AddZeroes(Strat_2,n); Strategies = [Strat_1;Strat_2];

%räkna antalet vinster respektive strategi har.

winner_by = [0 0];

%NumOfGames är antalet simuleringar av spelet vi vill göra

for games=1:NumOfGames

CurrentPos=[0 0]; %Start position

CurrentMove=[1 1]; %Börja spelet i rörelse %Börja spelet med första steglängden

CurrentStrat=[1 1];

StepsToTake = [Strat_1(1), Strat_2(1)];

%kasta tärningen, reslutat mellan 1 till 6

DiceRoll = randi(6);

while max(CurrentPos) < n %så länge ingen har gått i mål %DiceRoll är antalet sekunder till vi ska vänta %innan vi vänder oss om, som stoppare.

if DiceRoll == 0

(27)

%om någon är i rörelse, skicka dem till startposition %annars så väljer vi nästa steglängd.

[CurrentPos, CurrentStrat] =

SendBackIfMov(CurrentMove, CurrentPos, CurrentStrat);

%Updatera sedan antalet steg vi ska gå, baserat %på våran nuvarande strategi

StepsToTake =

StepStrat(StepsToTake,CurrentStrat, Strategies);

%kasta tärningen igen.

DiceRoll = randi(6);

%Sätt båda strategierna i rörelse igen. %Stopparen börjar kasta tärningen igen.

CurrentMove = [1 1];

end

%Gå ett steg, om vi är i rörelse

CurrentPos = CurrentPos + CurrentMove;

%Om vi inte ska ta fler steg så kommer %ReduceSteps att göra att vi står stilla.

[StepsToTake, CurrentMove] =

ReduceSteps(StepsToTake,CurrentMove);

%Nu har vi väntat 1 sekund, så ta bort den.

DiceRoll = DiceRoll − 1;

end

%den strategi som kom i mål först, är den strategi som %räknas som vinnare.

[M,I] = max(CurrentPos);

winner_by(I) = winner_by(I) + 1;

end end

A.2

Script för strategier

n = 30; %spelets längd

nm = 2; %räknare av strategier testade

%Testvector är den som vi modifierar för skapa listan med vektorer

TestVector = 1;

%tärningens maxvärde

MaxValue = 6;

%position i vektorn som skall ändras, om denna blir 0 så har vi ökat %första värdet större än maxvärdet, och genereringen skall avslutas.

Pos = 1;

prev_strat_est_rolls = n;

%vektor som innehåller alla testade vektorer

AllTested = 1;

(28)

%första kolumnen är nummer på strategin, andra är index där %vektorn börjar inne i AllTested, tredje kolumnen beskriver vart %den vektorn tar slut.

AllTestedMat = [1 1 1]; CurrentBestEst = n; CurrentWinningVector = 1;

TestVectorWithOnes = AddOnes(TestVector,n);

while Pos ~= 0;

%Smält samman två ettor till en tvåa

[TestVector, Pos] =

IncreasingVector( TestVector, Pos, MaxValue, n ); TestVectorWithOnes = AddOnes(TestVector,n); est_rolls = EstRolls(TestVectorWithOnes,n);

%om vi hittar en strategi med lägre väntevärde än den bästa %vi hittat hitills, så sparar vi ner informationen om %den vektorn

if est_rolls <= CurrentBestEst CurrentBestEst = est_rolls;

CurrentWinningVector = TestVector;

end

%om väntevärdet är 5 högre än sin föregångare ska vi gå %upp ett steg i trädet.

if prev_strat_est_rolls < (est_rolls − 5) Pos = −1;

prev_strat_est_rolls = n+1; %nollställning av väntevärde

else

prev_strat_est_rolls = est_rolls;

end

%pos = −1 betyder att vi ska gå baklänges i vektorn, hitta %där en skillnad finns, öka talet längst till vänster med 1 %och sedan fortsätta

if Pos == −1 TestVector(end) = []; for i = length(TestVector):−1:2 if TestVector(i) ~= TestVector(i−1) Chop = IncreasingVector(TestVector(i:end),1,MaxValue,n); TestVector = VectorFix(TestVector, Chop,i); Pos=length(TestVector)+1; break; end if i == 2 [TestVector, Pos] = IncreasingVector(TestVector,1,MaxValue,n); end end end

(29)

%Här skapas tabellen och vektorn med information om de %vektorer vi vill testa

AllTested = [AllTested,TestVector]; AllTestedMat(nm,1) = nm;

AllTestedMat(nm,2) = AllTestedMat(nm−1,3)+1;

AllTestedMat(nm,3) = AllTestedMat(nm,2) + length(TestVector)−1; nm = nm+1;

end

%Ta bort skräpdata

AllTested(end) = []; AllTestedMat(end,:) = [];

A.3

Finns Sten Sax Påse

function [ RPS, RPS_mat ] =

Find_RPS( AllVect, AllMat, n, NumOfGames )

%RPS är Rock Paper Scissor

%spara ner den strategi som hade flest antal vinster

[M I] = max(AllMat);

current_strat = AllVect( AllMat(I(6),2) : AllMat(I(6),3)); index_count = zeros(1,length(AllMat));

index_count(1) = I(6); best_strat = current_strat;

RPS = current_strat; RPS_mat = [1 ,1,length(RPS)]; endgame=0; nm = 2; i=1; countfound=0;

while endgame == 0

if not(ismember(i,index_count(2:end)))

%jämnför alla strategier mot den första vi valde.

if nm > 3 winner =

CompareStrats(current_strat, best_strat, n, NumOfGames); [MW IW] = max(winner); if IW == 2 RPS = [RPS, best_strat]; RPS_mat(nm,1) = nm; RPS_mat(nm,2) = RPS_mat(nm−1,3)+1; RPS_mat(nm,3) = length(RPS); break end end

%jämnför den nuvarande strategin mot alla andra.

strat = AllVect(AllMat(i,2):AllMat(i,3));

winner = CompareStrats(current_strat, strat, n, NumOfGames); [M I] = max(winner);

if I == 2

current_strat = AllVect(AllMat(i,2):AllMat(i,3)); index_count(countfound+2) = i;

(30)

RPS_mat(nm,1) = nm; RPS_mat(nm,2) = RPS_mat(nm−1,3)+1; RPS_mat(nm,3) = length(RPS); nm=nm+1; i = 1; countfound = countfound +1; else if i > length(AllMat)

%ingen sten sax påse funnen.

disp('No RPS found');

return end i = i+1; end else if i > length(AllMat)

%ingen sten sax påse funnen.

disp('No RPS found');

return end

i = i+1;

end

%om vi har samma strategi som vi började med %så ska vi avsluta sökningen

if nm > 3

if AddZeroes(current_strat,n) == AddZeroes(best_strat,n) endgame = 1;

end end

end%end while, endgame

%Utskrift

for j = 1:RPS_mat(end,1) disp('******')

vect = RPS(RPS_mat(j,2):RPS_mat(j,3)); disp(vect)

disp(EstRolls(vect,n))

[Rolls, Chance] = FindRolls(StrategyMatrix(AddOnes(vect,n),n),0.5); disp(Rolls)

disp(Chance)

end

end%end function

A.4

DuelStrats

function [ AllVectorsMat ] =

DuelStrats(AllVectors, AllVectorsMat,n,NumOfGames) AllVectorsMat(:,4) = 0; %Antalet vinster

AllVectorsMat(:,5) = 0; %Antaler nära lika

(31)

%börja med första fram till näst sista

for i = 1:(AllVectorsMat(end,1)−1)

%möt alla strategier under den.

for j =i+1:AllVectorsMat(end,1)

Strat1 = AllVectors(AllVectorsMat(i,2):AllVectorsMat(i,3)); Strat2 = AllVectors(AllVectorsMat(j,2):AllVectorsMat(j,3)); Winner = CompareStrats(Strat1,Strat2,n,NumOfGames);

[M I] = max(Winner);

%om man vinner med 5% marginal, så räknas det som lika

if M <= (NumOfGames*0.55)

AllVectorsMat(i,5) = AllVectorsMat(i,5) +1; AllVectorsMat(j,5) = AllVectorsMat(j,5) +1;

else %annars så är den som vann mest vinnaren.

if I == 1 AllVectorsMat(i,4) = AllVectorsMat(i,4) +1; else AllVectorsMat(j,4) = AllVectorsMat(j,4) +1; end end end end

%summera vinster och lika i sista kolumnen

AllVectorsMat(:,6) = sum(AllVectorsMat(:, 4:5), 2);

end

A.5

Top10percent

function [ R_vect, R_mat ] = Top10percent( AllVectors, AllVectorsMat ) top10p = round(AllVectorsMat(end,1)*0.1);

R_mat = zeros(top10p,6); R_vect = 0;

nm = 2; %vector lenght counter

for i=1:length(R_mat)

[M I] = max(AllVectorsMat); %find max value

R_mat(i,:) = AllVectorsMat(I(6),:); %store it

AllVectorsMat(I(6),:) = []; %remove max value for next iteration

R_vect = [R_vect, AllVectors(R_mat(i,2):R_mat(i,3))]; %add vector

R_mat(i,1) = i; R_mat(i,2) = nm; R_mat(i,3) = length(R_vect); nm = R_mat(i,3)+1; end end

A.6

Optimeringsprogram

(32)

vector = AddZeroes(AddOnes(vector,n),n); current_best_est = EstRolls(vector,n); prev_best_vect = vector; changes_made = 1;

while changes_made == 1

current_best_vect = prev_best_vect; changes_made = 0;

for i=5:−1:0 %talet vi ska öka

if ismember(i,current_best_vect)%om det finns

for j=1:6 %talet vi ska minska

if ismember(j,current_best_vect) %om det finns

if j == i+1

%gör inget, meningslös ändring

else

%hitta positioner vi vill ändra

INDEX_i = find(current_best_vect==i,1,'first'); INDEX_j = find(current_best_vect==j,1,'last');

%temp vektor vi ska ändra i

change_vector = current_best_vect;

change_vector(INDEX_i) = change_vector(INDEX_i)+1; change_vector(INDEX_j) = change_vector(INDEX_j)−1; new_est = EstRolls(change_vector,n);

%spara den bästa

if new_est < current_best_est current_best_est = new_est; prev_best_vect = change_vector; changes_made = 1; end end end end %for j end end%for i %print dispvector = prev_best_vect; dispvector(dispvector==0) = []; dispvector(dispvector==1) = []; disp([EstRolls(dispvector,n) dispvector]) pause end%while

%Ta bort ettor och nollor på returen.

R_vector = prev_best_vect; R_vector(R_vector==0) = []; R_vector(R_vector==1) = [];

(33)

A.7

fmincon script

n=30; x = ones(1,n); i = 0; for j =n−10:n UB = ones(1,j)*7; LB = ones(1,j)*1; x = LB; A = fmincon(@(x) minEST(x,n),x,[],[],x,n,LB,UB); i = i +1; B(i,:) = AddZeroes(A,n); C(i) = EstRolls(A, n); end %printout for i=1:size(B) dispvector = B(i,:);

dispvector(dispvector<1.01) = []; %ta bort ettor och nollor

disp([dispvector C(i)])

(34)

Bilaga B

Stödprogram

B.1

StrategyMatrix

function [ output_mat ] = StrategyMatrix( strat, n )

%producera övergångsmatrisen för en strategi %baserat på spelets längd n if sum(strat) < n strat = AddOnes(strat,n); end output_mat = zeros(length(strat)+1); for i=1:length(strat)

%sannolikheten att avancera

output_mat(i,i+1) = (7 − strat(i)) / 6;

%sannolikheten att komma till position 0

output_mat(i,1) = 1 − ( (7−strat(i)) / 6);

end

%vi har nått mål, vi kan inte forsätta längre.

output_mat(length(output_mat),length(output_mat)) = 1;

end

B.2

AddOnes

function [ vector ] = AddOnes( vector, n )

%Lägg till ettor i vektorn, så vektorns summa är n

vector = [vector, ones(1,n − sum(vector))];

end

B.3

AddZeroes

function [ vector ] = AddZeroes( vector, n )

(35)

vector=[vector, zeros(1,n − length(vector))];

end

B.4

IncreasingVector

function [ vector, pos ] =

IncreasingVector( vector, pos, max_value, max_sum )

%funktionen gör av av två saker

%om vi kan lägga till 2or gör den det..

%annars så ökar vi första index med 1 och returnerar bara det.

if pos == 1

vector = vector(1) + 1; pos = 2;

if vector(1) > max_value vector(1) = max_value;

%vi kan inte fortsätta, avsluta utökningen av vektorn

pos = 0; end return; end vector(pos) = 2; pos = pos +1; if sum(vector) > max_sum vector(end) = 1;

pos = −1; %signal att vi ska genomföra "chopping"

end end

B.5

EstRolls mat

function [ R_vector ] =

EstRolls_mat( AllVectors, AllVectorsMat, n )

%Beräkna väntevärdet för en mängd av strategier till %spelet av längden n R_vector = zeros(1,length(AllVectorsMat)); for i=1:length(AllVectorsMat) strat = AllVectorsMat(i,2):AllVectorsMat(i,3); R_vector(i) = EstRolls(AllVectors(strat,n)); end end

B.6

FindRolls

function [ num_of_rolls,chance_at_end ] = FindRolls( Strat_matrix, chance )

(36)

%sannolikhet att komma i mål

%detta görs genom att multiplicera övergångsmatrisen med sig själv %tills vi minst har chance sannolikhet att vara i mål.

V = 1;

V = AddZeroes(V,length(Strat_matrix)); rolls = zeros(1,length(V));

num_of_rolls = 0;

while rolls(end) < chance

num_of_rolls = num_of_rolls +1; rolls = V*Strat_matrix^num_of_rolls; end chance_at_end = rolls(end); end

B.7

EstRolls

function [ est ] = EstRolls( vect,n)

%returnera väntevärdet för en strategi för ett spel om längden n

strat_mat = StrategyMatrix(vect,n); mat_size = size(strat_mat)−1; strat_mat = strat_mat(1:mat_size,1:mat_size); strat_mat = inv(eye(mat_size)−strat_mat); est = sum(strat_mat(1,:)); end

B.8

StepStrat

function [ Steps_to_take ] = StepStrat(Steps_to_take,Current_strat, All_strat )

%bestäm hur många steg en viss strategi skall ta.

for i = 1:length(Current_strat)

Steps_to_take(i) = All_strat(i,Current_strat(i));

end end

B.9

VectorFix

function [ vector_A ] = VectorFix( vector_A, vector_B ,index )

%sätt samma vektor A och B med varandra i position index

while length(vector_A) >= index vector_A(end) = [];

end

vector_A = [vector_A vector_B];

(37)

B.10

SendBackIfMov

function [ All_pos, Current_strat ] =

SendBackIfMov(All_mov, All_pos, Current_strat)

%om spelaren befinner sig i rörelse skall den skickas till %position 0 och börja om spelet med den första strategin. %Annars så skall den välja nästa strategi.

for i = 1:length(All_mov) if All_mov(i) == 1 All_pos(i) = 0; Current_strat(i) = 1; else Current_strat(i) = Current_strat(i)+1; end end end

B.11

ReduceSteps

function [ Steps_to_take,All_mov ] = ReduceSteps(Steps_to_take,All_mov)

%reducera mängden steg en strategi tar med 1.

%om vi inte ska ta fler steg så ändras status till stillastående

Steps_to_take = Steps_to_take −1; for i = 1: length(Steps_to_take) if Steps_to_take(i) <= 0 Steps_to_take(i) = 0; All_mov(i) = 0; end end end

References

Related documents

➢ Efter två veckor kan 15 gauge nål användas och punktionen ske enligt gällande rutiner. steril rock och

Med de orden från en guate- maltekisk flykting i Mexico möt- tes en kamrat från Lund som till- sammans med två andra reser runt i Centralamerika för

ten får inte urholkas; det sker om man tar reformen till in- täkt för att inrätta en massa nya byråkrattjänster?. Fyra

Inte så att Nej till EU skulle ställa upp som eget parti; snarare blir det någon form av arbete för olika nejpartier resp nejlistor. Motioner

Det täcker allt från armeer av identiska elitsoldater till en kopia för att ersätta ett barn, som avlidit eller en kopia av mig själv så attjag får ett evigt Ii

I veckan har vi börjat med ”Grej of the day”(GOTD) Det blev igelkotten som första grej. Då berättar jag om igelkotten .Vi ser på bilder och pratar om vad barnen vet om den.

Sedan driften av njurbytesprogrammet STEP över- fördes till Scandiatransplant har totalt 7 transplan- tationer genomförts, och de två senaste njurbytena genomfördes mellan två

Om någon har höjt till höger om dig och spelet är typiskt eller tufft, bör du begränsa ditt spel till händerna i grupp 1 och 2.. Mot en extremt tajt spelare i ett tufft spel kan