[edit 31.3.24 korjasin pythonkoodin tulostusrivit. 1.4.24. lisäsin esimerkkitiedosto lähteisiin.]
Kevään 24 pitkän matematiikan yo-koetehtävässä tutkittiin satunnaisliikkettä. Esitän pari erilaista ratkaisutavaa GeoGebralla ja Pythonilla. GeoGebra-esimerkeissä käytetään Jono ja Zip-komentoja. Python-esimerkeissä for-silmukkaa sekä map ja itertools.product -funktioita.
11. brownin liike
Vuonna 1827 kasvitieteilijä Robert Brown tutki mikroskoopilla, miten siitepölyhiukkanen liikkuu nykien vedessä. Brownin koe viittasi molekyylien olemassaoloon, ja sillä oli siten tärkeä rooli atomiteorian historiassa. Tutkitaan yksinkertaistettua Brownin liikettä. Hiukkasen liike tasossa alkaa origosta. Tasaisin väliajoin hiukkanen liikkuu yhden yksikön verran joko ylös, alas, oikealle tai vasemmalle. Jokaisen suunnan todennäköisyys on 1/4. Esimerkiksi ensimmäisen askeleen jälkeen mahdolliset sijainnit ovat (0, 1), (0, -1), (1, 0) ja (-1, 0). Tutkitaan hiukkasen sijaintia neljän askeleen jälkeen. Kutsutaan tätä päätepisteeksi. Määritä päätepisteen kaikki mahdolliset x-koordinaatit sekä niiden todennäköisyydet.
ratkaisu geogebralla
Kun hiukkanen liikkuu tehtävänannon mukaisesti, niin yhdellä liikkumiskerralla x-koordinaatti voi muuttua neljällä yhtä todennäköisellä tavalla 0, 0, -1, +1 (paitsi eihän se koordinaatti muutu nollatapauksissa). Määritetään kaikki mahdolliset päätepisteen arvot GeoGebra sisäkkäisillä jonokomennoilla.

l1-jono näyttää kokonaisuudessaan tältä
{{{{0, 0, -1, 1}, {0, 0, -1, 1}, {-1, -1, -2, 0}, {1, 1, 0, 2}}, {{0, 0, -1, 1}, {0, 0, -1, 1}, {-1, -1, -2, 0}, {1, 1, 0, 2}}, {{-1, -1, -2, 0}, {-1, -1, -2, 0}, {-2, -2, -3, -1}, {0, 0, -1, 1}}, {{1, 1, 0, 2}, {1, 1, 0, 2}, {0, 0, -1, 1}, {2, 2, 1, 3}}}, {{{0, 0, -1, 1}, {0, 0, -1, 1}, {-1, -1, -2, 0}, {1, 1, 0, 2}}, {{0, 0, -1, 1}, {0, 0, -1, 1}, {-1, -1, -2, 0}, {1, 1, 0, 2}}, {{-1, -1, -2, 0}, {-1, -1, -2, 0}, {-2, -2, -3, -1}, {0, 0, -1, 1}}, {{1, 1, 0, 2}, {1, 1, 0, 2}, {0, 0, -1, 1}, {2, 2, 1, 3}}}, {{{-1, -1, -2, 0}, {-1, -1, -2, 0}, {-2, -2, -3, -1}, {0, 0, -1, 1}}, {{-1, -1, -2, 0}, {-1, -1, -2, 0}, {-2, -2, -3, -1}, {0, 0, -1, 1}}, {{-2, -2, -3, -1}, {-2, -2, -3, -1}, {-3, -3, -4, -2}, {-1, -1, -2, 0}}, {{0, 0, -1, 1}, {0, 0, -1, 1}, {-1, -1, -2, 0}, {1, 1, 0, 2}}}, {{{1, 1, 0, 2}, {1, 1, 0, 2}, {0, 0, -1, 1}, {2, 2, 1, 3}}, {{1, 1, 0, 2}, {1, 1, 0, 2}, {0, 0, -1, 1}, {2, 2, 1, 3}}, {{0, 0, -1, 1}, {0, 0, -1, 1}, {-1, -1, -2, 0}, {1, 1, 0, 2}}, {{2, 2, 1, 3}, {2, 2, 1, 3}, {1, 1, 0, 2}, {3, 3, 2, 4}}}}
Noista runsaista sisäkkäistä sulkeista pääsee eroon Tiivistä-komennolla. Päätepisteiden lukumäärät saa laskettua pistelistaksi LaskeJos-komennon avustuksella. LaskeJos-komennossa olevan ehtolauseen saa kirjoitettua näppäimistöltä muodossa (x==m, l2)
Bonuksena saa ratkaisun näkymään Piirtoalueella.

Toinen mahdollinen tapa käydä kaikki eri vaihtoehdot on käyttää Zip-komentoa. Tämä komentorivi näyttää ainakin minun silmissäni selkeämmältä kuin sisäkkäiset Jono-komennot.
l1=Zip(Zip(Zip(Zip(i + j + k + n, i, l), j, l), k, l), n, l)
Todennäköisyydet saa pistelistaksi komennolla
l4=Jono((i, LaskeJos(x==i, l2) / 256), i, -4, 4, 1)
l4 = {(-4, 0.004), (-3, 0.031), (-2, 0.109), (-1, 0.219), (0, 0.273), (1, 0.219), (2, 0.109), (3, 0.031), (4, 0.004)}
ratkaisu pythonilla
Pythonilla tällainen brute force-ratkaisu tehdään perinteisesti for-silmukoilla. Alla olevasta koodista löytynee selitys sille, miten se toimii.


Toinen tapa tuottaa kaikki eri 44 = 256 vaihtoehtoa on käyttää itertools-kirjaston product-funktiota. Se tuottaa syötelistoistaan kaikki eri vaihtoehdot (karteesinen tulo) monikkoina (tuple).

[(-1, -1, -1, -1), (-1, -1, -1, 0), (-1, -1, -1, 0), (-1, -1, -1, 1), (-1, -1, 0, -1), (-1, -1, 0, 0), ..., (1, 1, 1, 0), (1, 1, 1, 1)]
Seuraavassa esimerkissä suoritan tarvittavat yhteenlaskut Pythonin map-funktiolla. Se toimii saman tyyppisesti kuin GeoGebran Zip-komento. Alla olevassa esimerkissä map laskee sum-funktion avulla listassa olevien kolmikkojen summat. Jotta syntyneen iteroituvan listan saa tulostettua, se pitää muuttaa tulostettavaksi listaksi list-komennolla.

Eri päätepisteiden lukumäärä saadaan count()-metodilla.

Lopullinen koodi.

pieni huomautus jono ja zip-komentojen sekä for-silmukoiden, map ja product-funktioiden käyttöön
Kun alat tekemään koodeja sisäkkäisillä silmukoilla, niin ole varovainen. Ainakin minulla tulee helposti virheitä, koska koodista tulee helposti monimutkaisia. Kokeile ensin pienillä esimerkeillä, että koodi toimii oikein ja suhtaudu silloinkin skeptisesti oman koodisi oikeellisuuden suhteen.
Itertoolsin product ja map-funktio sen kanssa käytettynä, on siinä mielessä tärkeä, että menetelmä on jonkin verran nopeampi kuin for-silmukka. Esimerkiksi koodini ilman tulostusta for-silmukalla kesti 520 mikrosekuntia. Product ja map-menetelmällä aikaa kului 470 mikrosekuntia


lopuksi
Tämä ratkaisu on täysin omasta päästäni ja se ei liity millään tavalla ylioppilaskokeen arvosteluun.
lähteet
Kevään 2024 pitkän matematiikan ylioppilaskoe
https://yle.fi/plus/abitreenit/2024/kevat/matematiikka_pitka/index.html#question-nr-11
Python lähdekoodi Colabissa
https://colab.research.google.com/drive/1s90ClfZ2yWFY9FoC92klUEW435y1Q751?usp=sharing
Esimerkkitiedosto GeoGebra Materiaaleissa
https://www.geogebra.org/m/kmmtqmgn
Kolme noppaa ja Zip-komento
https://mikkorahikka.blog/2019/08/27/kolme-noppaa-ja-zip-komento/
Ohjelmoinnin perusteet ja jatkokurssi 2021: Tuple
https://ohjelmointi-21.mooc.fi/osa-5/4-tuple
W3schools: Python map() Function
https://www.w3schools.com/python/ref_func_map.asp
Geeg for Geegs: Python – Itertools.Product()
https://www.geeksforgeeks.org/python-itertools-product/
Listametodit esimerkeillä, append() ja count()-metodien esimerkit löytyy täältä
https://mikkorahikka.blog/2022/12/29/lista-metodit-esimerkeilla/
1D satunnaiskävely Pythonilla & histogrammeja – osa 2
https://mikkorahikka.blog/2022/04/27/1d-satunnaiskavely-pythonilla-histogrammeja-osa-2/

Jätä kommentti