Funkcija Random C ++

Usred stvaranja STL i nasilnog rat za C ++ jezika standardnog broja programera razvili smo vlastiti cross-platforma klase knjižnica pruža razvojnim alatima za rješavanje svakodnevnih zadataka, kao što su obrada podataka, algoritmi i rad s datotekama i tako dalje. D. Ova biblioteka se zove poticaj. Projekt je toliko uspješan da se Boost sposobnosti posuđuju i uklapaju u jezični standard, počevši od C + + 11. Jedna od ovih dodataka je poboljšana rad s nasumičnim brojevima.

Pseudo-slučajni generator

Funkcije rand () i srand () odnose se na razinu škole i pogodne su za pisanje jednostavnih programa. Nedostatak tih funkcija je stvaranje nedovoljno dobrog slijeda pseudo-slučajnih brojeva (gore prikazana slika). Također, mogućnosti jednostavnih funkcija nisu dovoljne pri razvoju složenih projekata.

Da bi se riješio problem, generirani su generatori slučajnih brojeva (u daljnjem tekstu: RNG). S njihovim izgledom znatno je poboljšan rad na stvaranju mnogih vrsta podataka, i pseudo-i doista slučajnih. Primjer generacije doista slučajnih brojeva je buka na slici ispod.

Doista slučajni generator

Pseudo-slučajni generator broja

Kockanje kao simbol slučaja

Tradicionalni algoritam za stvaranje MF-a kombinirao je i algoritam za stvaranje nepredvidljivih bitova i pretvaranje ih u niz brojeva. U slučajnom C + + knjižnici, koja je dio Boost, ova dva mehanizma su podijeljena. Sada generacija slučajnih brojeva i njihovog stvaranja distribucija (slijed) odvija se zasebno. Upotreba distribucije je potpuno logična. Budući da slučajni broj bez određenog konteksta nema smisla i teško je koristiti. Napišimo jednostavnu funkciju koja baca kost:

#include int roll_a_dice () {std :: default_random_engine e {} - // stvara slučajnost generatorstd :: uniform_int_distribution	d {1, 6} // stvoriti distribuciju s vrijednostima min i max return d (e) -}

Česta pogreška onima koji studiraju slučajno je zanemariti stvaranje distribucije i izravno kreirati slučajne brojeve u načinu na koji su navikli. Na primjer, razmotrite gore opisanu funkciju.

povrat 1 + e ()% 6-

Neki smatraju takvu upotrebu kao prihvatljivu. C + + omogućuje vam da radite na taj način. Ipak, kreatori knjižnice Boost i C ++ 11 standarda snažno se savjetuju da to ne čine. U najboljem slučaju, to će biti samo loš kod, a najgore će to biti radni kod koji čini pogreške koje je teško uhvatiti. Korištenje distribucija osigurava da programer dobiva ono što očekuje.

Inicijalizacija generatora i sjemena

Faza deklariranja, definiranja i stvaranja entiteta često se promatra kao nešto što ne treba posebnu pažnju. Ali ne dovoljno zamišljena inicijalizacija generatora slučajnih brojeva može utjecati na pravilan rad.

std :: default_random_engine e1- // implicitna inicijalizacija by defaultstd :: default_random_engine e2 {} - // eksplicitna inicijalizacija s zadanom vrijednošću

Prve dvije inicijalizacije su ekvivalentne. I za najveći dio se odnose na okus ili standarde pisanja lijepog koda. Ali sljedeća inicijalizacija je radikalno drugačija.

std :: default_random_engine e3 {31255} - // inicijalizacija s vrijednošću 31255

"31255" - to se naziva sjeme (sjeme, izvor) - broj na temelju kojeg generator stvara slučajne brojeve. Ovdje je ključna točka da s ovom inicijalizacijom, vrsta sjemena mora biti ista ili tipa s kojim generator djeluje. Ova je vrsta dostupna izgradnjom decltype (e ()) ili result_of ili typename.

Zašto generator stvara iste sekvence?

Kada se program pokrene nekoliko puta, generator uvijek stvara isti redoslijed brojeva, ako njegova inicijalizacija ne mijenja, tj. Definicija generatora se događa na isti način od početka do pokretanja programa. S jedne strane, to samoproizvodnja brojeva od strane generatora je korisna, na primjer, kada je ispravljanje pogrešaka. S druge strane - nepoželjno je i može stvoriti probleme.

Prema tome, kako bi se izbjeglo ponavljanje redoslijeda brojeva, generator mora biti inicijaliziran s različitim vrijednostima svaki put kada se program pokrene. Samo za ove namjene možete koristiti sjeme. Standardni način za inicijalizaciju GPRS-a jest poslati ga kao vrijeme sjemena vrijednosti (0) iz datoteke cesta zaglavlja. To znači da će generator biti inicijaliziran s vrijednošću koja je jednaka broju sekundi proteklo od 1. siječnja 00 00 00 00 00, 1970 UTC.

Inicijalizacija GPRS-a s drugim generatorom

Inicijalizacija vremena možda neće biti dovoljna za rješavanje brojnih zadataka. Zatim je moguće odrediti GPRS preko drugog generatora. Ovdje bih želio napraviti digresiju i razgovarati o jednom moćnom alatu koji vam omogućuje stvaranje doista slučajnih brojeva.

Random_device - generator istinski slučajnih brojeva

Nasumični brojevi

Svi generatori pseudo-slučajnih brojeva su deterministički. To jest, oni imaju definiciju. Ili drugim riječima, primanje slučajnih brojeva temelji se na matematičkim algoritmima. Random_device je također neodređen. On stvara brojeve na temelju stohastičkih (slučajnih s grčko-grčkim) procesima. Takvi procesi mogu biti promjene u fazi ili amplitudi strujnih oscilacija, oscilacija u molekularnim rešetkama, gibanje zračnih masa u atmosferi itd.

Očito, ne svako računalo i svaki sustav može imati ugrađenu sposobnost da dobije slučajni broj na temelju stohastičkog procesa. Stoga biste trebali koristiti samo random_device ako je potrebno. Njegov rad može se razlikovati od sustava do sustava, od računala do računala, a možda čak i nedostupan. Stoga, kada koristite generator doista slučajnih brojeva, potrebno je osigurati rukovanje pogreškama.

Koristeći random_device kao sjeme za RAND

std :: random_device rd {} - std :: default_random_engine e {rd ()} -


U ovom kodu nema ništa iznimno novog. Istodobno, sa svakim pokretanjem, GISCH se inicijalizira sa slučajnim vrijednostima generiranim od strane generatora doista slučajnih brojeva.

Također je vrijedno napomenuti da se vrijednost inicijalizacije generatora može resetirati u bilo kojem trenutku:

e.seed (15027) // inicijalizirajte number.seed () - // inicijalizirajte s zadanom vrijednošću.seed (rd ()) - // inicijalizirajte s drugim generatorom

Općenito: generatori i distribucije

Motor je objekt koji vam omogućuje stvaranje različitih brojeva koji se mogu opremiti.

Distribucija (distirbution) je objekt koji pretvara redoslijed brojeva generiranih od generatora u distribucije prema određenom zakonu, na primjer:

  • ujednačena (ujednačena);
  • Normalno - Gauss (normalno);
  • binomi, i tako dalje.

Razmotrite generatore standardne C + + knjižnice.

  1. Dovoljno je za početnike da koriste default_random_engine, ostavljajući izbor generatora knjižnici. Generator će biti izabran na temelju kombinacije čimbenika kao što su izvedba, veličina, kvaliteta slučajnosti.
  2. Za iskusne korisnike, knjižnica pruža 9 unaprijed generiranih generatora. Vrlo se razlikuju u izvedbi i veličini, ali istovremeno njihova kvaliteta rada podložna je ozbiljnim testovima. Često se koristi generator zvani Mersenne twister motori i njeni instanci mt19937 (stvaranje 32-bitnih brojeva) i mt19937_64 (stvaranje 64-bitnih brojeva). Generator je optimalna kombinacija brzine i slučajnosti. Za većinu problema koji će se pojaviti bit će dovoljno.
  3. Za stručnjake, knjižnica pruža predloške prilagodljivih generatora koji omogućuju stvaranje dodatnih vrsta generatora.
Uobičajena distribucija

Razmotrimo ključne aspekte distribucija. Na standardnom jeziku postoji 20 od njih. U gore navedenom primjeru slučajna distribucija slučajne C + + knjižnice upotrijebljena je u rasponu [a, b] za cijele brojeve - uniform_int_distribution. Ista raspodjela može se koristiti za pravi brojevi: uniformna realna raspodjela sa istim parametrima a i b intervala generiranja brojeva. Štoviše, uključene su granice intervala, tj. [A, b]. Nabrojite sve 20 distribucija i ponovite dokumentaciju C + + u članku nema smisla.

Treba napomenuti da svaka distribucija ima svoj vlastiti skup parametara. Za ravnomjerno raspoređivanje, ovo je interval od a do b. A za geometrijski (geometrijski_distribucija) parametar, vjerojatnost uspjeha je p.

Većina distribucija definira se kao predložak klase, za koji je parametar vrsta slijednih vrijednosti. Međutim, neke distribucije stvaraju samo sekvence za vrijednosti int ili samo stvarne vrijednosti. Ili, na primjer, Bernoullijeva sekvenca (bernoulli_distribution) koja daje vrijednosti kao što je bool. Kao i kod RNG, korisnik knjižnice može stvoriti vlastite distribucije i koristiti ih s ugrađenim generatorima ili s generatorima koji će stvoriti.

Distribucija gamme

Mogućnosti knjižnice nisu ograničene na ovo. Oni su mnogo širi. No, pružene informacije su dovoljne za korištenje i osnovno razumijevanje generatora slučajnih brojeva u C + +.

Kratke informacije: slučajno u stilu .Net

.Net okvir također ima Random klasu za stvaranje pseudo-slučajnih brojeva. Razmotrimo primjer generiranja slučajnog broja s ++ / CLI.

Za one koji rade u Visual Studiou i ne razumiju zašto sustavni prostor sustava nije definiran.

Da biste radili s .net, morate spojiti CLR. To je učinjeno na dva načina: 1) Stvaranje projekta nije aplikacija za Windows konzolu, ali s CLR podrškom - CLR aplikacija konzole 2) Povezivanje CLR podrške u postavkama već stvorenog projekta: svojstva projekta (kartica projekta, a ne " servis ") -> konfiguracija -> općenito -> zadane vrijednosti -> odaberite" CLR support (/ clr) "u padajućem popisu" podrška za zajednički jezik (CLR) ".

#include "stdafx.h" #include // koristeći naziv prostor System-int glavni (array ^ args) {System :: Random ^ rnd1 = gcnew System :: Random () - // stvoriti RNG, po defaultu je inicijaliziran s trenutnim vremenom std :: cout << rnd1-> Dalje () << " n" - // vraća pozitivan cijeli broj int upper = 50-std :: cout << rnd1-> Sljedeća (gornja) << n "- // vraća pozitivni cijeli broj koji nije veći od gornjeg a = -1000-int b = -500-std :: cout << rnd1-> Dalje (a, b) << " N" - // vraća cijeli broj u rasponu [a, b] int sjemena = 13.977-System :: Random ^ rnd2 = gcnew sustav :: Random (sjemena) - // inicijalizacija RNG broj seedstd :: cout << rnd2-> Dalje (500, 1000) << " n" - // svaki put kada se program pokrene, kreirat će se isti broj std :: cout << std :: endl-return 0-}

U ovom slučaju, sav posao obavlja se zahvaljujući funkciji Random Next C ++ / CLI.

Vrijedno je spomenuti da je .net velika knjižnica s velikim mogućnostima i koristi vlastitu verziju jezika, nazvanu C + + / CLI iz Common Language Infrastructure. Općenito, ovo je C ++ nastavak za .Net platformu.

Razmislite na kraju nekoliko primjera kako biste bolje razumjeli rad s nasumičnim brojevima.

#include #include #include int glavni () {std :: mt19937 e1-e1.seed (vrijeme (0)) - std :: cout << e1 () << std :: endl-std :: mt19937 e2 (vrijeme (0)) - std :: mt19937 e3 {} - std :: uniform_int_distribution uid1 (5, 10), uid2 (1,6) -std :: cout << uid1 (e2) << „” << uid2 (e3) << std :: endl-std :: default_random_engine e4 {} - std :: uniformno_real_distribution urd (0.5, 1.2) -std :: normalna distribucija nd (5.0, 2.0) - // normalna distribucija s prosječnom vrijednošću 5.0 i standardnom devijacijom 2.0std :: cout << urd (e4) << „” << nd (e4) << std :: endl-std :: cout << std :: endl-system ("pauza") - povratak 0-}

zaključak

Svaka tehnologija i metode stalno se razvijaju i poboljšavaju. Tako se to dogodilo s mehanizmom generiranja slučajnih brojeva rand (), koji je zastario i koji je prestao zadovoljiti moderne zahtjeve. U STL-u postoji slučajna knjižnica, u .Net okviru, Random klasu za rad s slučajnim brojevima. Iz koristeći rand Potrebno je odbiti u korist novih metoda, budući da odgovaraju modernim programskim paradigmama, a stare se metode izvode iz standarda.

Dijelite na društvenim mrežama:

Povezan
Što je Ruby? Programski jezik "Ruby"Što je Ruby? Programski jezik "Ruby"
Analiza korelacije kao alat za ekonomska i statistička istraživanjaAnaliza korelacije kao alat za ekonomska i statistička istraživanja
Korelacijska regresijska analiza i njegova široka primjena u gospodarstvuKorelacijska regresijska analiza i njegova široka primjena u gospodarstvu
Procesor I7 920: specifikacije, opis i recenzijeProcesor I7 920: specifikacije, opis i recenzije
Pretvorba vrste. Okrugli i Trunc funkcioniraju u PascaluPretvorba vrste. Okrugli i Trunc funkcioniraju u Pascalu
Što funkcionira SQL CONCAT?Što funkcionira SQL CONCAT?
Što funkcionira PHP mikrotime funkcija?Što funkcionira PHP mikrotime funkcija?
PHP: regularni izrazi, funkcija preg match allPHP: regularni izrazi, funkcija preg match all
Opis: generator brojnih lutrijaOpis: generator brojnih lutrija
Standardni postupci i funkcije u PascaluStandardni postupci i funkcije u Pascalu
» » Funkcija Random C ++
LiveInternet