(N) Satunnaislukuja

Tavoite: Harjoittelen satunnaislukugeneraattorin käyttämistä.

Ohjeita: Hae ohjelmakoodipohja: templates/02/random_numbers/ -> student/02/random_numbers/.

Satunnaisluvuista

Kirjastosta random löytyy luokka default_random_engine, joka on yksi kirjaston tarjoamista satunnaislukugeneraattoreista. Kun kutsutaan satunnaislukugeneraattoriluokan rakentajaa (eli luodaan satunnaislukugeneraattoriolio), voidaan parametrina antaa nk. siemenluku. Siemenluku on ikään kuin lähtökohta satunnaislukujen arpomiselle.

Siemenluvun antamisen lisäksi täytyy myös kertoa, mitä jakaumaa halutaan käyttää. Kirjasto random tarjoaa tähän useita vaihtoehtoja, mutta tässä tapauksessa käytämme jakaumaa uniform_int_distribution. Jakaumalle täytyy lisäksi kertoa, miltä väliltä satunnaisluvut halutaan.

Esimerkiksi seuraavassa koodissa generoidaan viisi satunnaislukua väliltä [1, 100] siemenluvulla 42.

// luodaan satunnaislukugeneraattori siemenarvolla 42
default_random_engine gen(42);

// luodaan jakauma
uniform_int_distribution<int> distr(1, 100);

// arvotaan ja tulostetaan viisi satunnaislukua
cout << distr(gen) << endl;
cout << distr(gen) << endl;
cout << distr(gen) << endl;
cout << distr(gen) << endl;
cout << distr(gen) << endl;

Tässä käytetyn satunnaislukugeneraattorin generoimat satunnaisluvut ovat nk. pseudosatunnaislukuja. Tämä tarkoittaa, että samalla siemenarvolla generoituu aina sama sarja satunnaislukuja. Jos pidät siemenarvon koko ajan samana (esim. 42), niin edellä oleva koodi tuottaa aina samat viisi satunnaislukua. Mutta jos vaihdat siemenarvon, myös satunnaislukujen sarja muuttuu (koska niiden lähtöarvo muuttuu).

Pseudosatunnaisuudesta on se hyöty, että ohjelmaa testatessa pystyy toistamaan saman ohjelman suorituksen uudelleen, kun tietää, millä siemenluvulla satunnaislukugeneraattori oli alustettu ohjelman suorituksen alussa.

Jos siemenlukua ei anneta satunnaislukugeneraattorin luomisen yhteydessä, se voidaan asettaa myöhemmin kutsumalla funktiota seed:

// luodaan satunnaislukugeneraattori ilman siemenarvoa
default_random_engine gen;

// asetetaan satunnaislukugeneraattorille siemenarvo
gen.seed(42);

Myös yllä olevassa koodissa luodaan satunnaislukugeneraattori eli kutsutaan rakentajaa, vaikkakin ensimmäinen koodirivi näyttää ihan tavalliselta esittelyltä. (Luokkia, olioita ja rakentajia käsitellään myöhemmin tarkemmin.)

Tehtävänanto

Koodipohjassa on valmiina pääohjelma, jossa luetaan ala- ja ylärajat välille, jolta satunnaisluvut generoidaan. Lisäksi siinä tarkistetaan, että alaraja on aidosti pienempi kuin yläraja.

Tehtävänäsi on toteuttaa funktio produce_random_numbers, joka tuottaa satunnaislukuja annetulle välille, kunnes käyttäjä antaa lopetuskomennon q.

Ohjelman on tarkoitus toimia seuraavasti:

Enter a lower bound: 1
Enter an upper bound: 10
Enter a seed value: 1

Your drawn random number is 1
Press q to quit or any other key to continue: c

Your drawn random number is 2
Press q to quit or any other key to continue: c

Your drawn random number is 8
Press q to quit or any other key to continue: c

Your drawn random number is 5
Press q to quit or any other key to continue: c

Your drawn random number is 6
Press q to quit or any other key to continue: c

Your drawn random number is 3
Press q to quit or any other key to continue: c

Your drawn random number is 1
Press q to quit or any other key to continue: q

Vinkkejä tehtävän tekemiseen:

  • Käyttäjän antamat komennot (c ja q) kannattaa lukea operaattorilla >>, koska myös ala- ja ylärajat luetaan tällä operaattorilla. (Samassa ohjelmassa ei kannata lukea syötteitä sekä funktiolla getline että operaattorilla >>, ei ainakaan järjestyksessä: ensin >> ja sitten getline.)

  • Voit tietenkin kokeilla, mitä tapahtuu, jos käyttäisit komentojen lukemiseen funktiota getline. Operaattorin >> ja funktion getline erona on se, että edellinen jättää syötteen lopussa olevan rivinvaihtomerkin lukematta. Tämä lukematta jäänyt merkki pitää lukea pois syötevirrasta, jos halutaan myöhemmin käyttää getline-funktiota.

A+ esittää tässä kohdassa tehtävän palautuslomakkeen.