Atsitiktiniai skaičiai: kokie jie yra ir kaip jie gaunami?

Spalio 7, 2011

Programuojant labai dažnai tenka susidurti su atvejais, kada prireikia sugeneruoti kokį nors atsitiktinį skaičių ar simbolį. Pvz. sukūrus „monetos metimo“ loteriją, juk realiai niekas ten jokios monetos nemėto, tiesiog kompiuteris sugeneruoja atsitiktinį skaičių (pvz. 0 ir 1) ir galiausiai vėliau išvedamas rezultatas iš to skaičiaus – tarkim, jeigu rezultatas yra 0, išvedamas rezultatas „Iškrito herbas“, o jeigu rezultatas yra 1, tai išvedamas rezultatas „Iškrito skaičius“. Visi žinome, kad kompiuteris yra visiškai logiška mašina, t.y. kompiuteris mums niekad neišves, kad 2+2 yra 5. Taigi, kokiu būdu logikai ir matematikai pavaldi mašina gali sukurti atsitiktinį skaičių?

Problema generuojant atsitiktinius skaičius atsirado vos atsiradus pirmiesiems mikroprocesoriams. Pirmiesiems programuotojams teko ilgokai pasukti galvas, kad sugalvotų, kaip daiktą, kuris visiškai paklūsta matematikai, priversti sugeneruoti atsitiktinį skaičių. Dabar programuotojams tame didelių problemų nekyla – praktiškai kiekviena programavimo kalba turi Random(); funkciją, kuri sugeneruoja tą skaičių ir visiškai nereikia galvoti apie kažkokias matematines formules, kurios skirtos tų skaičių generavimui. Neretas programuotojas (ypač pradedantysis) net nežino, kokiu būdu tie skaičiai yra sugeneruojami.

Atsitiktinių skaičių rūšys yra dvi – tikrieji atsitiktiniai skaičiai ir pseudo-atsitiktiniai skaičiai (pseudo-random). Tikrieji atsitiktiniai skaičiai yra sugeneruojami matuojant visiškai atsitiktinius procesus (branduolinį skilimą, atmosferinį triukšmą ir pan.). Tokiems skaičiams generuoti reikia papildomos įrangos, kaip pvz. Geiger–Müller kameros, kuri fiksuoja branduolinį skilimą ir naudojantis šia informacija galima sugeneruoti visiškai atsitiktinį skaičių. Pseudo-atsitiktinių skaičių generavimas yra loginis metodas, dažniausiai tai yra matematinė formulė. Paprastai tariant, į formulę įstatomas „seed“ ir iš to yra gaunama atsitiktinių skaičių seka. „Seed“ yra nežinomasis formulėje, tik jį pakeitus kažkokiu skaičiumi yra gaunamas atsakymas. Kiekvienąkart įvedus tą patį „seed“, visad gaunama lygiai tokia pati atsitiktinių skaičių seka. Pvz. jeigu įstatysime į formulę 5, visad gausime seką tarkim 147890154278…, taigi norint kaskart gauti vis skirtingą atsitiktinių skaičių seką, reikia, kad „seed“ pasikeistų. Tokiu atveju turbūt kyla klausimas, kokiu būdu kompiuteris gali parinkti atsitiktinį „seed“, kad seka kiekvieną kartą būtų visiškai atsitiktinė? Atsakymas paprastas – negali, todėl dažnai kaip „seed“ yra naudojama dabartinė sistemos data ir laikas unix išraiška. Unix išraiška reiškia sekundžių kiekį, kuris praėjo nuo 1970-ųjų metų sausio pirmos dienos.

Vienas iš pirmųjų pseudo-atsitiktinių skaičių generavimo būdų buvo John von Neumann 1946-aisiais išrastas metodas, vadinamas middle-square metodu. Metodas yra labai paprastas – tiesiog paimamas koks nors skaičius kaip „seed“, jis pakeliamas kvadratu ir viduriniai gauto rezultato skaičiai yra laikomi „atsitiktiniais“. Tuo tarpu, jei reikia sugeneruoti daugiau atsitiktinių skaičių, ankstesnis rezultatas yra panaudojamas, kaip seed, t.y. jis vėl pakeliamas kvadratu ir vėl imami gauto rezultato viduriniai skaičiai. Procesas kartojamas tiek kartų, kiek reikia. Šis metodas veikia tol, kol skaičių reikia labai nedaug, nes vėliau skaičiai gautoje sekoje pradeda kartotis. Pvz. paėmus nulį kaip pradinę reikšmę, skaičiai pradeda kartotis iškart ir gaunama reikšmė būna 0000… Šiuo metu yra rasta daug efektyvesnių pseudo-atsitiktinių skaičių generavimo būdų.

Kur yra naudojami pseudo-atsitiktiniai skaičiai ir kur geriau jų nenaudoti? Pseudo-atsitiktiniai skaičiai labai puikiai tinka statistikai, nes kiekvieno iš skaičių kritimo tikimybė yra lygiai tokia pati. T.y. nebus taip, kad sugeneravus 1 000 000 pseudo-atsitiktinių skaičių eilutę nuo 0 iki 1, gautame rezultate vienetas kartosis 95% kartų, o nulis – tik 5%. Gautame rezultate tikimybių nuokrypis nebus labai didelis, o bus „realus“, pvz 49% nulių ir 51% vienetų. Kadangi šis metodas yra grynai matematinis, visų skaičių tikimybės yra labai tikslios. Tačiau, nors vizualiai pseudo-atsitiktiniai skaičiai visiškai niekuo nesiskiria nuo realių atsitiktinių skaičių, šis metodas dažnai nėra naudojamas didelėse loterijose, kai kuriuose internetiniuose pokerio tinklalapiuose, nes teoriškai gali būti nuspėjamas. Tereikia žinot metodą, kuriuo naudojantis yra sugeneruojami skaičiai ir „seed“, kuris naudojamas (o tai dažnai būna, kaip minėjau, sistemos data ir laikas). Tiriant ilgą atsitiktinių skaičių eilutę gautą iš kokios nors virtualios ar realios loterijos, galima atspėti metodą ir nustatyti naudojamą „seed“, kaip neseniai padarė kanadietis statistikas Mohanas Srivastava, kuris pastebėjo tendencijas ir nustatė algoritmą loterijoje. Taigi, jeigu ruošiatės kurti kažkokią loteriją, geriau nenaudokite pseudo-atsitiktinių skaičių generatoriaus, nes Jūsų loterija gali būti paprasčiausiai „nulaužta“. :)

P.S. Žinau, kad gal kai kur mano rašymo stilius gali būti kiek per sudėtingas, todėl, jei kas nors neaišku – praneškite komentaruose. :)

10 komentarai(-ų) prie “Atsitiktiniai skaičiai: kokie jie yra ir kaip jie gaunami?”

  1. Įdomu, niekad nesusimąsčiau apie tuos atsitiktinius skaičius. Kažin, Lietuvoj yra tokių loterijų su spragomis? :) Akivaizdu, kad ne Tele loto, bet tarp tų nedidelių momentinių loterijų, gal visai tikėtina? Kilo noras atlikti eksperimentą. :D

  2. Neturiu duomenų, ar yra Lietuvoje tokių loterijų, bet manau, kad didesnės momentinės irgi tokių dalykų nenaudotų. :) Įranga generuot tikriems atsitiktiniams skaičiams šiuo metu kainuoja labai nedaug. :) Nors praeityje tokių dalykų buvo. Pamenu prieš kokius 8-10 metų buvo Utenos alaus loterija, galima būdavo po kamšteliu rast pinigų sumą ir ženklą – pvz. “+10 Lt” ir “-10 Lt”, jei turėdavai du kamštelius – galėdavai nueit iki terminalo ir atsiimt pinigus. Tai pamenu, kad nustatyt laimingą kamštelį būdavo įmanoma dviems būdais: ant kamštelio būdavo skaičiai, jeigu jie su žodžiu “Utena” eina lygiagrečiai – kamštelis nelaimingas, jeigu statmenai – laimingas, kitas būdas – pašviest kamštelį su ultravioletine lempa. :D Taip pat, kai kurie žinojo formulę (matyt kažkas iš “Utenos” darbuotojų paskleidė), į kurią įstačius tuos skaičius netgi buvo galima nustatyti, kokia suma slepiasi po kamšteliu.

    Momentinėse loterijose kai kuriose nujaučiu, kad yra kažkoks ryšys tarp “Čia netrinti” ir skaičių biliete (galbūt netgi “seed’as” pseudo-randomo?), tačiau problema, kad neišeina pamatyt, kas slepiasi po tuo užrašu “Čia netrinti”. :D

  3. Jei jau apie loterijas kalba eina pasidalinsiu prisiminimais kai senais laikais apie 2000metus(na reliatyviai seniai :D ) kaimynas gavo leaka kazkur koko kolos loterijos.Ten triukas buvo jei coca cola uzrasas.prilipes prie kairio krasto laimi dar buteli, jei ne sekmes kitasyk.Gyvate dar pamenu paime pinigu is manes uz triuka, 2lt ;D na kai po 9 metus buvom cia rimti pinigai ;D

  4. labai įdomiai ir suprantamai parašei, kaip tik pradėjom programuot univere dabar ir susidūrėm su random numbers statistikoj, pasiskaitai tokių dalykų ir motyvacijos daugiau atsiranda:)))))))))

  5. Šaunu, kad kažkam straipsnis pasirodė naudingas ir motyvuojantis. :) Sunkiai man sekasi tokius dalykus gerai išaiškint, tai labai malonu sulaukt tokio komentaro. Ačiū!

  6. ar galetum paskaičiuoti statistiskai galimus pvz Vikingu loto laimingus 6 skaičius? ar nors ta laiminga kur 3 mln. slepias :)

  7. Labas, Vilija. Tiesą sakant nelabai supratau Tavo klausimą, tačiau jeigu nori laimėjimo tikimybių, vienas blogeris yra padaręs tyrimą apie Vikingų loto: http://www.skaitykit.lt/naujas-vikingu-loto-paskaiciuokime-tikimybe-laimeti.htm

    Jis pasirašė programą, kuri atsitiktinai generuodavo bilietus ir iškritusius skaičius. Aišku, galima tą patį ir paskaičiuot matematikai pasinaudojus tikimybių teorija, bet greičiausiai rezultatai žymiai nesiskirtų nuo jo gautųjų.

    Tikiuosi kažkiek padėjau. :)

  8. Tekstas visai suprantamas buvusiam VGTU studentui :D
    Aciu uz straipsni!
    Visada knedejo suzinoti apie random funkcija.
    Tai kaip supratau PC pvz Exel naudoja tik pseudo random funkcija.

  9. Nejaugi Jūs tikit,kad lošimas sąžiningas-pažiūrėkit-kiek leidžiama išlošti-vidutiniškai iki 300,gal1000 Euro-vienas,kitas žmogus Lietuvoje. Lošimų nėra -prie šiuolaikinės lošimų (apgavikiškų) technologijos nieko nereiškia įvesti visos Lietuvos,o gal ir visų skndinavijos šalių lošiančius bilietus į galingą kompiuterį-kompiuteris momentaliai paskaičiuoja užprogramuotą optimalų variant-su minimaliais išlošimais ir maksimaliu pelnu . Taigi-kompiuteris išspjauna atsakymą-optimalūs skaičiai-o paskui juk nesunku per televiziją imituoti kažkokį lošimą ir parodyti-būk-tai išriedėjo tie skaičiai-juk cirke ne to dar būna. Taigi -žmonės gauna ubagiškas liekanas,o lošimų bendrovės susižęria milžiniškus pelnus. Nejaugi Jūs dar skaičiuojat kažkokias tikimybes-laikydami save labia protingais? Juk čia nėra jokių tikimybių,o yra tik cirko numeriai. Ir taip yra visose loterijose. Pačioje pradžioje buvo kažkas tikro-numerius traukė vaikai-bet ir jiems galima pakišti reikiamus numerius, nors…atrodė kažkaip sąžiningai. Tarp kitko -sporto lažybų bendrovės-irgi užsiima visokiom apgavystėm-dešimtys būdų,kuriuos išstudijavau.

  10. Idomi tema. Matematika ir aplamai technologijos yra nieko daugiau nei irankis. Zmogus tai stebuklas. Random number = 59810911.

Palikite komentarą