II OSA sisukord |
2.4 JUHUSLIKKUS
Mis on juhuslik?
def juhuslik_arv(): # Valitud ausa täringuviske põhjal, juhuslikkus garanteeritud return 4
Eelnev programmijupp on tuntud programmeerijate anekdoot juhuslikkuse kohta (ingliskeelne originaal).
Nali seisneb selles, et tavakeeles tähendab juhuslikkus tihti midagi muud kui programmeerijate jaoks. Kui paluda kaaslasel öelda üks juhuslik arv, siis mida saame tema valiku kohta öelda? Mis teeb sellest valikust juhusliku valiku? Kui laseme tal teist korda valida ja ta valib sama arvu, kas siis tema valik polegi juhuslik? Või oli esimene valik juhuslik ja teine mitte?
Mida mõtleme, kui ütleme, et mingi sündmus on juhuslik? Loomulik tundub, et sündmus võiks olla juhuslik siis, kui me ei osanud enne toimumist seda ette ennustada. Sel juhul paistab justkui sündmuse juhuslikkus sõltuks vaatlejast - oleks subjektiivne. Või hoopis on juhuslikud ainult need sündmused, mida on fundamentaalselt võimatu ette ennustada, olenemata vaatlejast?
Juhuslikkuse eesmärgid
Programmeerimises eristatakse tihti mitmeid erinevaid juhuslikkuse tüüpe sõltuvalt rakendustest.
Tuttav Pythoni funktsioon randint
genereerib juhusliku täisarvu antud lõigust. Kuid kuidas suudab arvuti kui deterministlik ja rangelt defineeritud käitumisega masin tekitada midagi juhuslikku? Ei suudagi, vähemalt mitte otseselt. Selle funktsiooni realiseerimiseks kasutatakse kavalaid matemaatilisi ja statistilisi võtteid, et jätta programmeerijale või rakenduse kasutajale mulje justkui tegemist oleks juhusliku arvuga. Tegelikult tekib see arv läbi keeruliste (kuid deterministlike) valemite või algoritmide, mis võtavad sisendiks mingi väikese hulga infot ja muundavad selle näivaks juhuslikkuseks.
Selliset juhuslikkust nimetatakse pseudojuhuslikkuseks, kusjuures eelnevalt mainitud sisendinfot kutsutakse juhuslikkuse seemneks (ingl random seed).
Pythonis on pseudojuhuslikkuse generaatorina kasutusel algoritm nimega Mersenne Twister, konkreetse Pythoni implementatsiooniga on võimalik tutvuda siin. Juhuslikkuse seemnest räägitakse tavaliselt mitte kui sõnest ega arvust, vaid bittide järjendist, sest bitid on kõige fundamentaalsemad informaatsiooniühikud. Seemnena kasutatakse pseudoarvude generaatorite juures tihti väärtuseid, mis väga tihti muutuvad ja millel on palju erinevaid olekuid. Python kasutab selles rollis kas arvuti operatsioonisüsteemi poolt pakutud juhuslikkuse allikat või sekundite arvu, mis on möödunud 1. jaanuarist 1970. a (vt Forte: UNIXi ajaarvamine jõuab 1234567890ni või ingl Unix time).
Enamik operatsioonisüsteeme pakuvad programmidele kasutamiseks juhuslikku infot, mis on pärit mingist füüsilisest allikast. Näiteks võib süsteem mõõta miniatuurseid temperatuuri kõikumisi mõne riistvarakomponendi juures.
Sellist tüüpi juhuslikkust nimetatakse tõeliseks juhuslikkuseks ning seda iseloomustab informatsiooni kordumatus.
Kui pseudojuhuslikult genereeritud arve on võimalik seemne põhjal uuesti tekitada, siis tõeline juhuslikkus ei sõltu mingist teadaolevast infost (seemnest). Tõelist juhuslikkust tekitatakse ka näiteks, mõõtes atmosfäärilist müra või muid füüsikalisi nähtuseid. Tõeliselt juhuslike arvude või sõnede genereemist pakub tasuta random.org. Krüptograafiliste rakenduste juures on äärmiselt oluline, et kasutatav juhuslikkus oleks just tõeline, mitte pseudojuhuslikkus. Vastasel juhul võib ründajal olla võimalus näivalt juhuslike andmeid ära arvata.
Erinevad jaotused
Vahel arvatakse juhuslikkusest rääkides, et võimalikud sündmused või väärtused peavad olema võrdvõimalikud, kuid see ei pruugi sugugi nii olla. Kui viskame palju kordi tavalist kuuetahulist täiringut, siis näeme tulemusi kokku võttes, et iga väärtus 1-6 esines keskmiselt sama palju kordi. Mis juhtub aga, kui viskame kahte kuuetahulist täringut korraga ja liidame saadud silmade arvud kokku?
from random import randint # Tekitame 12-elemendilise listi, kus iga element on 0 vaartused = [0] * 12 for i in range(10000): taring_1 = randint(1, 6) taring_2 = randint(1, 6) summa = taring_1 + taring_2 # Lisame ühe juurde elemendile, mis tähistab saadud tulemust vaartused[summa-1] += 1 print(vaartused)
Enam pole tulemuste jaotus üldse ühtlane, vaid palju rohkem on tulnud tulemusi, mis jäävad keskmiste väärtuste hulka. See on ka intuitiivne, sest summa 2 saamiseks on ainult üks võimalus, kuidas täringud peavad jääma: 1+1. Aga näiteks summa 7 saamiseks on variante lausa kuus: 1+6, 2+5, 3+4, 4+3, 5+2, 6+1.
Samad ideed on kasutusel ka loteriides ja hasartmängudes. Näiteks Bingo Loto puhul on iga palli loosimine võrdvõimalik, kuid õnneratta keerutamisel on ratta peal väiksemaid summasid vähem kui suuremaid.
II OSA sisukord |