A.S.: Jep, ilmeisesti ’nopan’ yksikkö on ’die’. đ
InternetissÀ on liikkunut hankala ohjelmointitehtÀvÀ, joka, kuten olet saattanut arvata yrittÀmÀstÀni pragmaattisesta otsikosta, voidaan formalisoida seuraavasti:
Suoritetaan funktio, joka palauttaa yhdenmukaisesti satunnaisen luvun vÀliltÀ 1-5 (mukaan lukien), suunnittele funktio, joka palauttaa yhdenmukaisesti satunnaisen luvun vÀliltÀ 1-7 (mukaan lukien).
Jos algoritmien ja tilastotieteen leikkauspiste on sinun juttusi, kokeile rohkeasti! LisÀhaasteena on tehdÀ algoritmistasi ajallisesti rajattu. Huomasin tÀmÀn olevan hauska harjoitus, vain tajutakseni, ettÀ tÀssÀ on perustavanlaatuisia rajoituksia.
Tietysti kuutio tarkoittaa tÀssÀ tÀydellisen tasaista satunnaisgeneraattoria, joka on olemassa vain teoriassa. Reaalimaailman noppia sÀÀtelevÀt luonnonlait ja ympÀristön epÀtÀydellisyydet niin, ettÀ ne ovat vain approksimaatio (vaikkakin hyvÀ) tÀstÀ abstraktista mallista.
Rajaton ratkaisu
Katsotaanpa rajaton algoritmien perhe. Luodaksemme satunnaisgeneraattorin, jolla on vÀhintÀÀn 7 lopputulosta, meidÀn on heitettÀvÀ viisisivuista noppaa vÀhintÀÀn kaksi kertaa. Kahdesti heittÀmÀllÀ saadaan 5^2=25 mahdollista tulosta, ja vaikka tÀmÀ ei ole 7:n kerroin, voimme jakaa ensimmÀiset 21 tulosta seitsemÀÀn yhtÀ suureen ryhmÀÀn, joiden koko on 3. Jos pÀÀdymme kuitenkin johonkin jÀljellÀ olevista neljÀstÀ tuloksesta, menettely on aloitettava uudelleen. Emme voi yksinkertaisesti mÀÀrittÀÀ mitÀ tahansa nÀistÀ neljÀstÀ epÀonnisesta lopputilanteesta jollekin ulostulolle, sillÀ tÀmÀ sotkee tasaisen satunnaisuuden ominaisuuden.
YllĂ€ olevassa kaaviossa ympyrĂ€t edustavat ohjelmamme ”tiloja”, ja niiden sisĂ€llĂ€ oleva teksti on heittokuution viimeisin arvo. VihreĂ€t laatikot edustavat sitten tulostetta, jonka annamme riippuen lopputilasta (= sen jĂ€lkeen, kun olemme heittĂ€neet noppaa kahdesti). 84 % ajasta saamme tuloksen kahden heiton jĂ€lkeen ja algoritmi pÀÀttyy. Kuten nĂ€et, silmukka on lĂ€snĂ€ ja tekee algoritmista rajoittamattoman. TĂ€mĂ€ tarkoittaa, ettĂ€ jokaisella kokonaisluvulla, olipa se kuinka suuri tahansa, on pieni mutta nollasta poikkeava todennĂ€köisyys sille, ettĂ€ heittojen kokonaismÀÀrĂ€ ylittÀÀ kyseisen mÀÀrĂ€n yhden lĂ€htöarvon laskemiseksi. Reaaliaikaiset sovellukset, joilla on tiukat aikavaatimukset, eivĂ€t siis tule kysymykseen, ellet ole valmis tekemÀÀn kompromisseja algoritmin tilastollisen tarkkuuden suhteen.
TĂ€mĂ€n ratkaisun muunnos heittÀÀ aluksi enintÀÀn kolme noppaa ennen uudelleenkĂ€ynnistystĂ€: tĂ€mĂ€ luo 5^3=125 lopputilaa, ja voimme mÀÀrittÀÀ niistĂ€ korkeintaan 119 seitsemÀÀn yhtĂ€ suureen ryhmÀÀn 17. Nyt on 95,2 % todennĂ€köisyys lopettaa enintÀÀn kolmen heiton jĂ€lkeen. Huomaa, ettĂ€ joudumme heittĂ€mÀÀn keskimÀÀrin vĂ€hemmĂ€n kertoja kuin aiemmin (280/119 â 2,35 vs. 50/21 â 2,38), koska useimmiten voimme jo kahden ensimmĂ€isen heiton jĂ€lkeen oikotietĂ€ ja liittÀÀ nĂ€mĂ€ vĂ€litilat suoraan tulokseen. TĂ€mĂ€ keskimÀÀrĂ€inen heittomÀÀrĂ€ laskee koko ajan, kun jatkamme trendiĂ€.
Jos olet perehtynyt informaatioteoriaan, niin mieti, ettĂ€ yksi heitto viisisivuisella nopalla (= rand5) tuottaa log2(5) â 2,32 bittiĂ€ informaatiota, ja yksi heitto seitsenpuolisella nopalla (= rand7) tuottaa log2(7) â 2,81 bittiĂ€ informaatiota. Osoittautuu, ettĂ€ rajatapauksessa tarvitsemme vain log(7)/log(5) â 1,21 rand5-kutsua jokaista rand7-arvoa kohden, jonka haluamme saada. Tarkka toteutus, joka toimii mielivaltaisesti lĂ€hellĂ€ tĂ€tĂ€ raja-arvoa, on melko monimutkainen ja tĂ€mĂ€n artikkelin soveltamisalan ulkopuolella. MeidĂ€n olisi tallennettava tilatietoa useiden rand7-kutsujen vĂ€lissĂ€, ja mieleeni tuleva algoritmi on edelleen rajoittamaton paitsi ajallisesti myös muistin suhteen. PyydĂ€n teitĂ€ mielellĂ€ni ilmoittamaan minulle menetelmĂ€n, joka ratkaisee tĂ€mĂ€n jĂ€lkimmĂ€isen ongelman!
Rajoitettu ratkaisu
Ei ole olemassa rajattua algoritmia, joka laskee tĂ€ydellisen yhdenmukaisen satunnaisarvon vĂ€liltĂ€ 1 ja 7, kun satunnaisgeneraattorille annetaan vain vĂ€liltĂ€ 1 ja 5. Tarkastellaan yllĂ€ olevaa rajoittamattomien ratkaisujen perhettĂ€. Kuten olen vihjannut, jokaisessa pisteessĂ€ on aina tietty mÀÀrĂ€ ”jĂ€ljelle jÀÀviĂ€” tiloja (jotka vaihtelevat vĂ€lillĂ€ 1-6), jotka aiheuttavat algoritmin uudelleenkĂ€ynnistyksen. TĂ€mĂ€ johtuu siitĂ€, ettĂ€ 5 ja 7 ovat alkulukuja, eikĂ€ mikÀÀn 5:n potenssi voi koskaan olla 7:n kerrannainen. Vaikka olisi kuinka houkuttelevaa kĂ€yttÀÀ Fermat’n pientĂ€ teoreemaa, tĂ€llaiset yritykset johtavat off-by-one-virheisiin, koska peruslukuteoria tekee rajoitetun ratkaisun tĂ€ssĂ€ perheessĂ€ mahdottomaksi.
Voit oikeutetusti huomauttaa, ettĂ€ lopputilojen mÀÀrĂ€ ei ole aina potenssi 5:stĂ€, esimerkiksi tapauksessa ”enintÀÀn kolme heittoa”, jossa voimme oikaista jo kahden heiton jĂ€lkeen. EhkĂ€ voisimme jĂ€rjestÀÀ tilakaavion niin, ettĂ€ syntyy rajattu algoritmi, jossa on vaihtelevan pituisia polkuja ja 7n lopputilaa? Mieti kuitenkin seuraavaa:
- NÀmÀ lopputilat eivÀt ole yhtÀ todennÀköisiÀ, koska kaikki polut eivÀt ole yhtÀ pitkiÀ (= rand5-kutsujen mÀÀrÀ).
- Voisimme hyvin helposti laajentaa puun niin, ettÀ jokaisesta polusta tulee yhtÀ pitkÀ, kutsumalla rand5:tÀ turhaan sopivan monta kertaa aina kun olemme ennenaikaisessa lopputilassa. Nyt lopputilojen mÀÀrÀstÀ tulee taas 5:n potenssi, ja kaikki lopputilat ovat yhtÀ todennÀköisiÀ.
TÀmÀ ei tietenkÀÀn ole muodollinen todiste, mutta toivon antaneeni sinulle jonkinlaisen intuition ongelmasta. Kuten nÀemme, joskus ongelma voi tuntua hyvin realistiselta, kunnes sitten törmÀÀ tÀllaisiin matemaattisiin tosiasioihin. Pystytkö tÀmÀn analyysin jÀlkeen keksimÀÀn, onko mahdollista simuloida 8-puolista noppaa alkaen 4-puolisesta nopasta?