OqPoWah.com

Funkcija naključni C + +

Sredi ustvarjanja STL in nasilni vojni za standardno število jeziku C ++ programerjev so razvili lastno platformah razred knjižnica zagotavlja razvijalcem orodja za soočanje z vsakodnevnimi nalogami, kot so obdelava podatkov, algoritmi, in delo z datotekami in tako naprej. D. Ta knjižnica se imenuje Boost. Projekt je bil tako uspešen, da so zmogljivosti Boost sposojene in se prilegajo jezikovnemu standardu, začenši s C ++ 11. Eden od teh dodatkov je izboljšano delo z naključnimi številkami.

Pseudo-naključni generator

Funkcije rand () in srand () se nanašajo na raven šole in so primerne za pisanje preprostih programov. Slaba stran teh funkcij je ustvarjanje nezadostno dobro zaporedje psevdo-naključnih številk (slika zgoraj). Tudi možnosti enostavnih funkcij pri razvoju kompleksnih projektov niso dovolj.

Za rešitev problema so bili izumljeni generatorji naključnih števil (v nadaljevanju RNG). S svojim videzom se je znatno izboljšalo delo na ustvarjanju številnih vrst podatkov, tako psevdo kot resnično naključnih. Primer generacije resnično naključnih številk je hrup na spodnji sliki.

Resnično naključni generator

Generator pseudo-naključnih števil

Kocke kot simbol naključja

Tradicionalni algoritem za ustvarjanje MF je združeval algoritem za ustvarjanje nepredvidljivih bitov in njihovo pretvorbo v zaporedje številk. V naključni knjižnici C ++, ki je del programa Boost, sta ti dve mehanizmi razdeljeni. Zdaj generiranje naključnih števil in njihova distribucija (zaporedje) se pojavita ločeno. Uporaba distribucije je popolnoma logična. Ker naključna številka brez določenega konteksta ni smiselna in je težko uporabljati. Let`s napisati preprosto funkcijo, ki vrže kosti:

#include int roll_a_dice () {std :: default_random_engine e {} - // ustvariti randomness generatorstd :: uniform_int_distribution	d {1, 6} // ustvarite distribucijo z vrednostmi min in max vrne d (e) -}

Pogosta napaka tistih, ki preučujejo naključje, je prezreti ustvarjanje distribucije in se naravnost usmeriti k ustvarjanju naključnih številk na način, na katerega se uporabljajo. Na primer, upoštevajte zgoraj opisano funkcijo.

vrnitev 1 + e ()% 6-

Nekateri menijo, da je takšna uporaba sprejemljiva. C + + omogoča, da delate tako. Kljub temu pa avtorjem knjižnic Boost in C ++ 11 svetujemo, naj to ne storijo. V najboljšem primeru bo to le napačna koda, v najslabšem primeru pa bo delovni kodek, ki bo zelo težko ujeti napake. Uporaba distribucij zagotavlja, da programer dobi, kar pričakuje.

Generator in inicializacija semena

Stopnja razglasitve, opredelitve in ustvarjanja subjektov se pogosto obravnava kot nekaj, kar ne potrebuje posebne pozornosti. Toda premalo premišljena inicializacija generatorja naključnih števil lahko vpliva na njegovo pravilno delovanje.

std :: default_random_engine e1- // implicitno inicializacija vrednost umolchaniyustd :: default_random_engine e2 {} - // eksplicitno inicializacijo praviloma je vrednost

Prvi dve inicializaciji sta enakovredni. In večinoma se nanašajo na okus ali na standarde pisanja lepe kode. Toda naslednja inicializacija je radikalno drugačna.

std :: default_random_engine e3 {31255} - / / inicializacija z vrednostjo 31255

"31255" - to se imenuje seme (seme, vir) - število, na podlagi katerega generator ustvarja naključne številke. Ključna točka je, da bi s to inicializacijo vrsta semena morala biti enaka ali tip, s katerim deluje generator. Ta vrsta je dostopna z izgradnjo decltypepe (e ()), ali result_of ali typename.

Zakaj generator ustvari enaka zaporedja?

Ko se program izvaja večkrat, generator vedno ustvari isto zaporedje številk, če se njegova inicializacija ne spremeni, to pomeni, da se definicija generatorja zgodi enako od zagona do zagona programa. Po eni strani je ta samopriproževanje številk s pomočjo generatorja koristno, na primer pri odpravljanju napak. Po drugi strani pa je nezaželen in lahko povzroči težave.

V skladu s tem je treba vsakič, ko se program zažene, generator izogniti ponavljanju zaporedja številk. Samo za te namene lahko uporabite seme. Standardni način za inicializacijo GPRS-ja je, da ga pošljete kot vrednost semena (0) iz datoteke glave ctime. To pomeni, da bo generator inicializiran z vrednostjo, ki je enaka številu sekund, ki so pretekle od 1. januarja 00 00 00 minut 00 sekund, 1970 UTC.

Inicializacija GPRS z drugim generatorjem

Inicializacija časa morda ne bo zadostovala za reševanje številnih nalog. Potem je mogoče določiti GPRS prek drugega generatorja. Tukaj bi rad naredil odmik in se pogovoril o enem močnem orodju, ki vam omogoča ustvarjanje resnično naključnih številk.

Random_device - generator resnično naključnih števil

Naključne številke

Vsi generatorji pseudo-naključnega števila so deterministični. To pomeni, da imajo definicijo. Ali z drugimi besedami, prejem naključnih števil temelji na matematičnih algoritmih. Random_device je tudi nedeterminističen. Ustvarja številke na podlagi stohastičnih (naključnih s grško-grškim) procesom. Takšni procesi so lahko spremembe faze ali amplitude tokovnih nihanj, nihanj v molekularnih rešetkah, gibanja zračnih mase v ozračju itd.

Očitno ni, da vsak računalnik in vsak sistem lahko ima vgrajeno zmožnost, da bi dobili naključno število, ki temelji na stohastičnem procesu. Zato bi se morali zateči k uporabi naključnega dela samo, če je potrebno. Njegovo delo se lahko razlikuje od sistema do sistema, od računalnika do računalnika in morda celo nedostopno. Zato je pri uporabi generatorja resnično naključnih številk potrebno zagotoviti napake.

Uporaba random_device kot semena za RAND

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



V tem kodeksu ni nič novega. Istočasno se z vsakim zagonom GISCH inicializira z naključnimi vrednostmi, ki jih generira resnično naključno število rd.

Prav tako je treba omeniti, da se lahko inicializacijska vrednost generatorja kadar koli ponastavi:

e.seed (15027) // inicializiramo number.seed () - // inicializiramo s privzeto vrednostjo.seed (rd ()) - / / inicializiramo z drugim generatorjem

Splošno: generatorji in distribucije

Motor je objekt, ki vam omogoča, da ustvarite različne enodružljive številke.

Porazdelitev (distirbution) je objekt, ki pretvarja zaporedje številk, ki jih ustvari generator v distribuciji v skladu z določenim zakonom, na primer:

  • enotna;
  • Normalno - Gaussovo (normalno);
  • binomial in tako naprej.

Razmislite o generatorjih standardne knjižnice C ++.

  1. Dovolj je, da začetniki uporabljajo default_random_engine in pustijo izbiro generatorja knjižnici. Generator bo izbran na podlagi kombinacije dejavnikov, kot so zmogljivost, velikost, kakovost naključnosti.
  2. Za izkušene uporabnike knjižnica ponuja 9 prednastavljenih generatorjev. Zelo so različni glede na zmogljivost in velikost, hkrati pa je njihova kakovost dela podvržena resnim testom. generator imenuje Mersenne Twister motorji in primeri pogosto uporablja mt19937 (ustvarjanje 32-bitne številke) in mt19937_64 (ustvarjanja 64-bitnih števil). Generator je optimalna kombinacija hitrosti in naključnosti. Za večino težav, ki se pojavijo, bo dovolj.
  3. Za strokovnjake knjižnica ponuja nastavljive predloge generatorja, ki omogočajo ustvarjanje dodatnih tipov generatorjev.
Normalna porazdelitev

Razmislimo o ključnih vidikih porazdelitve. V standardnem jeziku jih je 20. V zgornjem primeru je bila v območju [a, b] za celo število uporabljena naključna porazdelitev naključne knjižnice C ++ - uniform_int_distribution. Za isto distribucijo lahko uporabimo tudi realne številke: uniformno_real_distribution z istimi parametri a in b od intervala generiranja števil. Poleg tega so vključene tudi meje intervala, to je [a, b]. Navedite vseh 20 distribucij in ponovite dokumentacijo C + + v članku, ni smiselno.

Treba je opozoriti, da ima vsaka distribucija svoj parameter. Za enakomerno porazdelitev je to interval od a do b. Za geometrijski parameter (geometric_distribution) je verjetnost uspeha p.

Večina porazdelitev je definirana kot predlogo razreda, za katero je parameter vrsta zaporednih vrednosti. Vendar nekatere distribucije ustvarijo samo zaporedja za int vrednosti ali samo prave vrednosti. Ali, na primer, Bernoulli zaporedje (bernoulli_distribution), ki zagotavlja vrednosti, kot je bool. Kot pri RNG lahko uporabnik knjižnice ustvari lastne distribucije in jih uporablja z vgrajenimi generatorji ali generatorji, ki jih bodo ustvarili.

Gama distribucija

Knjižnične zmogljivosti niso omejene na to. So veliko širše. Toda predložene informacije zadoščajo za uporabo in osnovno razumevanje generatorja naključnih števil v C ++.

Kratke informacije: naključno v slogu .Net

Okvir .Net ima tudi razred Random za ustvarjanje pseudo-naključnih števil. Poglejmo si primer generacije Random number With ++ / CLI.

Za tiste, ki delajo v Visual Studio in ne morejo razumeti, zakaj sistemski prostor sistema ni določen.

Če želite delati z. Netko, morate povezati CLR. To je bilo opravljeno v dveh sposobami.1) Ustvarjanje projekta ni okna konzole app, in s podporo CLR - Console aplikacija CLR (CLR Console Application) 0,2) Priključite podporo CLR v nastavitvah že ustvarili projekt: projekt lastnosti ( "projekt", in ne " storitev ") -> konfiguracija -> splošno -> privzete -> v spustnem polju" podpore za skupno runtime jezik (CLR) "izberite" CLR okolju Support (/ CLR) ".

#include "stdafx.h" #include // uporabo namespace Sistemske-int main (matrične ^ args) {Sistemska :: Random ^ RND1 = gcnew sistem :: Random () - // ustvarjanje RNG privzeto inicializiran trenutno vremenemstd :: cout << rnd1-> Naprej () << " n" - // vrne pozitivno celo število int upper = 50-std :: cout << rnd1-> naprej (zgornji) << " n" - // vrne pozitivno celo število, ki ni večje od višine a = -1000-int b = -500-std :: cout << rnd1-> Naprej (a, b) << " n" - // vrne celo število v obsegu [a, b] int semen = 13977-System :: Naključno ^ rnd2 = gcnew System :: Naključno (seme) - // inicializiraj RNG s številko seedstd :: cout << rnd2-> Naprej (500, 1000) << " n" - // vsakič, ko se program zažene, bo ustvarjena ista številka. std :: cout << std :: endl-return 0-}

V tem primeru se celotno delo opravi s funkcijo Random Next C ++ / CLI.

Omeniti velja, da je .net velika knjižnica z obsežnimi zmogljivostmi in uporablja svojo različico jezika, imenovano C ++ / CLI, iz Common Language Infrastructure. Na splošno je to razširitev C + + za .Net platformo.

Na koncu si oglejte nekaj primerov, da bi bolje razumeli delo z naključnimi številkami.

#include #include #include int main () {std :: mt19937 e1-e1.seed (čas (0)) - std :: cout << e1 () << std :: endl-std :: mt19937 e2 (čas (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 :: normal_distribution nd (5.0, 2.0) - // normalna porazdelitev s povprečno vrednostjo 5,0 in standardnim odstopanjem 2.0std :: cout << urd (e4) << "," << nd (e4) << std :: endl-std :: cout << std :: endl-system ("pavza") - vrnitev 0-}

Zaključek

Vse tehnologije in metode se nenehno razvijajo in izboljšujejo. Torej se je to zgodilo z mehanizmom za generiranje naključnih števil rand (), ki je zastarelo in ne izpolnjuje sodobnih zahtev. V STL obstaja naključna knjižnica v .Net Framework, razred Random za delo z naključnimi številkami. Od z uporabo rand Zavrniti je treba nove metode, saj ustrezajo modernim programskim paradigmam, stare standardne metode pa bodo izpeljane iz standarda.

Zdieľať na sociálnych sieťach:

Príbuzný