Funkce Random C ++
Ve středu vytváření STL a násilnou válku pro C ++ jazyka standardní počet programátorů vyvinuli naši knihovnu vlastní cross-platform třída poskytuje vývojářům nástroje, které se zabývají každodenní úkoly, jako je zpracování dat, algoritmy a práci se soubory a tak dále. D. Tato knihovna se nazývá basů. Projekt je tak úspěšný, že funkce Boost jsou vypůjčeny a zapadají do jazykového standardu od C ++ 11. Jedním z těchto přírůstků je vylepšená práce s náhodnými čísly.
Obsah
- Generátor pseudonáhodných čísel
- Inicializace generátoru a semen
- Proč generátor vytváří stejné sekvence?
- Inicializace gprs s jiným generátorem
- Random_device - generátor skutečně náhodných čísel
- Použití random_device jako osiva pro rand
- Obecně: generátory a distribuce
- Stručné informace: náhodné ve stylu .net
- Závěr
Funkce rand () a srand () odkazují na úroveň školy a jsou vhodné pro psaní jednoduchých programů. Nevýhodou těchto funkcí je generování nedostatečně dobré sekvence pseudonáhodných čísel (obrázek výše). Také možnosti jednoduchých funkcí nestačí při vyvíjení komplexních projektů.
Pro vyřešení problému byly vynalezeny generátory náhodných čísel (dále jen "RNG"). S jejich vzhledu se práce na generování mnoha druhů dat, jak pseudo-tak opravdu náhodných, byla značně zlepšena. Příkladem generace skutečně náhodných čísel je šum na obrázku níže.
Generátor pseudonáhodných čísel
Tradiční algoritmus pro vytváření MF kombinoval jak algoritmus pro vytváření nepředvídatelných bitů, tak i konverzi do řady čísel. V náhodném C ++ knihovně, která je součástí Boost, jsou tyto dva mechanismy rozděleny. Nyní generace náhodných čísel a jejich vytvoření distribuce (sekvence) dochází odděleně. Použití distribuce je zcela logické. Protože náhodné číslo bez určitého kontextu nemá smysl a je těžké ho použít. Napište jednoduchou funkci, která hodí kost:
#include int role_a_dice () {std :: default_random_engine e {} - // vytvořit randomness generatorstd :: uniform_int_distribution d {1, 6} // vytvoří distribuci s hodnotami min a max vrátí d (e) -}
Častou chybou pro ty, kteří studují náhodně, je ignorovat vytvoření distribuce a jít přímo do vytváření náhodných čísel ve způsobu, jakým jsou zvyklí. Zvažte například funkci popsanou výše.
návrat 1 + e ()% 6-
Někteří považují toto použití za přijatelné. C ++ vám umožní pracovat tímto způsobem. Tvůrci knihovny Boost a standardů C ++ 11 však důrazně doporučují, aby tak neučinili. V nejlepším případě to bude jen špatně vypadající kód, a v nejhorším případě to bude fungující kód, který dělá chyby, které jsou velmi obtížné chytit. Použití distribucí zajišťuje, že programátor dostane to, co očekává.
Inicializace generátoru a semen
Fáze deklarování, definování a vytváření entit je často považována za něco, co nepotřebuje zvláštní pozornost. Ale dostatečně promyšlená inicializace generátoru náhodných čísel může ovlivnit jeho správné fungování.
std :: default_random_engine e1- // implicitní inicializace defaultstd :: default_random_engine e2 {} - // explicitní inicializace s výchozí hodnotou
První dvě inicializace jsou ekvivalentní. A z větší části se vztahují k chuti nebo ke standardům psaní krásného kódu. Následující inicializace je však radikálně odlišná.
std :: default_random_engine e3 {31255} - // inicializace s hodnotou 31255
"31255" - toto se nazývá semeno (semeno, zdroj) - číslo, na jehož základě generátor vytváří náhodné číslice. Klíčovým bodem je, že při této inicializaci by měl být typ osiva stejný nebo typ, se kterým generátor pracuje. Tento typ je přístupný konstrukcí typu dectype (e ()), nebo result_of nebo název_paměti.
Proč generátor vytváří stejné sekvence?
Pokud je program spuštěn několikrát, generátor vždy vytvoří stejnou sekvenci čísel, pokud se jeho inicializace nezmění, to znamená, že definice generátoru nastane stejným způsobem od spuštění programu. Na jedné straně je tato samoreprodukce čísel generátorem užitečná, například při ladění. A na druhé straně - je nežádoucí a může způsobit problémy.
Proto, aby se zabránilo opakování sekvence čísel, generátor musí být inicializován s různými hodnotami při každém spuštění programu. Jen pro tyto účely můžete použít osivo. Standardní způsob inicializace GPRS je poslat jako časový údaj (0) ze souboru záhlaví ctime. To znamená, že generátor bude inicializován hodnotou, která se rovná počtu sekund, který uplynul od 1. ledna 00 00 00 minut 00 sekund, 1970 UTC.
Inicializace GPRS s jiným generátorem
Inicializace času nemusí být dostatečná k vyřešení několika úkolů. Pak je možné určit GPRS přes jiný generátor. Zde bych chtěl udělat odbočku a mluvit o jednom mocném nástroji, který vám umožní vytvořit opravdu náhodné čísla.
Random_device - generátor skutečně náhodných čísel
Všechny generátory pseudonáhodných čísel jsou deterministické. To znamená, že mají definici. Jinými slovy, příjem náhodných čísel je založen na matematických algoritmech. Random_device je také nedeterministická. Vytváří čísla na základě stochastických (náhodných s řecko-řeckými) procesy. Takovými procesy mohou být změny ve fázi nebo amplitudě proudových kmitů, oscilace v molekulárních mřížích, pohyb vzdušných hmot v atmosféře apod.
Je zřejmé, že ne každý počítač a každý systém může mít vestavěnou schopnost získat náhodné číslo založené na stochastickém procesu. Proto byste se měli uchýlit k použití náhodného řešení pouze v případě potřeby. Jeho práce se může lišit od systému po systém, od počítače po počítač a může být dokonce nepřístupná. Při použití generátoru skutečně náhodných čísel je proto nutné zajistit zpracování chyb.
Použití random_device jako osiva pro RAND
std :: random_device rd {} - std :: default_random_engine e {rd ()} -
V tomto kódu není nic nového. Současně se při každém spuštění GISCH inicializuje náhodnými hodnotami generovanými generátorem skutečně náhodných čísel rd.
Je také třeba poznamenat, že inicializační hodnota generátoru může být kdykoli vynulována:
e.seed (15027) // inicializovat number.seed () - // inicializovat s výchozím value.seed (rd ()) - // inicializovat s jiným generátorem
Obecně: generátory a distribuce
Motor je objekt, který vám umožňuje vytvářet různá ekvivalentní čísla.
Distribuce (distirbution) je objekt, který konvertuje sekvenci čísel vytvořených generátorem do distribucí podle určitého zákona, například:
- jednotná;
- Normální - Gaussova (normální);
- binomiální a tak dále.
Zvažte generátory standardní knihovny C ++.
- Pro začátečníky stačí použít default_random_engine a nechá volbu generátoru do knihovny. Generátor bude vybrán na základě kombinace faktorů, jako je výkon, velikost, kvalita náhodnosti.
- Pro zkušené uživatele knihovna poskytuje 9 přednastavených generátorů. Jsou velmi rozdílné ve výkonu a velikosti, ale zároveň je jejich kvalita práce předmětem seriózních testů. generátor tzv Mersenne Twister motory a instance často používán mt19937 (Vytvoření 32-bitové číslo) a mt19937_64 (vytvoření 64-bitová celá čísla). Generátor je optimální kombinace rychlosti a náhodnosti. U většiny problémů, které vzniknou, bude stačit.
- Pro odborníky knihovna poskytuje konfigurovatelné generátorové šablony, které umožňují vytváření dalších typů generátorů.
Zvažme klíčové aspekty distribucí. Ve standardním jazyce je 20 z nich. Ve výše uvedeném příkladu byla použita náhodná distribuce náhodného C ++ knihovny v rozmezí [a, b] pro celá čísla - uniformní_roznášení. Stejná distribuce může být použita pro reálná čísla: rovnoměrné distribuce_realismu se stejnými parametry a a b intervalu generování čísel. Kromě toho jsou zahrnuty hranice intervalu, tj. [A, b]. Vyčíslit všech 20 distribucí a opakovat dokumentaci C ++ v článku nemá smysl.
Je třeba poznamenat, že každé rozdělení má vlastní sadu parametrů. Pro rovnoměrné rozložení je to interval od a do b. A pro geometrický (geometric_distribution) parametr, pravděpodobnost úspěchu je p.
Většina distribucí je definována jako šablona třídy, pro kterou je parametrem typ hodnot sekvence. Některé distribuce však vytvářejí pouze sekvence pro hodnoty int nebo pouze reálné hodnoty. Nebo například sekvence Bernoulli (bernoulli_distribution), která poskytuje hodnoty jako bool. Stejně jako u RNG může uživatel knihovny vytvářet vlastní distribuce a používat je s vestavěnými generátory nebo generátory, které vytvoří.
Možnosti knihovny nejsou omezeny. Jsou mnohem širší. Ale poskytnuté informace stačí k použití a základnímu pochopení generátoru náhodných čísel v jazyce C ++.
Stručné informace: Náhodné ve stylu .Net
Rámec .Net má také třídu Random pro vytváření pseudonáhodných čísel. Uvažujme o příkladu generování Náhodných čísel S ++ / CLI.
Pro ty, kteří pracují v aplikaci Visual Studio a nemohou pochopit, proč není jmenný prostor systému definován.
Chcete-li pracovat s .net, musíte připojit CLR. To se provádí ve dvou sposobami.1) Vytvoření projektu není okna konzole aplikace, a za podpory CLR - Console aplikace CLR (CLR Console Application) .2) Připojte podporu CLR v nastavení již vytvořili projekt: Vlastnosti projektu (dále jen „projekt“, a nikoli " ) -> konfigurace -> obecné -> výchozí hodnoty -> v rozbalovacím seznamu "Podpora běžné jazykové runtime (CLR)" vyberte "Podpora CLR (/ clr)".
#include "stdafx.h" #include // using namespace System-int hlavní (Array ^ args) {System :: Náhodné ^ RND1 = gcnew System :: Random () - // tvorba RNG výchozí inicializován aktuální vremenemstd :: cout << rnd1-> Další () << " n" - // vrátí kladné celé číslo int horní = 50-std :: cout << rnd1-> Next (horní) << " n" - // vrátí kladné celé číslo ne větší než upperint a = -1000- int b = -500-std :: cout << rnd1-> Další (a, b) << " N" - // vrací celé číslo v rozmezí [a, b] int semeno = 13977-System :: Náhodné ^ RND2 = gcnew System :: Random (semena) - // inicializovat RNG číslo seedstd :: cout << rnd2-> Další (500, 1000) << " n" - // při každém spuštění programu se vytvoří stejné číslo std :: cout << std :: endl-return 0-}
V tomto případě se veškerá práce provádí díky funkci Random Next C ++ / CLI.
Za zmínku stojí, že .net je rozsáhlá knihovna s rozsáhlými možnostmi a používá svou vlastní verzi jazyka C ++ / CLI z Common Language Infrastructure. Obecně jde o rozšíření C ++ pro platformu .Net.
Vezměte na závěr pár příkladů, abyste lépe porozuměli práci s náhodnými čísly.
#include #include #include int hlavní () {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 :: uniform_real_distribution urd (0.5, 1.2) -std :: normální_distribuce nd (5.0, 2.0) - // normální distribuce s průměrnou hodnotou 5.0 a standardní odchylkou 2.0std :: cout << urd (e4) << "," << nd (e4) << std :: endl-std :: cout << std :: endl-system ("pauza") - návrat 0-}
Závěr
Jakákoli technologie a metody se neustále vyvíjejí a zlepšují. Tak se to stalo s mechanismem generování náhodných čísel rand (), který je zastaralý a přestal splňovat moderní požadavky. V STL existuje náhodná knihovna v .Net Framework, náhodná třída pro práci s náhodnými čísly. Z pomocí řádku Je nutné odmítnout ve prospěch nových metod, protože odpovídají moderním programovým paradigmům a ze standardů budou odvozeny staré metody.
- JQuery: připojení k webové stránce
- Zaokrouhlovací čísla v WEB programování
- Co je to náhoda? Vítězství osudu
- Náhodný - co to je?
- Rand - co to je a co jí?
- Procesor Intel Core i7: popis, specifikace, modely
- Co dělá funkce SQL CONCAT?
- Matematika z jazyka jаvascript
- PHP: regulární výrazy, funkční předpřipravit všechny
- Teorie čísel: teorie a praxe
- Distribuční funkce náhodné proměnné. Jak najít distribuční funkci náhodné proměnné
- Použití metody replace ()
- Příklad jQuery. Jednoduché příklady skriptů na jQuery
- Standardní knihovny C ++
- Formátovací čísla: funkce PHP number_format ()
- Použití funkce PHP náhodné
- Kontrola existence souboru PHP file_exists
- Numerická sekvence: koncept, vlastnosti, metody přiřazení
- Jaká je metoda Monte Carlo?
- Strukturovaný typ - jednorozměrné pole
- Zaokrouhlování v aplikaci Excel je snadné!