geneettiset algoritmit ja sukupuolten...
TRANSCRIPT
Mat-2.108 Sovelletun matematiikan erikoistyöt
Geneettiset algoritmit ja sukupuolten taistelu
Pasi Virtanen 45787U 17.08.2005
1. Johdanto ................................................................................................................................................ 4 2. Perusteet ................................................................................................................................................ 5
2.1 Geneettiset algoritmit...................................................................................................................... 5 2.1.1 Geneettisten algoritmien yleinen rakenne................................................................................ 5 2.1.2 Geneettisen algoritmin käytännön toteutus.............................................................................. 6
2.2 Sukupuolten taistelu........................................................................................................................ 7 3. Geneettiset algoritmit ja sukupuolten taistelu....................................................................................... 9
3.1 Strategian esitys geneettisen algoritmin tarvitsemassa muodossa .................................................. 9 3.2 Hyvän strategian ominaisuuksia ................................................................................................... 11 3.3 Geneettisen algoritmin toteutukseen liittyvistä valinnoista .......................................................... 13
3.3.1 Peliparien valinta, pisteytys ja pelin pelaaminen ................................................................... 13 3.3.2 Risteytys, mutaatiot ja yhteistyötavoite ................................................................................. 14
4. Geneettisen algoritmin käytännön toteutus......................................................................................... 16 4.1 Ohjelman pääluokka GABattleOfSexes ....................................................................................... 16 4.2 Kierroksen pelaava luokka PlayRound ......................................................................................... 16 4.3 Risteytyksen suorittava luokka Crossover .................................................................................... 17 4.4 Mutaatiot tekevä luokka Mutate ................................................................................................... 17
5. Käytännön tuloksia ............................................................................................................................. 17 5.1 Käytännön tuloksia parametrien alkuarvoilla ............................................................................... 17 5.2 Pelikierroksen pituuden ja mutaatiotodennäköisyyden vaikutus .................................................. 20 5.3 Risteytysprosessin muuttamisen vaikutus algoritmin toimintaan................................................. 24 5.4 Parhaan mahdollisen strategian löytäminen muuttumatonta strategiaa vastaan ........................... 28
6. Yhteenveto ja pohdintaa...................................................................................................................... 36 Viitteet..................................................................................................................................................... 38 Liite 1: Ohjelmalistaus ............................................................................................................................ 39
1. Johdanto Geneettiset algoritmit tarjoavat voimakkaan työkalun etenkin sellaisten ongelmien ratkaisemiseen
joiden ratkaisu perinteisin menetelmin on liian työlästä, kunhan ratkaisuksi riittää joku riittävän hyvä
ratkaisu. Geneettiset algoritmit pyrkivät jäljittelemään toiminnassaan biologista evoluutiota siten, että
ratkaisua ongelmaan haetaan ratkaisuyritteiden populaatiosta josta muodostetaan uusia yritteitä
risteytyksillä ja mutaatioilla siten, että tämän hetkisistä ratkaisuista parhaimpia risteytetään keskenään
ja syntyvät uudet ratkaisut altistetaan satunnaisesti mutaatioille.
Yksi geneettisten algoritmien parhaista puolista on se, että ne ovat yksinkertaisia toteuttaa eivätkä ne
aseta juuri mitään rajoituksia sille ongelmalle jota yritetään ratkaista. Tarvitaan ainoastaan joku tapa
esittää ratkaisuyritteet binäärilukujonona ja joku funktio jolla näiden keskinäistä paremmuutta kyseisen
ongelman ratkaisemisessa voidaan mitata. Täten geneettiset algoritmit soveltuvatkin mainiosti hyvien
strategioiden hakemiseen normaalimuodossa oleville peleille koska näistä tiedetään aina kunkin
pelaajan strategiajoukko ja pelaajien saamat hyödyt kullakin pelikierroksella valituille strategioille.
Tämä takaa sen, että kukin strategia pystytään esittämään geneettisen algoritmin vaatimassa muodossa
ja eri strategioille on olemassa luonnollinen hyvyyden mitta peleistä saadun hyödyn muodossa.
Tässä työssä sovelletaan geneettisiä algoritmeja sukupuolten taisteluna tunnettuun yksinkertaiseen
peliin kun sitä pelataan toistetusti. Sukupuolten taistelussa oleellista on, että pelin molemmille
osapuolille on ensiarvoisen tärkeää tehdä yhteistyötä toisen pelaajan kanssa. Tutkitaan erityisesti sitä
miten yhteistyö kehittyy geneettisen algoritmin eri sukupolvien välillä ja muodostuuko ennen pitkää
jokin tasapainostrategia vai johtaako pelin luonnollinen epäsymmetrisyys siihen, että erityyppiset
yhteistyöhön kykenevät strategiat jäävät taistelemaan elintilasta keskenään. Tutkitaan myös sitä,
minkälaisia erilaisia tulkintoja tähän voidaan liittää kun risteytettävät strategiat valitaan eri tavoin.
2. Perusteet
2.1 Geneettiset algoritmit
2.1.1 Geneettisten algoritmien yleinen rakenne
Geneettiset algoritmit kehitti kerran John Holland Michiganin yliopistossa 1960-luvulla ensimmäisten
evoluution matemaattisten mallien innoittamana. Holland järkeili, että jos biologisten organismien
evoluutio on mallinnettavissa matemaattisesti niin ehkä samalla tavalla voidaan luoda kehittyviä
tietokoneohjelmia. Vaikka 1960-luvulla monet tutkijat käyttivät evoluutiota jäljitteleviä
ongelmanratkaisumenetelmiä, niin perusteoksena pidetään Hollandin 1975 julkaistua kirjaa Adaptation
in Natural and Artificial Systems: An Introductory Analysis with Applications to Biology, Control, and
Artificial Intelligence jossa ensimmäistä kertaa systemaattisesti formuloitiin geneettinen algoritmi sen
nykyään tunnetussa muodossa. [1]
Geneettisen algoritmin yleinen rakenne on seuraava:
• Asetetaan sukupolvien määrää algoritmin ajossa kuvaava aikamuuttujan arvoksi 1
• Generoidaan, usein satunnaisesti, alkupopulaatio
• Lasketaan populaation yksilöiden hyvyys jollain tietyllä arviointifunktiolla f(X)
• Testataan täyttääkö populaatio valitun lopetuskriteerin
• Toistetaan seuraavaa kunnes lopetuskriteeri täyttyy :
o Kasvatetaan aikamuuttujaa yhdellä
o Valitaan populaatiosta risteytettävät ratkaisut
o Yhdistetään valittujen vanhempien geeneistä seuraavan sukupolven yksilöt
o Altistetaan jälkeläiset mutaatioille
o Lasketaan uuden sukupolven yksilöiden hyvyys funktiolla f(X)
2.1.2 Geneettisen algoritmin käytännön toteutus Algoritmin populaation yksilöitä kuvataan binäärilukujonoina, nyt kun kyseessä on peliteoreettinen
tapaus niin jokainen tällainen binäärilukujono vastaa jotain tiettyä strategiaa. Alkupopulaatio voitaisiin
siis valita tunnettujen strategioiden joukosta, mutta tässä työssä kuitenkin käytetään satunnaista
alkupopulaatiota.
Arviointifunktio on periaatteessa peleille määritelty luonnollisella tavalla. Kutsutaan tästä eteenpäin
pelissä pelaajan saavuttamaa hyötyä pisteiksi, jolloin tietyn strategian hyvyys on sen strategian
saavuttama pistemäärä peliä pelattaessa. Se tapa millä peliä algoritmin puitteissa pelataan voidaan
kuitenkin valita monin eri tavoin ja eri tavat johtavat aivan erilaisiin tulkintoihin ja erilaiseen
evoluutioprosessiin. Tässä työssä arviointifunktion arvo lasketaan siten, että populaation jäsenet
pelaavat peliä saman määrän jokaista mahdollista populaatiossa olevaa vastustajaa vastaan.
Luonnollisia tulkintoja tälle ovat minkälaiseksi populaatio muuttuu jos sen jäsenten välinen kilpailu on
kuvattavissa käytetyn pelin kaltaisella mallilla ja minkälaisia ovat tämän pelin tasapainostrategiat eli
strategiat jotka ovat siinä mielessä parhaita, että niitä ei kannata muuttaa jos muutkin pelaajat käyttävät
yhtä vahvoja strategioita. Muita vaihtoehtoja arviointifunktiolle olisivat esimerkiksi se, että populaation
yksilöt pelaisivat peliä jotain valittua strategiaa tai strategioiden joukkoa vastaan jolloin luonnollinen
tulkinta algoritmille olisi se, että yritetään löytää jokin strategia joka voittaa testistrategioina käytetyt
tai sitten voitaisiin valita ne yksilöt jotka joutuvat pelaamaan toisiaan vastaan jollain kriteerillä tai
satunnaisesti, jolloin tulkinnat riippuisivat valituista kriteereistä.
Jos populaation yksilöiden arviointi on suoritettu ja valittu lopetus kriteeri ei ole täyttynyt, täytyy
jollakin menetelmällä valita ne yksilöt joista risteytetään seuraavan sukupolven ratkaisuehdokkaita.
Perusajatus vanhempien valinnassa on se, että halutaan pyrkiä yhdistämään parhaiden ratkaisujen
ominaisuuksia siinä toivossa, että muodostunut ratkaisu olisi parempi kuin kumpikaan vanhempansa.
Valintakriteeri halutaan sellaiseksi, että se suosii parempia yksilöitä, mutta valitsee kuitenkin
heikompiakin yksilöitä jotta populaatio ei muodostu liian yksipuoliseksi liian nopeasti. Valintaa varten
halutaan arviointifunktion arvot usein skaalata jotenkin. Tällä voidaan vaikuttaa siihen kuinka paljon
parempia pisteitä saaneita yksilöitä halutaan suosia. Tässä työssä käytetään valintakriteerinä
niinkutsuttua ruletti-menetelmää jossa kunkin yksilön todennäköisyys tulla valituksi risteytykseen on
suoraan verrannollinen sen yksilön skaalattuun arviointifunktion arvoon.
Kun risteytettävät yksilöt on valittu on itse risteytyksen aika. Tässä tapauksessa risteytys halutaan
suorittaa siten, että geneettinen koodi pysyy kaikilla yksilöillä saman mittaisena. Nyt kun perimää
kuvataan binäärilukujonona, tämä tapahtuu yksinkertaisesti siten, että valitaan satunnaisesti kohta, josta
vanhempien perimä katkaistaan ja lapsen perimä muodostetaan liittämällä toisen vanhemman perimän
alkuosa toisen vanhemman perimän loppuosaan.
Risteytyksen jälkeen uusi ratkaisukokelas altistetaan satunnaisesti mutaatioille. Mutaatioiden tarkoitus
on varmistaa, ettei ratkaisua haettaessa juututa lokaaliin optimiin joka on erityisen tärkeää jos on syytä
olettaa, että alkupopulaatioksi valitut ratkaisut eivät ole lähellä optimaalista. Mutaatioiden halutaan
esiintyvän niin usein, että algoritmi ei jää lokaaliin optimiin liian pitkäksi aikaa, mutta mutaatiot
halutaan pitää niin harvinaisina, että algoritmi silti konvergoi johonkin ratkaisuun. Mutaatiot voitaisiin
suorittaa periaatteessa monin eri tavoin, mutta nyt kun halutaan kunkin ratkaisuehdokkaan geneettisen
koodin pysyvän aina samanmittaisena niin toteutetaan mutaatiot yksinkertaisimmalla tavalla siten, että
valitaan jokin pieni todennäköisyys p ja kullekin geenille muutetaan sen arvo nollasta ykköseksi tai
päinvastoin todennäköisyydellä p. Tutkitaan myös p:n valinnan vaikutusta algoritmin käyttäytymiseen.
2.2 Sukupuolten taistelu
Sukupuolten taisteluna, englanninkieliseltä nimeltään Battle of the Sexes, tunnettu peli, on määritelty
seuraavasti [2]: Liisa ja Pekka päättävät molemmat samanaikaisesti työpaikoillaan illan huvituksista.
Molemmilla on kaksi vaihtoehtoa, joko oopperaan tai nyrkkeilyotteluun. Kumpikin pelaajista viettäisi
illan mielummin samassa paikassa kuin erikseen, mutta Liisa olisi mielummin yhdessä oopperassa kun
taas Pekka viihtyisi paremmin nyrkkeilyottelussa. Pelaajienn saavuttamat hyödyt menevät nyt oheisen
matriisin mukaisesti
Pekka/Nyrkkeilyottelu Pekka/Ooppera
Liisa/Nyrkkeilyottelu Pekka: 2 Liisa: 1 Pekka: 0 Liisa: 0
Liisa/Ooppera Pekka: 0 Liisa: 0 Pekka: 1 Liisa: 2
Taulukko 1: Sukupuolten taistelu
Peliteoriasta tiedetään, että tällä pelillä on puhtaille strategioille, ts. strategioille joissa pelaajien
tekemät valinnat ovat deterministisiä, kaksi Nash-tasapainoa. Nash-tasapaino on strategiajoukko
kaikille pelaajille josta kenenkään pelaajan ei kannata yksin poiketa jos muut pelaajat pitävät
strategiansa ennallaan. Nash-tasapainot ovat nyt se, että molemmat pelaajat valitsevat oopperan ja se,
että molemmat pelaajat valitsevat nyrkkeilyottelun. Sukupuolten taistelun problematiikka on siinä, että
nämä tasapainot eivät kerro oikeastaan mitään siitä minkälaisella strategialla peliä kannattaisi pelata,
sillä molempien valitessa itselleen suotuisimman vaihtoehdon päädytään molemmille huonoimpaan
ratkaisuun.
Sekastrategioille, eli sellaisille strategioille joissa pelaaja valitsee pelaamansa vaihtoehdon jonkun
todennäköisyysjakauman mukaan, löytyy vielä kolmas Nash-tasapaino. Tässä tasapainossa Pekka pelaa
vaihtoehdon nyrkkeily todennäköisyydellä 2/3 ja vaihtoehdon ooppera todennäköisyydellä 1/3. Liisa
vastaavasti pelaa ooppera todennäköisyydellä 2/3 ja nyrkkeily todennäköisyydellä 1/3. Jos tarkastellaan
näitä tasapainoja pelissä saavutettavan hyödyn oletusarvon mielessä niin nähdään, että
sekastrategiatasapainolle molempien pelaajien odotusarvo on 961*
32*
312*
31*
32
=
+
. Puhtaille
strategioille saadaan odotusarvot 2 toiselle pelaajalle ja 1 toiselle. Tässä mielessä siis kummallekin
pelaajalle molemmat puhtaiden strategioiden tasapainot ovat mieluisampia kuin sekastrategiatasapaino.
Kuten hyötymatriisista nähdään, sukupuolten taistelun kantavana ideana on pelaajien välinen
yhteistyökyky. Vaikka kumpikin pelaaja hyötyy näennäisesti eniten itselle mieluisamman vaihtoehdon
pelaamisesta, niin kumpikin pelaaja saa huonoimman mahdollisen lopputuloksen pelatessaan aina
pelkästään itsepäisestä omaa vaihtoehtoaan. Jos peliä pelataan vain kerran ilman mitään etukäteistietoa
vastustajan preferensseistä niin peli onkin pitkälti arpapeliä. Peli saakin lisää luonnetta kun sitä
pelataan toistetusti samaa vastustajaa vastaan koska tällöin pelaajilla on mahdollisuus strategiallaan
lähettää toiselle pelaajalle signaaleja joiden avulla pelaajien on mahdollista kehittää yhteistyökykyään
ja täten pelissä saamaansa tulosta.
3. Geneettiset algoritmit ja sukupuolten taistelu
3.1 Strategian esitys geneettisen algoritmin tarvitsemassa muodossa
Geneettisiä algoritmeja on käytetty ennenkin peliteorin tutkimiseen. Ensimmäinen julkaisu aiheesta on
vuodelta 1987 jossa Fujiki ja Dickinson sovelsivat geneettistä algoritmita toistetusti pelattuun vangin
ongelmaan. [3] Vangin ongelmaan geneettisiä algoritmeja on sovellettu useastikin, rohkaisevin
tuloksin. Tässä työssä kuitenkin valittiin tarkastelun kohteeksi hieman harvinaisempi peli.
Sukupuolten taistelullekin on pelin yksinkertaisuuden vuoksi helposti formuloitavissa esitys
pelistrategioille joihin voidaan sitten geneettisiä algoritmeja soveltaa. Erityisen kätevää on, että
jokaisella pelaajalla on vuorollaan vain kaksi erilaista vaihtoehtoa joita kuvaavat siis nyt 0 ja 1.
Strategiat saadaan täten pidettyä suhteellisen pienikokoisina.
Nyt kun peliä pelataan toistetusti kutakin vastustajaa vastaan, on luonnollista, että kussakin pelin
vaiheessa pelaajan tekemä valinta riippuu pelissä aiemmin tapahtuneista siirroista. Strategian kertova
binäärilukujono siis kertoo nyt deterministisesti pelaajan valitseman siirron kun tiedetään pelin historia
siihen asti. Tässä toteutuksessa siirto tehdään kahden edellisen kierrosten lopputulemien perusteella.
Strategiaa esittävään binäärilukujonoon tarvitaan siis valittu siirto kaikille mahdollisille kahden siirron
historioille ja lisäksi erikseen pelin ensimmäiselle ja toiselle siirrolle.
Kokonaisuudessaan strategiaa kuvaavan binääriluvun rakenne on seuraava. Taulukossa historia
tarkoittaa pelissä tapahtuneita valintoja siten, että ensimmäinen luku on pelaajan itsensä tekemä valinta
ja jälkimmäinen vastustajan valinta. Kyseinen bitti kertoo siis mikä valinta tehdään kyseistä historiaa
vastaavassa tilanteessa:
Bitti Historia Bitti Historia 1 - (alku) 12 01,10 2 00 13 01,11 3 01 14 10,00 4 10 15 10,01 5 11 16 10,10 6 00,00 17 10,11 7 00,01 18 11,00 8 00,10 19 11,01 9 00,11 20 11,10 10 01,00 21 11,11 11 01,01 Taulukko 2: Strategioiden esitys geneettisessä algoritmissa sukupuolten taistelulle
Kunkin strategian esitys on siis pituudeltaan 21 bittiä. Huomattavaa on, että jokaisessa strategiassa on
bittejä joita peliä pelattaessa ei voida ikinä tarvita, luontevimpana esimerkkinä biteistä 2-5 ne joissa
historian strategian omaa siirtoa vastaava valinta on eri kuin ensimmäisen bitin deterministisesti
määräämä aloitussiirto. Näitä bittejä on kuitenkin syytä säilyttää strategioissa, koska risteytykset tai
mutaatiot voivat muuttaa aloitussiirtoa siten, että bitit tulevat taas merkityksellisiksi.
Tässä työssä sukupuolten taistelua pelataan toistetusti, eli geneettisen algoritmin toivotaan löytävän
strategioita jotka kykenevät yhteistyöhön muiden strategioiden kanssa mahdollisimman usein. Nash-
tasapainoista saadaan puhtaiden strategioiden tasapainot loogisiksi vaihtoehdoiksi strategioiksi jotka
geneettisillä algoritmeilla on seuraavanlaisella toteutuksella löydettävissä. Sekastrategiatasapainoilla ei
ole oikeastaan mitään tekemistä tämän toteutuksen kanssa, koska ne olettavat, että pelaaja valitsee
jonkun todennäköisyysjakauman mukaisesti kun taas edellä esitetyn kaltaisilla strategioilla kaikki
valinnat ovat deterministisiä kun pelin historia tunnetaan.
Vaikka geneettiset algoritmit pyrkivät luonnostaan löytämään annetulle tehtävälle, tässä tapauksessa
sukupuolten taistelun pelaamiselle, hyviä ratkaisuja niin tässä tapauksessa muodostuvat ratkaisut eivät
ole yhtä tärkeitä kun tieto siitä pystytäänkö geneettisillä algoritmeilla luomaan strategioita jotka
pystyvät yhteistyöhön muiden samanlaisten strategioiden kanssa. Tätä ominaisuutta kuvaava suure
saadaan nyt helposti kun huomataan, että pelaajat saavat yhteensä kolme pistettä tehdessään yhteistyötä
ja 0 pistettä muuten. Täten jos pelataan yhteensä n peliä sukupuolten taistelua ja niissä pelaajat saavat
yhteensä p pistettä niin yhteistyötä tehtiin np
3 peleistä. Toivottuna tuloksena olisi, että geneettisen
algoritmin edetessä tämä arvo nousisi ykköseen tai ainakin lähelle sitä.
3.2 Hyvän strategian ominaisuuksia Geneettisen algoritmin tavoitteena tässä työssä on siis muokata ratkaisuehdokkaiden populaatiota siten,
että ne pystyvät yhteistyöhön keskenään, eli tekevät peliä pelattaessa samoja valintoja joutuessaan
samanlaiseen tilanteeseen. Tästä nähdään triviaalisti, että täydelliseen yhteistyöhön pystyvät ainakin
sellaiset ratkaisujoukot joissa kaikki yksilöt ovat strategialtaan identtisiä. Huomattakoon myös, että
tässä tapauksessa jos geneettistä algoritmia jatketaan niin risteytys tuottaa satunnaisista tekijöistä
riippumatta jälleen identtisen populaation, joten jos mutaatioiden todennäköisyys on pieni, kuten sen
pitää käytännössä geneettisissä algoritmeissa olla jotta algoritmi pystyy konvergoimaan johonkin
ratkaisuun, niin täydelliseen yhteistyöhön pystyvä populaatio on myös lähes stabiili ainoastaan
mutaatioiden aiheuttaessa pieniä tilapäisiä pudotuksia yhteityöprosentissa. Evoluution kannalta
ajateltuna geneettinen algoritmi siis tuottaa onnistuessaan populaatioita joiden yhteistyökyky perustuu
edellisiltä sukupolvilta opittuihin käyttäytymistapoihin.
Täydellistä yhteistyötä tekevästä populaatiosta pantakoon merkille, että kun kaikissa peleissä pelaajat
tekevät yhteistyötä jokaisella pelikierroksella niin strategiasta ainoastaan ne bitit jotka edustavat
valintoja jotka tehdään kun historiassa on tehty aina yhteistyötä voivat käytännössä olla merkitseviä.
Täydellinen yhteistyö ei siis vaadi käytännössä sitä, että populaation jäsenet ovat täysin identtisiä vaan
tiettyjen bittien yhtäsuuruus kaikissa populaation yksilöissä riittää täydelliseen yhteistyöhön. Nämä
bitit ovat siis ylläolevasta taulukosta numerot 1, 2, 5, 6, 9, 18 ja 21. Yksinkertaisimmissa täydellisen
yhteistyön populaatioissa riittää kolmen näiden yhtäsuuruus, esimerkiksi populaatio jonka jokaisella
yksilöllä bittien 1, 5 ja 21 arvo on 1 tekee yhteistyötä kaikissa yksilöiden välillä pelatuissa peleissä
jokaisen yksilön valitessa strategiakseen ykkösen kaikissa mahdollisissa tilanteissa. Vastaavasti jos
kaikilla yksilöillä bitit 1, 2 ja 6 saavat arvon 0 niin kaikissa tällaisten yksilöiden pelaamissa peleissä
molemmat pelaajat valitsevat vaihtoehdon 0 pelin kaikissa vaiheissa.
Ohessa puumainen graafinen esitys erilaisten tasapainostrategioiden tuottamista syklisistä peliketjuista
kun pelataan ensin vaihtoehtoa 0, 1:llä alkavat vastaavat ketjut saataisiin vaihtamalla kuviossa nollat
ykkösiksi ja ykköset nolliksi.
00 00 11
00 11 1100 ... 00 11
00 11
... ...
11
... 00 00 11
... ...
00 11 00
...
11
...
... 00 11
...00 11...00 11
... ...
Kuva : Tasapainostrategioiden tuottamat peliketjut kun ensimmäiseksi pelataan 0:aa
Ohessa vielä lista tasapainostrategioiden tuottamista peliketjuista ja kunkin tasapainostrategian
yhtäsuuruutta vaativista biteistä, kukin peliketjun numero vastaa molempien pelaajien tekemää
valintaa:
Peliketju Kriittiset bitit Peliketju Kriittiset bitit
000... 1,2,6 111... 1,5,21
001001001... 1,2,6,9,18 110110110... 1,5,9,18,21
001010101... 1,2,6,9,18 110101010... 1,5,9,18,21
00110011... 1,2,6,9,18,21 11001100... 1,5,6,9,18,21
0011011011... 1,2,6,9,18,21 1100100100... 1,5,6,9,18,21
00111111... 1,2,6,9,21 11000000... 1,5,6,18,21
01000000... 1,2,6,9,18 10111111... 1,5,9,18,21
01001001001... 1,2,6,9,18 10110110110... 1,5,9,18,21
01010101... 1,2,9,18 10101010... 1,5,9,18
0110000000... 1,2,6,9,18,21 1001111111... 1,5,6,9,18,21
011001100110011... 1,2,6,9,18,21 100110011001100... 1,5,6,9,18,21
011011011011... 1,2,9,18,21 100100100100... 1,5,6,9,18
0111111111... 1,2,9,21 1000000000... 1,5,6,18 Taulukko 3: Tasapainostrategioiden tuottamat sykliset peliketjut ja yhtäsuuruutta vaativat bitit
Nyt siis jokaisella tasapainostrategialla on olemassa peilikuvastrategia joka tuottaa päinvastaisen
lopputuloksen. Tällaisten peilikuvastrategioiden lopputuloksia evaluoitaessa tarkastellaan kuitenkin
pelin edetessä eri bittejä, joten kaikkien bittien arvot eivät ole yhdentekeviä strategian hyvyyden
kannalta kun tavoitteena pidetään täydelliseen yhteistyöhön kykenevää populaatiota ts. vaikka kaikki
mahdolliset strategiat voivat esiintyä ainakin joissain populaatioissa jotka tekevät täydellistä yhteistyötä
niin joillekin strategioille mahdollisia yhteistyökumppaneita löytyy enemmän kuin toisille.
Yksinkertaisimmat, ja tästä johtuen myös todennäköisesti yleisimmät, tasapainostrategiat ovat sellaisia
joissa jokaisella pelikierroksella kaikki pelaajat pelaavat samaa vaihtoehtoa. Jos palataan siis
yhteistyökyvyn tarkastelemisesta pelin alkuperäiseen ideaan sukupuolten välisenä taisteluna niin
näyttää todennäköiseltä, että geneettinen algoritmi päätyy useimmiten tilanteeseen jossa toinen
sukupuolista on käytännössä voittanut sukupuolten taistelun ja jokainen tämän sukupuolen yksilöistä
saavuttaa pelin suurimman mahdollisen pistemäärän. Kuten yllä nähtiin on olemassa myös strategioita
jotka päättyvät tasapainotilaan jossa molemmat sukupuolet saavat saman pistemäärän, jos pelataan
parillinen määrä pelejä, mutta tällaiset tasapainostrategiat ovat todennäköisesti melko harvinaisia
geneettisen algoritmin tuloksina. Näiden osuutta algoritmin antamista tuloksista tarkastellaan
myöhemmin käytännön toteutuksen tuloksia käsittelevässä luvussa.
3.3 Geneettisen algoritmin toteutukseen liittyvistä valinnoista
Tätä työtä varten tarvittava geneettinen algoritmi voitaisiin toteuttaa useilla eri tavoilla. Tässä luvussa
käydään läpi tehtyjä valintoja ja niiden erityispiirteitä algoritmin käyttäytymisessä ja tuloksissa.
3.3.1 Peliparien valinta, pisteytys ja pelin pelaaminen
Nyt peluutetaan siis kussakin sukupolvessa kutakin yksilöä kaikkia toisen sukupolven edustajia
vastaan. Tämä tarkoittaa käytännössä sitä, että populaation täytyy käytännössä ajan myötä muuttua
käytökseltään homogeeniseksi pystyäkseen saavuttamaan korkean pistemäärän. Kun risteytys
suoritetaan rulettimenetelmää käyttämällä niin näin pitäisi tapahtua myös käytännössä geneettistä
algoritima käytettäessä. Valittu risteytystapa ja peliparien valitseminen siis tukevat toisiaan. Jos
ajatellaan geneettisen algoritmin toimintaa evoluution kannalta niin voidaan ajatella, että vastaava
tilanne on sellainen jossa kaikkien populaation jäsenten pitää kyetä yhteistyöhön tai olla yhteensopivia
kaikkien muiden yksilöiden kanssa. Toinen mielenkiintoinen asetelma voisi olla sellainen jossa
populaatio koostuu ryhmistä joiden sisällä yksilöt pelaavat kaikkia muita saman ryhmän yksilöitä
vastaan ja ryhmien välillä pelaisivat vain muutamat erikseen valitut yksilöt, mahdollisesti erilaisella
pisteytyksellä. Tällaisessa asetelmassa syntyisi monipuolisempia tasapainoasemia ja olisi mahdollista
mallintaa, vaikkakin karkeasti, hieman monipuolisempien toisiinsa vaikuttavien systeemien
käyttäytymistä ja niissä tapahtuvaa kehitystä ja oppimista.
Pisteytys aloitetaan pelin määritelmän mukaisella yhdellä ja kahdella pisteellä yhteistyöstä. Näillä
pistemäärillä on vaarana, että algoritmi löytää tasapainotiloja hitaasti tai ei ollenkaan, sillä täysin
satunnaisestikin pelaavat pelaajat saavat keskimäärin 0,25*1+0,25*2 = 0,75 pistettä, eli piste-erot
voivat jäädä tällä pisteytyksellä niin vähäpätöisiksi, että risteyttämisen aikaansaama parannus saattaa
jäädä pieneksi. Strategioiden tekemien valintojen riippuminen vain kahdesta edellisestä kierroksesta
saa aikaan sen, että pelien tulosketjut ovat syklisiä jolloin pelikierrosten määrän muuttaminen aiheuttaa
käytännössä pistemäärän kertomisen jollakin vakiolla. Tässä työssä risteytyksessä käytettävässä
rulettimenetelmässä kaikkien pistemäärien kertominen vakiolla ei muuta risteytystilannetta mitenkään,
joten lineaarisesti pistemäärää muuttavat variaatiot eivät muuta olennaisesti algoritmin käyttäytymistä.
Suurempia eroja pistemäärissä voidaan kuitenkin saada aikaan esimerkiksi korottamalla saadut
pistemäärät toiseen potenssiin. Tämän vaikutusta algoritmiin kokeillaan myöhemmin.
Pelikertojen määräksi valittiin 20 kullekin peliparille. Pelin lopputulosten syklisyyden pitäisi tulla esille
tällä toistomäärällä ja algoritmin suoritus pysyy kuitenkin nopeana. Jos tasapainotilojen löytyminen on
liian hidasta niin pelikertojen määrää voidaan nostaa jolloin paremmin yhteistyötä tekevät strategiat
saavat risteytystä silmällä pitäen enemmän pisteitä.
3.3.2 Risteytys, mutaatiot ja yhteistyötavoite Risteytys suoritetaan siis ns. rulettimenetelmällä eli risteytettävät yksilöt valitaan koko populaatiosta
siten, että yksilön todennäköisyys tulla valituksi on suoraan riippuvainen yksilön saamista pisteistä.
Tällainen risteytys voidaan ajatella evoluution kannalta tilanteena jossa oppiminen tapahtuu edelliseltä
sukupolvelta oppien esimerkkiä seuraamalla eli seuraava sukupolvi pyrkii käyttäytymään samalla
tavalla kuin menestyksekkäimmät edellisen sukupolven edustajat. Risteytys tehdään tässä työssä
risteyttämällä eri sukupuolisia yksilöitä keskenään, vaihtoehtoisesti voitaisiin korostaa edelliseltä
sukupolvelta oppimista esimerkkiä seuraamalla risteyttämällä kummankin sukupuolen jälkeläiset vain
saman sukupuolen edustajista. Tällöin voitaisiin ajatella asetelma esimerkiksi kahden eri lajin väliseksi
symbioottiseksi kilpailutilanteeksi. Eräs kolmas vaihtoehtoinen risteyttämisstrategia olisi yrittää
mallintaa risteytystä nimensä mukaisesti perimän kautta siten, että eri sukupuolten edustajista
muodostettaisiin risteytyksessä pareja jotka saivat keskenään hyvän pistemäärän ja näistä valittaisiin
risteytettävät parit parien yhteensä saamaan pistemäärän avulla. Tässä tapauksessa siis risteytettävät
parit olisivat valmiiksi jo todennäköisesti melko homogeenisiä ainakin dnan merkitsevien bittien osalta.
Myöhemmin tässä työssä kokeillaan lyhyesti näiden risteyttämismenetelmien eroja yhteistyön
saavuttamisessa.
Mutaatioiden merkitys geneettiselle algoritmille on siis tarjota mahdollisuus poistua lokaaleista
tasapainotiloista sellaisissa tapauksissa jossa ratkaisua ei pystyttäisi löytämään pelkällä risteyttämisellä.
Mutaatiot siis takaavat, että kaikki mahdolliset ratkaisut ovat saavutettavissa geneettisillä algoritmeilla.
Tässä tapauksessa, kuten luvusta 3.2 nähdään erilaisia täydellisiä tasapainostrategioita on hyvin suuri
joukko ja mikä tahansa alkupopulaatio sisältää varmasti tarvittavat geenit täydellisen yhteistyön
saavuttamiseksi. Mutaatioiden todennäköisyys halutaan siis jättää tässä tapauksessa pieneksi.
Alkuarvoksi valitaan mutaation todennäköisyydeksi 0.1%.
Luvussa 3.2 nähtiin myös, että täydelliset tasapainostrategiat ovat paitsi saavutettavissa millä tahansa
alkupopulaatiolla niin myös varsin yksinkertaisia. Nyt kun vielä mutaatioiden todennäköisyys on pieni
niin voidaan ottaa suoraan tavoitteeksi täydellinen yhteistyö, eli geneettistä algoritmia jatketaan kunnes
yhteistyöprosentti on 100%:
4. Geneettisen algoritmin käytännön toteutus Geneettinen algoritmi toteutettiin java-kielellä ja suhteellisen yksinkertaisen rakenteen takia mitään
apukirjastoja ei tarvinnut käyttää. Ohjelmalistaus on esitetty liitteessä 1. Tässä luvussa käydään läpi
ohjelmaan kuuluvien luokkien rakenne ja valitut toteutustavat.
4.1 Ohjelman pääluokka GABattleOfSexes Ohjelman pääluokka GABattleOfSexes suorittaa varsinaisen geneettisen algoritmin suorituksen ja
muistuttaa rakenteeltaan luvun 2.2.1 kuvausta geneettisen algoritmin yleisestä toiminnasta. Tässä
luokassa on myös määritelty suurin osa muuttujista. Pääluokassa määritellyt muuttujat ovat DNASIZE
joka kertoo halutun DNA-ketjun pituuden, populationSize joka on populaation koko, targetCooperation
joka on yhteistyöraja suhteellisena osuutena johon asti algoritmia jatketaan ja numberOfRounds joka
on kunkin peliparin pelaamien toistojen lukumäärä.
Pääluokassa ensin alustetaan alkupopulaatio satunnaiseksi. Tämän jälkeen kutsutaan PlayRound –
luokkaa joka ottaa syötteinä populaation ja kierrosten lukumäärän ja palauttaa kunkin yksilön saamat
pisteet tällä kierroksella. Tämän jälkeen pääluokassa lasketaan pisteet yhteen ja tästä tehdyn yhteistyön
suhteellinen osuus ja nämä tulostetaan ohjelman käyttäjälle. Sitten toistetaan silmukkaa jossa ensin
suoritetaan risteytys kutsumalla luokkaa Crossover ja altistetaan yksilöt mutaatioille kutsumalla
luokkaa Mutate, tämän jälkeen silmukassa pelataan uusi kierros, lasketaan pisteet yhteen ja yhteistyön
osuus ja tulostetaan tulokset ja jatketaan kunnes yhteistyön osuus ylittää asetetun rajan.
4.2 Kierroksen pelaava luokka PlayRound Luokka PlayRound ottaa syötteenä populaation esitettynä taulukkona ja pelattavien kierrosten
lukumäärän. Luokkaan on koodattu sisään luvussa 3.1 esitetty kuvaus DNA:sta ja sitä hyödyksi
käyttäen se laskee historiasta jota pidetään samalla muistissa kullakin kierroksella vertailtavien
strategiabittien numerot ja vertaa niiden yhtäsuuruutta päivittäen pelaajien pisteitä jos ne ovat
yhtäsuuret sen mukaan kummalle edullisempaa vaihtoehtoa pelattiin. Tämän jälkeen päivitetään
pelihistoriaan viimeisimmän kierroksen tulos ja jatketaan kunnes on pelattu niin monta kierrosta kun
syötteenä otettavassa luvussa kerrottiin.
4.3 Risteytyksen suorittava luokka Crossover Luokka Crossover ottaa syötteenä populaation ja yksilöiden saamat pisteet taulukkoina ja suorittaa
risteytyksen. Risteytettävät parit arvotaan rulettimenetelmällä siten, että arvotaan satunnaisluku yhden
ja saman sukupuolen kaikkien jäsenten saavuttamien yhteispisteiden välillä ja vähennetään tästä yksi
kerrallaan yksilöiden saavuttamat pisteet kunnes saadaan tulokseksi nolla tai pienempi luku. Tämän
jälkeen arvotaan satunnaisesti leikkauskohta ja muodostetaan yksi yksilö jolla on isänsä DNA
ensimmäisestä bitistä leikkauskohtaan asti ja äitinsä DNA siitä eteenpäin ja toinen päinvastoin. Sen
jälkeen näille kahdelle jälkeläiselle arvotaan satunnaisesti sukupuolet. Tässä toteutuksessa siis kukin
lisääntymään valittu pari tuottaa kaksi jälkeläistä, yhden kumpaakin sukupuolta. Lopuksi palautetaan
uusi sukupolvi.
4.4 Mutaatiot tekevä luokka Mutate
Luokka Mutate ottaa syötteenä populaation ja altistaa tämän kaikkien yksilöiden kaikki geenit
mutaatioille. Tämä tapahtuu yksinkertaisesti niin, että kullekin geenille arvotaan satunnaisluku ja jos se
alittaa säädetyn todennäköisyyden niin muutetaan bitin arvo nollasta ykköseksi tai ykkösestä nollaksi.
Lopuksi palautetaan uusi populaatio.
5. Käytännön tuloksia
5.1 Käytännön tuloksia parametrien alkuarvoilla
Geneettistä algoritmia kokeiltiin ensin yllämainituin asetuksin 20 kertaa ja tulokset ensimmäisistä
koeajoista ovat allaolevassa taulukossa. Kullekin kerralle on ilmoitettu kuinka monta sukupolvea
tarvittiin täydellisen yhteistyön aikaansaamiseksi ja mitkä olivat lopun tasapainotilassa kunkin
sukupuolen yksilöiden saamat pisteet.
Sukupolvia Pisteet sukupuolelle 0 Pisteet sukupuolelle 1
1 16 400 200
2 61 210 390
3 59 210 390
4 117 340 260
5 47 330 270
6 101 290 310
7 31 220 380
8 12 200 400
9 112 310 290
10 15 400 200
11 35 390 210
12 30 200 400
13 18 390 210
14 6 400 200
15 29 300 300
16 27 300 300
17 22 400 200
18 20 310 290
19 161 400 200
20 16 390 210
Taulukko 4: Käytännön tuloksia parametrien alkuarvoilla
Geneettinen algoritmi päätyi siis täydelliseen tasapainotilaan kaikissa tapauksissa suhteellisen lyhyessä
ajassa. Vaihtelu tarvittavien sukupolvien määrässä tosin vaihteli melko paljon. On kuitenkin selvää,
että geneettisillä algoritmeilla voidaan saada helposti toimivia strategioita vaikka erot pistemäärissä
strategioiden välillä olisivatkin pieniä. Tasapainotiloista yleisimpiä olivat sellaiset, joissa toinen
sukupuoli sai selkeästi enemmän pisteitä, yleisimpinä pisteiden jakautuminen 400-200 joka tapahtui
7:ssä tapauksessa, mikä on loogista seurausta sille, että tällaiset tasapainotilat ovat yksinkertaisempia ja
täten yleisimpiä kuten luvussa 3.2 nähtiin. Melkein yhtä yleisiä olivat 390-210 jakautumiset joita
tapahtui kuudessa tapauksessa. Pisteiden jakautumista täysin tasankin tapahtui kuitenkin kahdessa
tapauksessa, joten harvinaisempiakin tasapainoasemia esiintyy tässä tapauksessa suhteellisen suurella
todennäköisyydellä. Keskimäärin tasapainon löytämisessä kului tässä tapauksessa 46,75 sukupolvea.
Ohessa vielä taulukko yhteistyöasteen kehityksestä näissä 20 ajossa kuudenkymmenen ensimmäisen
sukupolven osalta.
Yhteistyön suhteellisen osuuden kehittyminen geneettisessä algoritmissa
0,4
0,5
0,6
0,7
0,8
0,9
1
0 10 20 30 40 50 60
Sukupolvi
Yhte
isty
ön s
uhte
ellin
en o
suus
Kuva 1: Yhteistyön kehittyminen geneettisessä algoritmissa parametrien alkuarvoilla
Vaikka vaihtelua eri ajojen välillä selkeästi on, niin algoritmin yleinen käyttäytyminen on melko saman
suuntaista. Satunnaisilla alkustrategioilla yhteistyön osuudet ovat lähellä 0,5:ttä, joka on siis myös
odotusarvo täysin satunnaisille strategioille. Tästä strategiat kehittyvät selvästi ensimmäisten
sukupolvien aikana kunnes noin 20 sukupolven jälkeen saavutetaan tasanne, jossa vielä tasapainoa
löytämättömien strategioiden yhteistyöosuudet vaihtelevat noin välillä 0,7-0,95 kunnes yksi kerrallaan
nekin saavuttavat tasapainon. Tyypilliseltä käytökseltä näyttäisi myös sahalaitakuvio joka viittaa siihen,
että yhteistyön osuuden kasvua seuraa seuraavassa sukupolvessa yleensä yhteistyön osuuden
tippuminen.
Geneettiset algoritmit näyttävät siis soveltuvan varsin hyvin tämäntyyppiseen peliteoreettiseen
evoluutioasetelmaan. Seuraavaksi kokeiltiin mallin parametrien muuttamisen vaikutusta yhteistyön
kehittymiseen.
5.2 Pelikierroksen pituuden ja mutaatiotodennäköisyyden vaikutus Seuraavaksi kokeiltiin pelikierroksen pituuden vaikutusta. Edellisessä tapauksessa kukin pari pelasi peliä 20
kertaa ja tätä koetta varten toistojen määrä nostettiin neljäänkymmeneen. Käytännössä tämän pitäisi tarkoittaa
ensimmäisten strategiabittien vaikutuksen pienenemistä. Pelikierrosten määrän lisääminen toivottavasti korostaa
myös kullakin hetkellä yhteistyökykyisempiä strategioita ja täten parantaa geneettisen algoritmin toimivuutta,
mutta toisaalta tässä tapauksessa pelien lopputulemien ollessa syklisiä strategioiden esitystavasta johtuen voi
käydä niin, että eri pelaajien pistemäärien suhteet pysyvät käytännössä samoina jolloin rulettimenetelmän
todennäköisyydet eivät muutu ja ensimmäisen bitin vaikutuksen väheneminen voi jopa huonontaa algoritmin
toimivuutta koska ensimmäinen strategiabitti on ainoa strategiabitti jonka arvon on pakko olla kaikissa
mahdollisissa tasapainoasemissa kaikilla pelaajilla sama.
Algoritmia toistettiin jälleen 20 kertaa seuraavin tuloksin:
Sukupolvet Sukupolvet
1 46 11 25
2 23 12 47
3 94 13 31
4 102 14 48
5 60 15 56
6 93 16 250
7 50 17 16
8 14 18 34
9 30 19 16
10 18 20 14
Taulukko 5: Geneettisen algoritmin tuloksia pitemmällä pelikierroksen pituudella
Keskimäärin tasapainon löytämiseen meni nyt keskimäärin 53,35 sukupolvea. Pelikierroksen
pidentäminen ei siis ainakaan parantanut algoritmin toimivuutta. Kuudennentoista kerran
poikkeuksellisen huono tulos saattaa johtua ensimmäisen bitin vaikutuksen vähenemisestä.
Toinen säädettävä parametri jonka vaikutusta haluttiin tutkia on mutaatioiden todennäköisyys.
Parametrin vaikutusta testattiin nostamalla sen arvo 0.01:stä 0.03:een. Nyt kun tavoitteena on
täydellinen yhteistyö ja se voidaan saavuttaa kaikista alkupopulaatioista myös ilman mutaatioita niin
korkeammasta mutaatiotodennäköisyydestä on todennäköisesti enemmän haittaa kun hyötyä.
Algoritmia toistettiin 20 kertaa korkeammalla mutaatiotodennäköisyydellä seuraavin tuloksin:
Sukupolvet Sukupolvet
1 18 11 247
2 13 12 168
3 102 13 634
4 109 14 391
5 100 15 92
6 168 16 132
7 50 17 165
8 1400 18 22
9 13 19 61
10 549 20 111
Taulukko 6: Geneettisen algoritmin tuloksia mutaatiotodennäköisyydellä 0,03
Mutaatiotodennäköisyyden kasvattaminen aiheutti siis selkeästi huonompia tuloksia, 0,03 on selkeästi
liian suuri todennäköisyys mutaatiolle.
Koska mutaatiotodennäköisyyden kasvattaminen vaikutti näin selkeästi huonontavasti tuloksiin niin
kokeiltiin myös mutaatiotodennäköisyyden pienentämistä arvoon 0,001.
Suoritettiin jälleen 20 toistoa seuraavin tuloksin:
Sukupolvet Sukupolvet
1 21 11 10
2 56 12 21
3 19 13 25
4 22 14 33
5 31 15 23
6 51 16 12
7 26 17 19
8 17 18 26
9 36 19 21
10 12 20 27
Taulukko 7: Geneettisen algoritmin tuloksia mutaatiotodennäköisyydellä 0,001
Nyt tarvittiin keskimäärin 25,4 sukupolvea tasapainoaseman saavuttamiseen.
Mutaatiotodennäköisyyden pienentäminen siis paransi selkeästi algoritmin toimintaa, etenkin
huomattavaa parannus oli huonoimmissa toistoissa; siinä missä ensimmäisissä tuloksissa neljässä
tapauksessa kahdestakymmenestä tarvittiin yli 100 sukupolvea niin nyt huonoin tulos oli 56
sukupolvea.
Ohessa vielä taulukko yhteistyöasteen kehityksestä tässä tapauksessa:
Yhteistyön suhteellisen osuuden kehitys
0,4
0,5
0,6
0,7
0,8
0,9
1
0 10 20 30 40 50 6
Sukupolvi
Yhte
isty
ön s
uhte
ellin
en o
suus
0
Kuva 2: Yhteistyön kehittyminen geneettisessä algoritmissa pienemmällä mutaatiotodennäköisyydellä
Verrattuna alkuperäiseen tulokseen algoritmin käytös on saman suuntaista yhteistyöasteen noustessa
jälleen tasaisesti ensimmäisten 20 sukupolven aikana, mutta tässä tapauksessa käytös on huomattavasti
tasaisempaa ja kehitys tasaisempaa. Siinä missä mutaatiotodennäköisyydellä 0,01 kahdenkymmenen
sukupolven jälkeen yhteistyöaste vaihteli vielä tasapainoa hakevissa tapauksissa noin 0,7:n ja 0,95:n
välillä niin mutaatiotodennäköisyydellä 0,001 melkein kaikkien tapausten yhteistyöosuudet pysyivät
vastaavassa tilanteessa yli 0,9:ssä. Pienempi mutaatiotodennäköisyys on siis selkeästi tässä tapauksessa
parempi algoritmin toiminnan kannalta. Tästä eteenpäin tässä työssä käytetään pienempää
mutaatiotodennäköisyyttä.
5.3 Risteytysprosessin muuttamisen vaikutus algoritmin toimintaan Vaikka algoritmi löytää tämänhetkisilläkin asetuksilla täydellisen yhteistyön tasapainotiloja varmasti ja
nopeasti niin kokeillaan pistemäärien muuntamisen vaikutusta. Kuten aiemmin todettiin, pistemäärien
vakiolla kertominen ei aiheuta rulettimenetelmää käytettäessä eroa algoritmin toimintaan, joten
kokeillaan algoritmin toiminnan muuttumista jos pistemäärät korotetaan toiseen potenssiin risteytystä
tehdessä. Tällöin korkeampia pistemääriä saaneiden yksilöiden todennäköisyys tulla valituksi
risteytykseen kasvaa. Nyt kun tavoitteena on homogeenisen populaation luominen niin tämän pitäisi
nopeuttaa algoritmin toimintaa.
20 toiston sarja tuotti seuraavanlaiset tulokset:
Sukupolvet Sukupolvet
1 12 11 12
2 36 12 9
3 7 13 6
4 18 14 20
5 8 15 18
6 25 16 10
7 10 17 12
8 10 18 15
9 16 19 10
10 14 20 18
Taulukko 8: Geneettisen algoritmin tuloksia kun risteytettäessä pistemäärät korotetaan toiseen potenssiin
Nyt tarvittiin keskimäärin 14,3 sukupolvea tasapainon löytymiseen, eli parannusta edelliseen malliin
saatiin odotetusti. Jos ajatellaan jälleen geneettistä algoritmia peliteoreettisessa mallissa jonkun
populaation evoluution mallina niin pistemäärien korottamisella johonkin potenssiin voidaan mallissa
kuvata oppimisnopeutta, mitä korkeampaan potenssiin pistemäärät nostetaan sitä todennäköisemmin
seuraava sukupolvi ottaa oppia tämän sukupolven parhaiten menestyvistä yksilöistä.
Vertailun vuoksi vielä yhteistyöasteen kehitys tässä mallissa:
Yhteistyön suhteellisen osuuden kehittyminen geneettisessä algoritmissa
0,4
0,5
0,6
0,7
0,8
0,9
1
0 10 20 30 40 50 60
Sukupolvi
Yhte
isty
ön s
uhte
ellin
en o
suus
Kuva 3: Yhteistyön kehittyminen kun risteytettäessä pistemäärät korotetaan toiseen potenssiin
Verrattuna edellisiin tapauksiin algoritmin alussa parannus yhteistyössä on nopeampaa ja aiemmin
havaittua tasaantumista ei useimmissa tapauksissa esiinny vaan nousu jatkuu suoraan
yhteistyötavoitteeseen asti. Tästä eteenpäin työssä käytetään pisteiden korotusta toiseen potenssiin.
Seuraavaksi kokeiltiin risteytysprosessin muuttamista sellaiseksi, että kummallekin sukupuolelle
risteytyksessä otetaan vanhemmat saman sukupuolen sisältä. Tämän voidaan ajatella vastaavan
tilannetta jossa eri sukupuolet ovat symbioosissa eläviä populaatioita jotka ottavat oppia tai perivät
ominaisuutensa vain omasta populaatiostaan.
20 toistoa tuotti seuraavanlaiset tulokset:
Sukupolvet Sukupolvet
1 13 11 1579
2 45 12 2251
3 13 13 1014
4 218 14 152
5 8 15 226
6 1307 16 213
7 178 17 9
8 14 18 13
9 91 19 8
10 384 20 25
Taulukko 9: Geneettisen algoritmin tuloksia kun risteytys suoritettiin vain sukupuolten sisällä
Nyt ero edellisiin tapauksiin on huomattava. Erityisesti on nyt tapauksia joissa täydelliseen
yhteistyöhön pääsemiseksi tarvitaan hyvin suuri määrä sukupolvia. Yhteistyön kehitystä tutkittaessa
tapauksissa joissa sukupolvia tarvittiin paljon paljastaa, että tällöin on tyypillistä, että yhteistyön osuus
pysyy usein samana useiden sukupolvien ajan joka viittaa algoritmin jäävän lokaaliin maksimiin. Tämä
johtunee sukupuolten taistelulle ominaisesta epätasapainosta, eli siitä että kummallakin sukupuolella on
mieluisampi vaihtoehto. Aiemmat tapaukset välttivät nämä lokaalit maksimit sillä, että risteytettäessä
sukupuolten geenit menevät ristiin siten, että kaikilla yksilöillä on geenejä myös vastakkaiselta
sukupuolelta. Nyt kun yleisimmät tasapainot ovat sellaisia joissa toisen sukupuolten jäsenet saavat
kukin 200 pistettä ja saman pistemäärän kyseisen sukupuolen edustajat saavat myös sellaisessa
lopputuloksessa jossa ne pelaavat aina mieluisinta vaihtoehtoaan, mutta yhteistyötä tapahtuu vain 50%
ajasta niin on luonnollista, että täydellisen yhteistyön löytäminen kestää kauan, eihän täydellinen
yhteistyö ole molemmille sukupuolille optimaalinen tilanne. Kaikissa tapauksissa kuitenkin päädyttiin
täydelliseen yhteistyöhön joka kertoo geneettisen algoritmin voimasta löytää ratkaisuja vaikka käytetty
pisteytys ei tässä tapauksessa mittaakaan yhtä aikaa molemmille sukupuolille varsinaisen tavoitteen
läheisyyttä.
Lokaalien minimien yleisyys antaa myös aihetta epäillä, että tässä tapauksessa voitaisiin saada
parempia tuloksia nostamalla mutaatiotodennäköisyyttä sen lasketusta arvosta. Ohessa on tulokset 20
toistosta kun mutaation todennäköisyys oli 0.1:
Sukupolvet Sukupolvet
1 75 11 446
2 58 12 14
3 63 13 58
4 95 14 36
5 90 15 13
6 12 16 76
7 14 17 265
8 282 18 78
9 70 19 307
10 32 20 15
Taulukko 10: Geneettisen algoritmin tuloksia suuremmalla mutaatiotodennäköisyydellä kun risteytys suoritettiin
vain sukupuolten sisällä
Edellisiin tuloksiin verrattuna parannusta tapahtui etenkin kaikista eniten sukupolvia vaatineissa
tapauksissa. Suuremmasta mutaatiotodennäköisyydestä näytti siis olleen tässä tapauksessa selkeästi
hyötyä siinä missä alkuperäisessä tapauksessa siitä oli haittaa. Oikean mutaatiotodennäköisyyden
valinta geneettisessä algoritmissa riippuu siis kulloinkin kyseessä olevasta tehtävästä. Yleisesti ottaen
monimutkaisemmat ja vaikeammat tehtävät hyötyvät suuremmasta mutaatiotodennäköisyydestä.
5.4 Parhaan mahdollisen strategian löytäminen muuttumatonta strategiaa vastaan Geneettisiä algoritmeja käytetään yleensä ratkaisun löytämiseen johonkin ongelmaan. Tässä työssä
tähän mennessä geneettistä algoritmia on käytetty eräänlaisen evoluution mallina, tavoitteena tutkia
pikemminkin geneettisen algoritmin käyttäytymistä ja tarkastelun alla olevan peliteoreettisen pelin
luontaisia ominaisuuksia. On kuitenkin mielenkiintoista tutkia samalla miten tehokkaasti geneettisellä
algoritmilla voidaan löytää optimaalinen strategia jotain tiettyä strategiaa vastaan pelattaessa. Tässä
osassa työtä tutkittiin siis geneettistä algoritmia tilanteessa, jossa toisen sukupuolen strategia on aina
vakio. Normaalisti tällaisessa tilanteessa algoritmi voitaisiin lopettaa heti, kun löytyy yksikin strategia
joka saa täydet pisteet vastustajan strategiaa vastaan, mutta tässä työssä tasapainostrategioiden
vaatimusten ollessa näin vähäiset, vaikeimmassakin tapauksessa vaaditaan siis vain viiden bitin
yhtäsuuruutta, otetaan tässäkin tapauksessa lopetusehdoksi koko populaation yhteistyökyky
vakiostrategian kanssa. Evoluutionäkökulmasta tämä tarkoittaa tarkastelua sille miten nopeasti koko
populaatio saadaan pelaamaan optimaalisesti. On tärkeä muistaa, että liitteenä esitetyssä
ohjelmalistauksessa käytetään lopetusrajana yhteistyön suhteellista osuutta, nyt on kuitenkin
mahdollista, että täydellinen yhteistyö ei takaa kaikissa tapauksissa sukupuolelle suurinta mahdollista
pistemäärää joten on valittava vastustajiksi vain strategioita joissa optimaalinen tulos saavutetaan
yhteistyöllä tai muutettava algoritmin pysähtymisehtoa.
Tässä luvussa geneettinen algoritmi säätelee sukupuolen 0 kehitystä, sukupuoli 1:n strategia pysyys siis
vakiona. Samalla kaksinkertaistetaan sukupuolen 0 populaation koko, eli geneettinen algoritmi
käsittelee yhä 20:tä yksilöä.
Kokeilu aloitettiin helpoimmasta tapauksesta jossa sukupuoli 1 pelaa aina sukupuolelle 0 mieluisempaa
vaihtoehtoa, eli vaihtoehtoa 0. Sukupuolen 1 strategian jokainen bitti on siis 0. Optimaaliset populaatiot
ovat siis sellaiset joissa kaikkien yksilöiden strategioiden bitit 1, 2 ja 6 saavat arvon 0.
Algoritmia toistettiin 20 kertaa ja tulokset ovat seuraavassa taulukossa:
Sukupolvet Sukupolvet
1 14 11 10
2 14 12 29
3 8 13 581
4 7 14 17
5 11 15 9
6 19 16 18
7 16 17 189
8 377 18 14
9 483 19 19
10 18 20 31
Taulukko 11: Geneettisen algoritmin tuloksia strategiahaussa staattista vastusta vastaan osa 1
Nähdään, että vaihtelu tulosten välillä on hyvin suurta. Suurimassa osassa tapauksia oikea strategia
löydettiin koko populaatiolle nopeasti, mutta muutamissa tapauksissa tässä kesti hyvin kauan. Ohessa
vielä kuvaaja yhteistyön kehittymisestä 50 ensimmäisen sukupolven aikana.
Yhteistyön kehittyminen geneettisessä algoritmissa
0,4
0,5
0,6
0,7
0,8
0,9
1
0 5 10 15 20 25 30 35 40 45 50
Sukupolvi
Yhte
isty
ön s
uhte
ellin
en o
suus
Kuva 4: Yhteistyön kehittyminen strategiahaussa staattista vastustajaa vastaan
Jälleen kerran nähdään selkeästi samansuuntaista käytöstä. Kaikissa tapauksissa yhteistyön nousu
viiden ensimmäisen sukupolven aikana on voimakasta ja kaikissa tapauksissa melko samanlaista.
Tämän jälkeen yhteistyö tasoittuu noin 0,95:een jossa se suurimmaksi osaksi pysyy kunnes täydellinen
tasapaino löydetään jossain vaiheessa. Tämä esimerkki demonstroi myös hyvin yhden geneettisen
algoritmin haitan, nimittäin sen että vaikka geneettisellä algoritmilla onkin aina mahdollisuus löytää
optimaalinen ratkaisu jos se on olemassa niin algoritmi voi juuttua käytännössä lokaaliin maksimiin.
Tässä tapauksessa tiesimme optimaalisen ratkaisun, mutta jos optimaalista ratkaisua ei tiedetä
etukäteen niin löydetyn ratkaisun optimaalisuutta ei voida taata. On kuitenkin pidettävä mielessä, että
geneettinen algoritmi löytää hyvin nopeasti melko hyvän ratkaisun ongelmalle ja geneettisiä
algoritmeja käytetäänkin usein tilanteissa joissa hyvä ratkaisu riittää globaalin optimin sijaan.
Tutkimalla lukuarvoja tapauksista joissa sukupolvia kului paljon nähdään, että jälleen saadaan pitkiä
tasaisia jaksoja. Tyypillisiä yhteistyöasteen arvoja näille tasanteille ovat 0.95, 0.945 ja 0.9475. Nyt kun
pelejä pelataan kierroksessa yhteensä 400 niin nämä vastaavat tapauksia joissa yhteistyötä tehdään 380
tapauksessa, 378 tapauksessa ja 379 tapauksessa. Tapaus jossa yhteistyötä tehdään 380 tapauksessa
vastaa ilmeisesti sellaista tilannetta, jossa populaation kaikki jäsenet pelaavat ensimmäisellä
kierroksella ykköstä ja kaikilla seuraavilla nollaa jolloin kukin menettää ensimmäisellä pelikierroksella
kaksi pistettä. Tällaiseen tilanteeseen algoritmi jää helposti jumiin sellaisessa tapauksessa, jossa
populaatiossa yleisesti strategiabitti 2 saa arvon 1 jolloin siinäkin tapauksessa jolloin mutaatio muuttaa
jossain yksilössä bitin 1 arvon ykköseksi jolloin tämä yksilö tekee yhteistyötä ensimmäisellä
kierroksella niin yhteistyötä toisella pelikierroksella ei tapahdu ja oikeansuuntainen mutaatio ei saakaan
aikaan yhtään parempaa yksilöä ja tämä geeni voi helposti seuraavassa risteytyksessä poistua jälleen
populaatiosta. Muut havaitut lokaalit maksimit ovat niin lähellä tätä tapausta, että niissä lienee eroa
tähän tilanteeseen vain yhden yksilön strategiassa.
Tässäkin tapauksessa siis vaikka täydellinen tasapaino vaatii vain kolmen bitin tiettyä arvoa on
mahdollista jäädä hyvinkin pitkäksi ajaksi jumiin lokaaliin maksimiin, joten mutaation
todennäköisyyttä voisi kannattaa kasvattaa. Toisaalta yleisessä tapauksessa kun algoritmille riittää
yhdenkin optimaalisen ratkaisun löytäminen ei ole tarpeellista liikaa kasvattaa mutaatioiden
todennäköisyyttä, vaikkakin tällöin myös mutaatioiden suurimman haitta tämän työn ensimmäisessä
vaiheessa, eli muuten valmiin populaation muuttaminen pois optimaalisesta, todennäköisyys pienenee
rajusti. Evoluution kannalta ajateltuna tämä tarkoittaa sitä, että poikkeaminen totutuista tavoista on
kannattavaa silloin, kun tavoitellaan yksittäisiä onnistumisia ja vähiten kannattavaa tilanteessa jossa
halutaan välttää yhdenkään populaation jäsenen epäonnistumista. Tällä tavoin siis geneettinen algoritmi
mallintaa melko luontevasti riskinottamista totutusta poikkeavin muutoksin strategioihin.
Koska yksinkertaisimmassakin tapauksessa lokaalit maksimit aiheuttivat algoritmin venymistä niin
jatkossa käytetään jälleen mutaation todennäköisyytenä 0,01:tä.
Seuraavaksi kokeiltiin seuraavaksi yksinkertaisinta tilannetta, jossa sukupolven 1 strategian
ensimmäinen bitti on 1 ja muut nollia. Nyt siis vastustaja pelaa ensimmäisellä kierroksella vaihtoehdon
1 ja sen jälkeen aina vaihtoehdon 0. Nyt täydellinen tasapaino vaatii siis neljän bitin yhtäsuuruutta.
Algoritmia toistettiin jälleen 20 kertaa ja tulokset ovat seuraavassa taulukossa:
Sukupolvet Sukupolvet
1 31 11 126
2 51 12 81
3 649 13 33
4 684 14 39
5 242 15 63
6 20 16 28
7 277 17 8
8 77 18 567
9 51 19 31
10 55 20 144
Taulukko 12: Geneettisen algoritmin tuloksia strategiahaussa staattista vastusta vastaan osa 2
Verrattuna edellisiin tuloksiin saatiin nyt tasaisesti hieman huonompia tuloksia, joka oli odotettavissa
koska tällä kertaa vaadittu ratkaisu oli monimutkaisempi kun viime kerralla.
Yhteistyön kehittyminen geneettisessä algoritmissa
0,4
0,5
0,6
0,7
0,8
0,9
1
0 5 10 15 20 25 30 35 40 45 50
Sukupolvi
Yhte
isty
ön s
uhte
ellin
en o
suus
Kuva 5: Yhteistyön kehittyminen strategiahaussa staattista vastustajaa vastaan
Algoritmin käytös on suurin piirtein sellainen kuin edellisistä tapauksista voitiin päätelläkin. Varsin
hyvään tulokseen päästään viidessä sukupolvessa ja siitä eteenpäin yhteistyötaso liikkuu noin 0,95:en
ympärillä kunnes tasapaino löydetään. Korkeamman mutaatiotodennäköisyyden vaikutus näkyy
selvästi suurempana vaihteluna kehityksen kasvun taituttua samalla tavoin kuin ensimmäisissä
käytännön kokeissa.
Viimeisenä esimerkkinä strategian löytämisestä vastustajan staattista strategiaa vastaan kokeiltiin vielä
yhtä monimutkaisimista täydellisen yhteistyön tasapainoista. Monimutkaisimmat tapauksethan vaativat
taulukon 2 mukaan kuuden bitin yhtäsuuruutta. Tähän vaiheeseen valittiin tasapaino jossa täydellisessä
yhteistyössä pelaajat pelaavat ketjun 01100110011001100... Tällaisia strategioita ovat sellaiset, joissa
bitti 1 saa arvon 0, bitti 2 arvon 1, bitti 6 arvon 1, bitti 9 arvon 1, bitti 18 arvon 0 ja bitti 21 arvon 0.
Jotta täydellinen tasapaino vastaisi sukupuolen 1 pistemäärän maksimointia niin muiden bittien
arvoiksi annettiin 1. Sukupuolen 1 strategia on siis nyt 011111111111111110110.
Algoritmia toistettiin jälleen 20 kertaa ja saatiin seuraavat tulokset.
Sukupolvet Sukupolvet
1 12 11 61
2 47 12 45
3 28 13 61
4 18 14 16
5 11 15 8
6 294 16 58
7 10 17 31
8 69 18 71
9 18 19 44
10 244 20 52
Taulukko 13: Geneettisen algoritmin tuloksia strategiahaussa staattista vastusta vastaan osa 3
Verrattuna edellisiin tuloksiin yhteistyön saavuttaminen onnistui tällä kertaa keskimäärin jopa
nopeammin kuin viimeksi, vaikka tehtävän pitäisi olla haastavampi. Tämä saattaa kertoa siitä, että tässä
tapauksessa algoritmi ei kohtaa niin paljon lokaaleja maksimeja kuin edellisessä tapauksessa. Tämä voi
olla seurausta siitä, että tässä tapauksessa, toisin kuin edellisissä esimerkeissä, ei saa korkeaa
pistemäärää enää pelkästään kuudennen bitin yhtäsuuruudella. Edelliset tapauksethan olivat sellaisia,
joissa vastustaja pelasi kahden 0-yhteistyön jälkeen aina nollaa jolloin algoritmi löysi nopeasti
strategiat jotka pystyvät tähän muita paremmiksi jolloin poikkeamat optimista kahdella ensimmäisellä
pelikierroksella muodostivat käytännössä suurimman vaaran algoritmin jumiutumiselle. Katsotaan
vielä tässä tapauksessa yhteistyöasteen kehitys.
Yhteistyön kehittyminen geneettisessä algoritmissa
0,4
0,5
0,6
0,7
0,8
0,9
1
0 5 10 15 20 25 30 35 40 45 50
Sukupolvi
Yhte
isty
ön s
uhte
ellin
en o
suus
Kuva 6: Yhteistyön kehittyminen strategiahaussa staattista vastustajaa vastaan
Tässä huomataan nyt tehtävän näennäinen haastavuus siinä, että vaikka parametrit ovat samat kuin
edellisessä tapauksessa niin yhteistyöasteen nousu algoritmin alussa ei ole yhtä jyrkkää ja
yhdenmukaista kuin aikaisemmin, vaan nyt löytyy tapauksia joissa yhteistyöaste kehittyy hitaammin,
vaikkakin suurimmassa osassa tapauksista yhteistyöaste nousee jälleen noin viidessä sukupolvessa oli
0,9:ään. Tässä tapauksessa myös tasapainoa vielä 20 sukupolven jälkeenkin hakevien tapausten
vaihtelu on aiempaa suurempaa. Tämä lienee merkki siitä, että vastustajan monimutkaisempi strategia
saa aikaan sen, että mutaatiot aiheuttavat suurempaa vaihtelua nyt kun lähellä täydellistä tasapainoa
olevissa tapauksissa suurempi osa strategiabiteistä on merkittäviä peliketjujen suhteen. Tässä
tapauksessa siis peliketjut ovat monipuolisempia ja käytännössä tarkastetaan enemmän bittejä jolloin
mutaatioilla on suurempi todennäköisyys osua merkityksellisiin bitteihin.
6. Yhteenveto ja pohdintaa
Tässä työssä tutkittiin geneettisten algoritmien käyttöä strategioiden etsimiseen peliteoreettisessa
tilanteessa. Kun peli esitetään peliteorian normaalimuodossa niin todettiin, että pelin strategiat voidaan
esittää helposti geneettisen algoritmin vaatimassa muodossa. Toisaalta monimutkaisten strategioiden
esittämisen mahdollistava strategiaesitys kasvaa helposti liian suureksi ollakseen käytännöllinen. Tässä
työssä käytettiin yhtä yksinkertaisimmista esitystavoista, eli sellaista jossa strategiat riippuvat
muutamasta viimeksi pelatusta kierroksesta, tässä tapauksessa kahdesta. Toistetuissa peleissä kaikkien
mahdollisten strategioiden joukko on käytännössä varsin suuri, joten geneettiset algoritmit eivät sovellu
kovin hyvin monimutkaisten pelien optimaalisten strategioiden hakemiseen. Tässä työssä kuitenkin
havaittiin geneettisten algoritmien se yleinen ominaisuus, että ne löytävät yleensä hyvin nopeasti,
etenkin nykyaikaisten tietokoneiden laskentateholla, suhteellisen hyviä ratkaisuja. Geneettiset
algoritmit siis soveltuvat mainiosti hyvien strategioiden etsimiseen yksinkertaisissa pelinä esitetyissä
tilanteissa.
Tässä työssä kiinnitettiin erityisesti huomiota populaation evoluution mallintamisen mielekkyyteen
geneettisillä algoritmeilla ja sopivilla pelitilanteilla. Käytännön kokeet osoittivat, että koko populaatio
ajan myötä päätyy optimaaliseen strategiaan. Kokeet joissa risteytettävät yksilöt valittiin yksilöiden
pistemäärien perusteella, mutta lopetusehtona oli täydellisen yhteistyön saavuttaminen osoittivat, että
geneettiset algoritmit pystyvät kehittymään yhdessä populaatioina vaikka täydellisen yhteistyön tilanne
ei olekaan kaikille yksilöille risteytyksessä käytettävän kriteerin mukaan optimaalinen. Tämä antaa
aihetta uskoa, että yksinkertaistettujen toisiinsa kytkeytyvien systeemien välistä kehitysprosessia
voitaisiin mallintaa peliteoreettisesti käyttäen geneettisiä algoritmeja kehityksen mallintamiseen.
Geneettisten algoritmien ominaisuuksiksi havaittiin käytännön kokeissa nopea kehitys melko hyvään
ratkaisuun, tässä tapauksessa yhteistyön osuus saatiin yli 90%:n melkein kaikissa tapauksissa nopeasti.
Havaittiin myös pisteytyksen epälineaarisen muuntamisen ja mutaatiotodennäköisyyden huomattava
vaikutus algoritmin käyttäytymiseen. Yleensä tämä on hieman ongelmallinen piirre geneettisissä
algoritmeissa, sillä parametrien parhaiden arvojen löytäminen on vaikeaa ja huonosti tehtävään
sopivilla parametrin arvoilla algoritmin suorituskyky voi laskea ratkaisevasti. Evoluutionäkökulmasta
mietittynä nämä parametrit tarjoavat kuitenkin mahdollisuuden mallinnettavana olevan systeemin
ominaisuuksien kuvaamiseen todellisuutta paremmin vastaaviksi. Mutaatioiden todennäköisyydestä
huomattiin erityisesti se, että yksinkertaisille ongelmille mutaatioista voi olla haittaa algoritmin
toiminnalle, mutta ongelmissa joissa joudutaan usein lokaaliin maksimiin korkeampi
mutaatiotodennäköisyys on kuitenkin välttämätön. Kaikista huonoin algoritmin toiminta saatiin
tilanteissa joissa algoritmi jäi samaan lokaaliin maksimiin monen sukupolven ajaksi, kun
mutaatiotodennäköisyys nostettiin 0,001:stä 0,01:een niin kaikista pahimmilta tapahtumilta vältyttiin.
Tuntemattomalle ongelmalle lienee siis parasta pitää mutaatiotodennäköisyys aluksi suhteellisen
korkeana, etenkin tilanteessa jossa riittää että yksi populaation jäsenistä päätyy optimaaliseen
ratkaisuun.
Geneettisestä algoritmista huomattiin myös se, että vaikka se tilanteessa jossa optimiratkaisuja on
useita erilaisia todennäköisesti päätyy johonkin yksinkertaisimmista vaihtoehdoista, niin
harvinaisempiinkin optimiratkaisuihin päädytään kuitenkin säännöllisesti, kuten nähtiin alkuperäisen
tapauksen pistemääristä. Viimeinen käytännön kokeista osoitti myös sen, että näennäisesti
yksinkertaisempi tehtävä ei välttämättä ole geneettiselle algoritmille helpompi lokaalien maksimien
ollessa syypäinä algoritmin huonoon toimintaan ratkaisun harvinaisuuden sijaan. On tosin muistettava,
että keskimäärin vaikeampiin tehtäviin liittyy myös suurempi lokaaliin maksimiin juuttumisen
todennäköisyys.
Kokonaisuutena voidaan todeta, että geneettiset algoritmit tarjoavat yksinkertaisesti toteutettavissa
olevan tavan tutkia yksinkertaisia pelejä ja niissä esiintyviä hyviä strategioita. Parametrien avulla ja
pelin rakennetta muuttamalla algoritmin käyttäytymistä voidaan ohjata haluttuun suuntaan jolloin
geneettistä algoritmia ja pelimallia voidaan käyttää yksinkertaisten systeemien kehityksen
mallintamiseen. Geneettiset algoritmit eivät kuitenkaan sovellu hyvin tilanteisiin joissa vaaditaan
ehdottomasti globaalin optimin löytämistä tai monimutkaisten strategioiden luomista.
Viitteet [1] Holland: Adaptation in Natural and Artificial Systems: An Introductory Analysis with Applications to Biology, Control, and Artificial Intelligence, MIT Press, 1975. [2] Gibbons: A Primer in Game Theory, Prentice Hall, 1992. [3] Fujiki, C., Dickinson, J. Using the genetic algorithm to generate Lisp source code to solve the Prisoner's Dilemma. In: Grefenstette J.J. (ed.) Genetic Algorithms and their Applications, Proceedings of the 2nd. International Conference on Genetic Algorithms, Hillsdale, N.J.: Lawrence Erlbaum, 1987
Liite 1: Ohjelmalistaus import java.util.*;
public class GABattleOfSexes {
/**
* @param args
*/
public static void main(String[] args) {
int DNASIZE = 21;
int populationSize = 20;
int[][] population;
population = new int[populationSize][DNASIZE];
int[] score;
score = new int[populationSize];
double cooperation = 0;
double targetCooperation = 1;
int numberOfRounds = 20;
int totalScore = 0;
int i=0;
int generation = 0;
/* Risteytys sukupuolten sisällä */
int[][] population0; int[][] population1;
population0 = new int[populationSize/2][DNASIZE];
population1 = new int[populationSize/2][DNASIZE];
int[] score0; int[] score1;
score0 = new int[populationSize/2];
score1 = new int[populationSize/2];
/* Sukupuolten sisän loppu */
Random rand = new Random();
for (i=0; i<populationSize; i++)
{
for (int j=0; j<DNASIZE; j++)
{
population[i][j]=rand.nextInt(2);
}
}
generation++;
score = PlayRound(population, numberOfRounds); totalScore=0;
for(i=0; i<populationSize; i++)
{
totalScore += score[i];
}
cooperation = (double) totalScore/(3*(double) numberOfRounds*((double) populationSize/2)*((double)populationSize/2));
/*System.out.println("Total score for generation "+generation+": "+totalScore+".\n");*/
System.out.println(/*"Cooperation: "+*/cooperation/*+"\n"*/);
while (cooperation<targetCooperation)
{
/*population = Crossover(population, score);*/
for(i=0; i<population0.length; i++)
{
System.arraycopy(population[i], 0, population0[i], 0, population[i].length);
score0[i]=score[i];
System.arraycopy(population[i+population0.length], 0, population1[i], 0, population[i].length);
score1[i]=score[i+population0.length];
}
population0 = Crossover2(population0, score0);
population1 = Crossover2(population1, score1);
for(i=0; i<population0.length; i++)
{
System.arraycopy(population0[i], 0, population[i], 0, population[i].length);
score[i]=score0[i];
System.arraycopy(population1[i], 0, population[i+population0.length], 0, population[i].length);
score[i+population0.length]=score1[i];
}
/* muutosten loppu */
population = Mutate(population);
generation++;
score = PlayRound(population, numberOfRounds); totalScore=0;
for(i=0; i<populationSize; i++)
{
totalScore += score[i];
}
cooperation = (double) totalScore/(3*(double) numberOfRounds*((double) populationSize/2)*((double)populationSize/2));
/*System.out.println("Total score for generation "+generation+": "+totalScore+".\n");*/
System.out.println(/*"Cooperation: "+*/cooperation/*+"\n"*/);
}
System.out.println("Done");
score=PlayRound(population, numberOfRounds);
}
private static int[] PlayRound (int[][] population, int numberOfRounds)
{
int[] score;
int[] history;
int bitToCheck0 = 3;
int bitToCheck1 = 2;
score = new int[population.length];
history = new int[4];
for(int i=0; i<population.length/2; i++)
{
for(int j=population.length/2; j<population.length; j++)
{
if (population[i][0]==population[j][0]) {
if (population[i][0]==0) {score[i]+=2;
score[j]+=1;bitToCheck0=1;bitToCheck1=1;history[0]=0;history[1]=0;}
else {score[i]+=1; score[j]+=2;bitToCheck0=4;bitToCheck1=4;history[0]=1;history[1]=1;}
}
if (population[i][0]==0 && population[j][0]==1) {bitToCheck0=2;bitToCheck1=3;history[0]=0;history[1]=1;
}
if (population[i][bitToCheck0]==population[j][bitToCheck1])
{
if (population[i][bitToCheck0]==population[j][bitToCheck1]) {
if (population[i][bitToCheck0]==0) {score[i]+=2; score[j]+=1;history[2]=0;history[3]=0;}
else {score[i]+=1; score[j]+=2;history[2]=1;history[3]=1;}
}}
else if (population[i][bitToCheck0]==0 && population[j][bitToCheck1]==1) {history[2]=0;history[3]=1;}
else {history[2]=1;history[3]=0;}
history[1]=history[1];
for (int k=2;k<numberOfRounds;k++)
{
bitToCheck0 = 5+8*history[0]+4*history[1]+2*history[2]+history[3];
bitToCheck1 = 5+8*history[1]+4*history[0]+2*history[3]+history[2];
history[0]=history[2];history[1]=history[3];
if (population[i][bitToCheck0]==population[j][bitToCheck1])
{
if (population[i][bitToCheck0]==0) {score[i]+=2;
score[j]+=1;history[2]=0;history[3]=0;}
else {score[i]+=1; score[j]+=2;history[2]=1;history[3]=1;}
}
else if (population[i][bitToCheck0]==0 && population[j][bitToCheck1]==1) {history[2]=0;history[3]=1;}
else {history[2]=1;history[3]=0;}
}
}
}
return score;
}
private static int[][] Crossover(int[][] population, int[] score)
{
int totalScore0 = 0;
int totalScore1 = 0;
int i=0; int j=0;
int halfPopulation = score.length/2;
int roulette; int father; int mother; int cutoff;
int[][] newPopulation;
int[] child1; int[] child2;
Random rand = new Random();
newPopulation = new int[population.length][population[0].length];
child1 = new int[population[0].length]; child2 = new int[population[0].length];
/* Pisteet toiseen potenssiin */
for(i=0; i<score.length; i++)
{
score[i]=score[i]*score[i];
}
/**/
for(i=0; i<score.length/2; i++)
{
totalScore0+=score[i];
}
for(i=score.length/2; i<score.length; i++)
{
totalScore1+=score[i];
}
/*
for(i=0; i<score.length/2; i++)
{
totalScore0+=score[i];
}
*/
for(i=0; i<score.length/2; i++)
{
roulette = rand.nextInt(totalScore0)+1; father=-1;
while (roulette>0) {
father++;
roulette-=score[father];
}
roulette = rand.nextInt(totalScore1)+1; mother=score.length/2-1;
while (roulette>0) {
mother++;
roulette-=score[mother];
}
cutoff = rand.nextInt(population[0].length-1);
for(j=0; j<cutoff; j++)
{
child1[j]=population[father][j]; child2[j]=population[mother][j];
}
for(j=cutoff;j<child1.length; j++)
{
child1[j]=population[mother][j]; child2[j]=population[father][j];
}
if(rand.nextInt(2)==0)
{
System.arraycopy(child1, 0, newPopulation[i], 0, child1.length);
System.arraycopy(child2, 0, newPopulation[i+halfPopulation], 0, child2.length);
/*newPopulation[i]=child1; newPopulation[i+halfPopulation]=child2;*/
}
else
{
/*newPopulation[i]=child2; newPopulation[i+halfPopulation]=child1;*/
System.arraycopy(child2, 0, newPopulation[i], 0, child2.length);
System.arraycopy(child1, 0, newPopulation[i+halfPopulation], 0, child1.length);
}
}
return newPopulation;
}
private static int[][] Mutate(int[][] population)
{
int i; int j;
double mutationProbability = 0.01;
Random rand = new Random();
for(i=0; i<population.length; i++)
{
for(j=0; j<population[i].length; j++)
{
if(rand.nextDouble()<mutationProbability)
{
if(population[i][j]==1) population[i][j]=0; else population[i][j]=1;
}
}
}
return population;
}
private static int[][] Crossover2(int[][] population, int[] score)
{
int totalScore = 0;
int i=0; int j=0;
int roulette; int father; int mother; int cutoff;
int[][] newPopulation;
int tempScore;
int[] child;
Random rand = new Random();
newPopulation = new int[population.length][population[0].length];
child = new int[population[0].length];
/* Pisteet toiseen potenssiin */
for(i=0; i<score.length; i++)
{
score[i]=score[i]*score[i];
}
/**/
for(i=0; i<score.length; i++)
{
totalScore+=score[i];
}
for(i=0; i<score.length; i++)
{
roulette = rand.nextInt(totalScore)+1; father=-1;
while (roulette>0) {
father++;
roulette-=score[father];
}
tempScore = score[father]; totalScore-=score[father]; score[father]=0;
roulette = rand.nextInt(totalScore)+1; mother=-1;
while (roulette>0) {
mother++;
roulette-=score[mother];
}
totalScore+=tempScore; score[father]=tempScore;
cutoff = rand.nextInt(population[0].length-1);
if(rand.nextInt(2)==0)
{
tempScore=father; father=mother; mother=tempScore;
}
for(j=0; j<cutoff; j++)
{
child[j]=population[father][j];
}
for(j=cutoff; j<child.length; j++)
{
child[j]=population[mother][j];
}
System.arraycopy(child, 0, newPopulation[i], 0, child.length);
}
return newPopulation;
}
}