Monty Hall Pythonilla – osa 2

Pari viikkoa sitten käsittelin Monty Hall -probleemaa Python ohjelmoinnin avulla. Jatkan tässä tarinaa aiheesta. Yleistetään ongelmaa hieman ja saadaan uusia ongelmia ratkaistavaksi. Aiempi artikkeli löytyy täältä.

Ongelma sanallisesti

Wikipediassa perinteinen Monty Hall -ongelma esitetään seuraavasti: ”Monty Hallin ongelmassa kilpailijalla on edessään kolme ovea. Yhden oven takana on palkintona auto, kahden muun takana vuohi. Kilpailija, joka ei tiedä minkä oven takana mikin palkinto on, saa valita ovista yhden. Valittuaan oven hän ei vielä avaa sitä. Jäljelle jääneistä kahdesta ovesta avataan toinen, ja sen takana on aina vuohi. Tämän jälkeen kilpailija saa valita, vaihtaako ensin valitsemansa oven toiseen jäljellä olevaan suljettuun oveen, vai pitääkö ensin valitsemansa oven.”

Yleistetään ongelmaa siten, että vuohien ja autojen määrää voi vaihtaa. Ongelma olisi nyt tämän kaltainen. ”Olkoon v vuohien määrä (v > 1) ja a autojen määrä ( a ≥ 1). Ovien määrä on v + a.  Vuohet ja autot laitetaan satunnaisesti, yksi kunkin suljetun oven taakse. Kilpailija valitsee jonkin oven. Sen jälkeen lopuista ovista poistetaan yksi sellainen ovi, jonka takana on vuohi. Tämän jälkeen kilpailija saa valita, vaihtaako ensin valitsemansa oven johonkin jäljellä olevaan suljettuun oveen, vai pitääkö ensin valitsemansa oven.”

Ratkaisu Pythonilla

Tehdään Pythonilla simulaatio, jossa pelaaja aina vaihtaa valintansa. Tutkitaan aluksi sellaista erikoistapausta, jossa on kolme ovea ja kaksi autoa. Yritän tässä jäljitellä minun tapaani tuottaa ohjelmia, ensin yritän saada ohjelman toimimaan yksinkertaisella versiolla, sitten siirryn monimutkaisempaan tapaukseen. Pyrin myös välttämään kovin pitkiä, vaikeasti luettavia koodirivejä. En myöskään pyri tässä mahdollisimman tehokkaaseen koodin. Tämä on tarkoitettu opiskelumateriaaliksi opettajille ja ohjelmoinnista kiinnostuneille koululaisille ja opiskelijoille.

Koodi

Alla olevat kuvankaappaukset ovat Spyder ohjelmointiympäristön editorin ja konsolin kuvia. Eli kuvassa näkyy ohjelma ja sen tuotos.

Jos olet lukenut edellisen tarinan ja ymmärtänyt sen, niin koodi taitaa olla aika itsestään selvä. Muutamia kommentteja silti. 

Rivit 1-7: Spyderin tuottamaa metatietoa, tämä on ”turhaa”. Toki rivi 2 takaa, että ääkkösten pitäisi toimia.

9-10: Random kirjaston funktiot, shuffle sekoittaa listan ja randint arpoo kokonaisluvun.

13: Luodaan ovet, nollat vuohia ja ykköset autoja eli voittoja.

16: Sekoitetaan ovet-lista.

20: Arvotaan luku väliltä 0, …, 4. Tässä pitää muistaa, että Pythonissa listan ensimmäisen jäsenen järjestysluku on 0. Funktio len(lista) tulostaa lista pituuden eli sen jäsenten lukumäärän. 

28: pop-metodi poistaa olion listasta ja antaa sen tulosteena.  Jos lista  = [13, 42, 666, 42], niin lista.pop(1) antaa tulokseksi luvun 42 ja samalla listasta katoaa jäsen 42, eli nyt lista on [13, 666, 42].

32: remove-metodi poistaa ensimmäisen esiintymän syötteestään. Jos lista  = [13, 42, 42, 666, 42], niin lista.remove(42) muuttaa sen listaksi [13, 42, 666, 42].

37: Sekoitetaan jäljelle jääneet ovet uudestaan.

42: Valitaan ensimmäinen ovi. En enää jaksa arpoa jotain ovea ja sen jälkeen avata sitä, avaan eina ekan oven. Rivin 37 sekoittaminen takaa, että ovi on satunnainen. Saman olisi tietysti voinut tehdä jo rivillä 20, mutta siellä yritin noudattaa alkuperäistä reseptiä.

46-49 Päätöksentekoa voitosta.

Kuva, joka sisältää kohteen teksti

Kuvaus luotu automaattisesti

Alla pari suorituskertaa.

Kuva, joka sisältää kohteen teksti

Kuvaus luotu automaattisesti

Iterointia

Toistetaan peliä muutaman kerran ja lasketaan kuinka suuri osa tuottaa voittoja.

Kuva, joka sisältää kohteen teksti

Kuvaus luotu automaattisesti
Kuva, joka sisältää kohteen teksti

Kuvaus luotu automaattisesti

Ongelmia

Palannen yleiseen ongelmaan lähiaikoina. Nyt varmaankin valistunut lukija pystyy itsekin tuottamaan oman ratkaisunsa tämän kaltaisiin ongelmiin.

1 Jos vuohia on x kpl ja autoja y, niin määritä P(x, y).

2 Milloin P(x, y) > ½? Millainen tasoalue on kyseessä?

3 Kun sinulla on lauseke P:lle. Miten esittäisit sitä fiksuimmin kuvaajana?

4 Etsi pilkkuvirhe artikkelista.

koodi colabissa

täshätää

Jos edellä oleva linkki ei toimi, niin koita toisella selaimella.

Jakaumakomentoja GeoGebralla 1

[edit. 3.11 Lisäsin Miken kommentin GeoGebra-foorumilta]

Lukion lyhyen matematiikan Tilastot ja todennäköisyys 2 -kurssilla opitaan jakaumiin liittyvää matematiikkaa. Kaikkein helpoimmin suurin osa tehtävistä ratkeaa käyttämällä GeoGebra 5 ja 6 versioiden Todennäköisyyslaskuria. Jakaumia voi laskea myös käyttämällä komentoja. Tutkitaan komentojen käyttöä esimerkkien avulla.

Binomijakauma

Esimerkki 1. Heitetään noppaa 10 kertaa. a) Kuinka suurella todennäköisyydellä saadaan tasan kolme kuutosta? b) Kuinka suurella todennäköisyydellä saadaan korkeintaan kolme kuutosta.

GeoGebran CAS:issa Binomijakauma(n, p, k, totuus) laskee Binomijakauman pistetodennäköisyyden arvon, jos totuus on false. Jos totuusarvo on true, niin komento laskee kertymäfunktion arvon.

Ratkaisu:

Kuva, joka sisältää kohteen teksti

Kuvaus luotu automaattisesti

Viimeisellä rivillä näkyy menetelmä, jolla saa laskettua todennäköisyyksien summan peräkkäisillä k:n arvoilla.

Todennäköisyyslaskurilla:

Jos komentoa käyttää syöttökentässä, niin sen avulla saa piirrettyä jakauman histogrammin piirtoalueelle.

Poissonjakauma

Esimerkki 2. Koulun ruokalassa on ruokavälitunnilla keskimäärin 10,3 oppilasta jonossa. Tulet ruokailemaan. a) Millä todennäköisyydellä jonossa on tasan 8 oppilasta ennen sinua? b) Millä todennäköisyydellä jonossa on yli kahdeksan oppilasta. c) Millä todennäköisyydellä jonossa on 3…8 oppilasta?

Komento Poisson( µ, k, totuus ) toimii samalla tavalla kuin Binomijakaumakomentokin.

Ratkaisu:

c-kohta Todennäköisyyslaskurilla:

Nytpä havaitsin bugin GeoGebrassa. Jos tuolla syntaksilla Poisson(10.3, 3..8) odotusarvo on ei luonnollinen luku, niin komento antaa väärän tuloksen. Luonnollisilla odotusarvoluvuilla komento näyttää laskevan oikein. Lähetin aiheesta viestin GeoGebra foorumille. https://help.geogebra.org/topic/poisson10-5-11-16-gives-wrong-answer

Miken vastaus :o)

CAS:issa 

Kuva, joka sisältää kohteen teksti

Kuvaus luotu automaattisesti

antaa saman tuloksen kuin Todennäköisyyslaskurikin.

Syöttökentässä Poisson(10.3) tuottaa jakauman histogrammin.

Tämän bugin selvittämiseen meni sen verran aikaa, että jatkan normaalijakauman komennoista lähipäivinä.

Noppien summa GeoGebralla – n noppaa

Edellisissä artikkeleissani olen käsitellyt 1,…, 3 nopan heittoa simuloiden ja laskemalla todennäköisyysjakaumat. Jotta saisin tämän trilogiani jotenkin päätettyä, niin tarkastelen tässä yleistä n:n nopan summan todennäköisyysjakaumaa tilastollisesti ja laskemalla tarkat arvot käyttämällä polynomin kertoimia. 

Loin appletin GeoGebra 5:llä. Pääosin komennot kirjoitetaan syöttökenttään, todennäköisyysjakauman yhteydessä tarvitaan myös CAS:ia.

simulointi

Olkoon m noppien lukumäärä ja n heittojen määrä. Luodaan liu’t.

m = 10
n = 10000

Liu’un m asetuksissa Min: 1, Max: 10 ja Animaatioaskel: 1, liu’ulla n Min: 0, Max: 10000 ja Animaatioaskel: 100. 

Noppien summat-lista saadaan käyttämällä Jono-komentoja

summat = Jono(Summa(Jono(Satunnaisluku(1, 6), mm, 1, m)), nn, 1, n)

Tässä sisin Jono-komento Jono(Satunnaisluku(1, 6), mm, 1, m) tuottaa m:n pituisen jonon satunnaislukuja 1, 2, …6. Summa laskee edellisen summan ja uloin Jono tuottaa summia n kappaletta. Sisäisiä muuttujia mm ja nn ei käytetä, tuossa kohdin pitää vain olla jokin muuttuja, jotta Jonon syntaksi on oikein. Teoriassa sisemmän Jono-komennon ja Summan olisi pitänyt pystyä korvaamaan yhdellä Summa-komennolla. En saanut sitä toimimaan. Joko GeoGebra tai minun aivoni toimivat tässä kohtaa epäloogisesti.

Tilaston jakauman pylväskaavio tulee yhdellä komennolla

Pylväskaavio(summat, 1, 1 / n)

Taas minua ihmetyttää, miten tämä onnistuu näin vähillä riveillä.

todennäköisyysjakauma

Lasketaan m:n nopan summan todennäköisyysjakauma. Yritän seuraavalla esimerkillä perustella miksi sopivasti valitun polynomin kertoimet kertovat kuinka monella eri tavalla jokin summa voidaan saada nopan heitossa.

Kuvitellaan, että meillä on kaksi kummallista noppaa, jossa toisessa on luvut 1, 2 ja 3 ja toisessa vain luvut 1 ja 2. Eiväthän nuo ihan tavallisia noppia ole, vaan jotain ihan toisesta maailmasta, mieti itse miten toteuttaisit tuollaiset nopat. Millaisia tuloksia ja miten paljon niitä voi tulla.

Summataulukko kertoo meille, että esimerkiksi kolmosen voi saada kahdella eri tavalla (2, 1) ja (1, 2).

Onko jotain algoritmia tuon frekvenssitaulukon tuottamiseksi. Mitäpä jos luodaan polynomi, jossa muuttuja korotetaan nopan arvon potensseihin. Kerrotaan polynomit keskenään. Mitä polynomin kertoimet kertovat.

Katso miten MathPapa poistaa sulkeet ja pohdi miksi potenssit kertovat summan ja kertoimet niiden lukumäärän.

Edellisessä sulkeiden poistamisessa toiseksi viimeiellä rivillä on itse asiassa sama informaatio kuin 2*3 summataulukossa.

Jos pohditaan vaikkapa kuinka monella eri tavalla näiden noppien heitossa summaksi tulee kolme, niin se vastaa polynomin kertolaskussa tilannetta jossa x kerrotaan x^2 tai x^2 kerrotaan x:llä. Eli sam tilanne kuin summataulukon (1, 2) ja (2, 1). Sievennetyssä polynomissa kolmannen asteen kertoimeksi tulee 2. Se kertoo meille kuinka monella tavalla summaksi tulee kaksi.

Tutkitaan kahden perinteisen nopan heittoa, kolmen nopan heittoa jne. Yhtä noppaa vastaa polynomi noppa = a + a^2  + a^3 + a^4 + a^5 + a^6. Silloin kahden nopan summat saadaan noppa-polynomin potenssien kertoimina.

Tässä polynomin kertoimet kertovat esimerkiksi, että kahden nopan heiton 6*6 summataulukossa ysejä on neljä kappaletta. Alla oleva kuva on artikkelin ”Nopat GeoGebralla – kaksi noppaa” esimerkkitiedostosta.

Tuotetaan yleinen jakauma käyttämällä polynomin kertoimia. Määritellään ensin CAS:iin noppa-polynomi. Tämä vastaa yhtä noppaa.

noppa:=a+a^2+a^3+a^4+a^5+a^6
-> noppa:=a^6 + a^5 + a^4 + a^3 + a^2 + a

Tässä vaiheessa kannattaa laittaa m ja n-liukujen arvot sopivan pieniksi.

Poistetaan sulkeet noppa^m polynomista CASissa, tässä m:n arvo on kolme.

pol:=PoistaSulkeet(noppa^m)
-> pol:=a^18 + 3  a^17 + 6  a^16 + 10  a^15 + 15  a^14 + 21  a^13 + 25  a^12 + 27  a^11 + 27  a^10 + 25  a^9 + 21  a^8 + 15  a^7 + 10  a^6 + 6  a^5 + 3  a^4 + a^3

Polynomin kertoimet saadaan Kertoimet-komennolla. Ensimmäinen on tässä 18-asteen termin kerroin ja viimeinen nolla on nollannen asteen termin kerroin.

ker:=Kertoimet(pol)
-> ker:={1, 3, 6, 10, 15, 21, 25, 27, 27, 25, 21, 15, 10, 6, 3, 1, 0, 0, 0}

Käännetään ker-lista toisinpäin Käännä-komennolla Syöttökentässä.

kert = Käännä(ker)

Luodaan histogrammille reunat ja piirretään todennäköisyysjakauma.

reunat = Jono(-0.5, 6m + 0.5, 1)
hist = Histogrammi(reunat, kert / 6^m)

Esimerkkitiedosto löytyy GeoGebra-Materiaaleista https://www.geogebra.org/m/eqsebrjq

Nyt taidan lopettaa noppien tutkiskelun ainakin joksikin aikaa. Nytpä tästä noparartikklelisarjasta tulikin tetralogia. Vai onko tämä kvadrilogia?

Liitteet

Hyvä esitys miksi edellä esitetty polynomien kerroinmenetelmä toimii ”world of math and physics” -blogissa. https://www.lucamoroni.it/the-dice-roll-sum-problem/

Multinomiaali kertoimista hieman haastavampi blogiartikkeli ”A Blog on Probability and Statistics”-blogissa. https://probabilityandstats.wordpress.com/tag/multinomial-coefficients/


Aiemmat aiheeseen liittyvät blogiartikkelini.

Kolme noppaa https://mikonfysiikka.wordpress.com/2020/04/26/nopat-geogebralla-kolme-noppaa/

kaksi noppaa, https://mikonfysiikka.wordpress.com/2020/04/24/nopat-geogebralla-kaksi-noppaa/

yksi noppa, https://mikonfysiikka.wordpress.com/2020/04/23/nopat-geogebralla-yksi-noppa/

kolme noppaa ja zip-komento, https://mikonfysiikka.wordpress.com/2019/08/27/kolme-noppaa-ja-zip-komento/

Youtube-video viiden nopan heitosta https://www.youtube.com/watch?v=oUEbI5_vy-4