Sdílet prostřednictvím


<random>

Definuje zařízení pro generování náhodných čísel, což umožňuje vytváření jednotně distribuovaných náhodných čísel.

Požadavky

Hlavička: <random>

Namespace: std

Poznámka:

Knihovna <random> používá příkaz #include <initializer_list>.

Shrnutí

Generátor náhodných čísel je objekt, který vytváří sekvenci pseudonáhodných hodnot. Generátor, který vytváří hodnoty, které jsou jednotně distribuovány v zadaném rozsahu, je Uniform Random Number Generator (URNG). Šablona třídy navržená tak, aby fungovala jako URNG, se označuje jako modul , pokud má tato třída určité společné vlastnosti, které jsou popsány dále v tomto článku. Urng může být (a obvykle je) v kombinaci s rozdělením předáním URING jako argumentu rozdělení operator() k vytvoření hodnot distribuovaných způsobem, který je definován rozdělením.

Tyto odkazy přeskočí na hlavní části tohoto článku:

Rychlé tipy

Tady je několik tipů, které byste při používání <random>měli mít na paměti:

  • Pro většinu účelů vytvářejí skupiny URNG nezpracované bity, které musí být tvarovány rozděleními. (Výjimkou je std::shuffle() to, že používá přímo urng.)

  • Jednu instanci URING nebo distribuce nelze bezpečně volat současně, protože spuštění urng nebo distribuce je operace úpravy. Další informace naleznete v tématu Zabezpečení vlákna ve standardní knihovně jazyka C++.

  • Předdefinované typy několika modulů jsou k dispozici. To je upřednostňovaný způsob, jak vytvořit URNG, pokud se používá motor.

  • Nejužitečnější párování pro většinu aplikací je mt19937 modul s uniform_int_distribution, jak je znázorněno v příkladu kódu dále v tomto článku.

V záhlaví si můžete vybrat <random> z mnoha možností a každá z nich je vhodnější než zastaralá funkce rand()modulu runtime jazyka C . Informace o tom, co je špatně rand() a jak <random> tyto nedostatky řeší, najdete v tomto videu.

Příklady

Následující příklad kódu ukazuje, jak vygenerovat některá náhodná čísla v tomto případě pět z nich pomocí generátoru vytvořeného s ne deterministickými počátečními čísly.

#include <random>
#include <iostream>

using namespace std;

int main()
{
    random_device rd;   // non-deterministic generator
    mt19937 gen(rd());  // to seed mersenne twister.
                        // replace the call to rd() with a
                        // constant value to get repeatable
                        // results.

    for (int i = 0; i < 5; ++i) {
        cout << gen() << " "; // print the raw output of the generator.
    }
    cout << endl;
}
2430338871 3531691818 2723770500 3252414483 3632920437

I když se jedná o vysoce kvalitní náhodná čísla a liší se při každém spuštění tohoto programu, nemusí být nutně v užitečném rozsahu. K řízení rozsahu použijte jednotné rozdělení, jak je znázorněno v následujícím kódu:

#include <random>
#include <iostream>

using namespace std;

int main()
{
    random_device rd;   // non-deterministic generator
    mt19937 gen(rd());  // to seed mersenne twister.
    uniform_int_distribution<> dist(1,6); // distribute results between 1 and 6 inclusive.

    for (int i = 0; i < 5; ++i) {
        cout << dist(gen) << " "; // pass the generator to the distribution.
    }
    cout << endl;
}
5 1 6 1 2

Následující příklad kódu ukazuje realističtější sadu případů použití s jednotně distribuovanými generátory náhodných čísel prohazující obsah vektoru a pole.

// cl.exe /EHsc /nologo /W4 /MTd
#include <algorithm>
#include <array>
#include <iostream>
#include <random>
#include <string>
#include <vector>
#include <functional> // ref()

using namespace std;

template <typename C> void print(const C& c) {
    for (const auto& e : c) {
        cout << e << " ";
    }

    cout << endl;
}

template <class URNG>
void test(URNG& urng) {

    // Uniform distribution used with a vector
    // Distribution is [-5, 5] inclusive
    uniform_int_distribution<int> dist(-5, 5);
    vector<int> v;

    for (int i = 0; i < 20; ++i) {
        v.push_back(dist(urng));
    }

    cout << "Randomized vector: ";
    print(v);

    // Shuffle an array
    // (Notice that shuffle() takes a URNG, not a distribution)
    array<string, 26> arr = { { "H", "He", "Li", "Be", "B", "C", "N", "O", "F",
        "Ne", "Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar", "K", "Ca", "Sc",
        "Ti", "V", "Cr", "Mn", "Fe" } };

    shuffle(arr.begin(), arr.end(), urng);

    cout << "Randomized array: ";
    print(arr);
    cout << "--" << endl;
}

int main()
{
    // First run: non-seedable, non-deterministic URNG random_device
    // Slower but crypto-secure and non-repeatable.
    random_device rd;
    cout << "Using random_device URNG:" << endl;
    test(rd);

    // Second run: simple integer seed, repeatable results
    cout << "Using constant-seed mersenne twister URNG:" << endl;
    mt19937 engine1(12345);
    test(engine1);

    // Third run: random_device as a seed, different each run
    // (Desirable for most purposes)
    cout << "Using non-deterministic-seed mersenne twister URNG:" << endl;
    mt19937 engine2(rd());
    test(engine2);

    // Fourth run: "warm-up" sequence as a seed, different each run
    // (Advanced uses, allows more than 32 bits of randomness)
    cout << "Using non-deterministic-seed \"warm-up\" sequence mersenne twister URNG:" << endl;
    array<unsigned int, mt19937::state_size> seed_data;
    generate_n(seed_data.begin(), seed_data.size(), ref(rd));
    seed_seq seq(begin(seed_data), end(seed_data));
    mt19937 engine3(seq);
    test(engine3);
}
Using random_device URNG:
Randomized vector: 5 -4 2 3 0 5 -2 0 4 2 -1 2 -4 -3 1 4 4 1 2 -2
Randomized array: O Li V K C Ti N Mg Ne Sc Cl B Cr Mn Ca Al F P Na Be Si Ar Fe S He H
--
Using constant-seed mersenne twister URNG:
Randomized vector: 3 -1 -5 0 0 5 3 -4 -3 -4 1 -3 0 -3 -2 -4 5 1 -1 -1
Randomized array: Al O Ne Si Na Be C N Cr Mn H V F Sc Mg Fe K Ca S Ti B P Ar Cl Li He
--
Using non-deterministic-seed mersenne twister URNG:
Randomized vector: 5 -4 0 2 1 -2 4 4 -4 0 0 4 -5 4 -5 -1 -3 0 0 3
Randomized array: Si Fe Al Ar Na P B Sc H F Mg Li C Ti He N Mn Be O Ca Cr V K Ne Cl S
--
Using non-deterministic-seed "warm-up" sequence mersenne twister URNG:
Randomized vector: -1 3 -2 4 1 3 0 -5 5 -5 0 0 5 0 -3 3 -4 2 5 0
Randomized array: Si C Sc H Na O S Cr K Li Al Ti Cl B Mn He Fe Ne Be Ar V P Ca N Mg F
--

Tento kód ukazuje dvě různá náhodná rozdělení – randomizace vektoru celých čísel a náhodné prohazování pole indexovaných dat – pomocí funkce testovací šablony. První volání testovací funkce používá kryptograficky bezpečné, ne deterministické, nepůseditelné, neopakovatelné URNG random_device. Druhé testovací spuštění se používá mersenne_twister_engine jako URNG s deterministickým 32bitovým počátečním počátečním znakem, což znamená, že výsledky se dají opakovat. Třetí testovací běh semen mersenne_twister_engine s 32bitovým ne deterministickým výsledkem .random_device Čtvrtý testovací běh se na to rozšiřuje pomocí počáteční sekvence naplněné random_device výsledky, která účinně dává více než 32bitový ne deterministický náhodnost (ale stále není kryptograficky zabezpečená). Další informace najdete tady.

Zařazení do kategorií

Generátory jednotných náhodných čísel

Skupiny URNG se často popisují z hlediska těchto vlastností:

  1. Délka období: Kolik iterací trvá opakování posloupnosti vygenerovaných čísel. Čím déle, tím lépe.

  2. Výkon: Jak rychle se dají generovat čísla a kolik paměti zabere. Čím menší, tím lépe.

  3. Kvalita: Jak blízko ke skutečným náhodným číslům je vygenerovaná sekvence. Tomu se často říká náhodnost.

Následující části uvádějí generátory jednotných náhodných čísel (URNG) uvedené v <random> hlavičce.

Ne deterministický generátor

random_device Třída
Vygeneruje ne deterministický kryptograficky zabezpečený náhodný sekvenci pomocí externího zařízení. Obvykle se používá k zasadí motoru. Nízký výkon, velmi vysoká kvalita. Další informace naleznete v tématu Poznámky.

Definice typedef motoru s předdefinovanými parametry

Pro vytváření instancí motorů a adaptérů motoru. Další informace naleznete v tématu Moduly a distribuce.

  • default_random_engine Výchozí modul.

    typedef mt19937 default_random_engine;
    
  • knuth_b Knuth motor.

    typedef shuffle_order_engine<minstd_rand0, 256> knuth_b;
    
  • minstd_rand0 Minimální standardní motor 1988 (Lewis, Goodman a Miller, 1969).

    typedef linear_congruential_engine<unsigned int, 16807, 0, 2147483647> minstd_rand0;
    
  • minstd_rand Aktualizoval minimální standardní motor minstd_rand0 (Park, Miller a Stockmeyer, 1993).

    typedef linear_congruential_engine<unsigned int, 48271, 0, 2147483647> minstd_rand;
    
  • mt19937 32bitový twister Mersenne (Matsumoto a Nishimura, 1998).

    typedef mersenne_twister_engine<
        unsigned int, 32, 624, 397,
        31, 0x9908b0df,
        11, 0xffffffff,
        7, 0x9d2c5680,
        15, 0xefc60000,
        18, 1812433253> mt19937;
    
  • mt19937_64 64bitový twister Mersenne (Matsumoto a Nishimura, 2000).

    typedef mersenne_twister_engine<
        unsigned long long, 64, 312, 156,
        31, 0xb5026f5aa96619e9ULL,
        29, 0x5555555555555555ULL,
        17, 0x71d67fffeda60000ULL,
        37, 0xfff7eee000000000ULL,
        43, 6364136223846793005ULL> mt19937_64;
    
  • ranlux24 24bitový motor RANLUX (Martin Lüscher a Fred James, 1994).

    typedef discard_block_engine<ranlux24_base, 223, 23> ranlux24;
    
  • ranlux24_base Používá se jako základ pro ranlux24.

    typedef subtract_with_carry_engine<unsigned int, 24, 10, 24> ranlux24_base;
    
  • ranlux48 48bitový motor RANLUX (Martin Lüscher a Fred James, 1994).

    typedef discard_block_engine<ranlux48_base, 389, 11> ranlux48;
    
  • ranlux48_base Používá se jako základ pro ranlux48.

    typedef subtract_with_carry_engine<unsigned long long, 48, 5, 12> ranlux48_base;
    

Šablony stroje

Šablony motoru se používají jako samostatné URNG nebo jako základní motory předávané adaptérům motoru. Obvykle se vytvoří instance s předdefinovaným typedef motoru a předá se do distribuce. Další informace najdete v části Moduly a distribuce.

Název Popis
linear_congruential_engine Třída Generuje náhodnou sekvenci pomocí lineárního kongruenciálního algoritmu. Nejsimístnější a nejnižší kvalita.
mersenne_twister_engine Třída Generuje náhodnou sekvenci pomocí algoritmu Twister Mersenne. Nejsložitější a je nejvyšší kvalita s výjimkou třídy random_device. Velmi rychlý výkon.
subtract_with_carry_engine Třída Vygeneruje náhodnou sekvenci pomocí algoritmu odčítání s přenosem. Zlepšení linear_congruential_engine, ale mnohem nižší kvalita a výkon než mersenne_twister_engine.

Šablony adaptéru motoru

Adaptéry motoru jsou šablony, které přizpůsobují jiné (základní) motory. Obvykle se vytvoří instance s předdefinovaným typedef motoru a předá se do distribuce. Další informace najdete v části Moduly a distribuce.

Název Popis
discard_block_engine Třída Generuje náhodnou sekvenci tak, že zahodí hodnoty vrácené základním modulem.
independent_bits_engine Třída Vygeneruje náhodnou sekvenci se zadaným počtem bitů opětovným zabalením bitů z hodnot vrácených jeho základním motorem.
shuffle_order_engine Třída Vygeneruje náhodnou sekvenci tak, že změní pořadí hodnot vrácených ze základního modulu.

[Šablony stroje]

Rozdělení náhodných čísel

Následující části obsahují seznam distribucí uvedených v <random> hlavičce. Distribuce jsou mechanismus následného zpracování, který obvykle jako vstup používá výstup URNG a distribuuje výstup definovanou funkcí hustoty statistické pravděpodobnosti. Další informace najdete v části Moduly a distribuce.

Uniform Distributions

Název Popis
uniform_int_distribution Třída Vytvoří rovnoměrné celočíselné rozdělení hodnoty v rozsahu v uzavřeném intervalu [a, b] (včetně).
uniform_real_distribution Třída Vytvoří rovnoměrné rozdělení reálné hodnoty (s plovoucí desetinou čárkou) v rozsahu v polootevřeném intervalu [a, b) (včetně výhradního).
generate_canonical Vytvoří rovnoměrné rozdělení skutečných hodnot (s plovoucí desetinnou čárkou) dané přesnosti mezi [0, 1) (včetně výhradního).

[Rozdělení náhodných čísel]

Bernoulli Distributions

Název Popis
bernoulli_distribution Třída Vytvoří Bernoulli rozdělení bool hodnot.
binomial_distribution Třída Vytvoří binomické rozdělení celočíselné hodnoty.
geometric_distribution Třída Vytvoří geometrické rozdělení celočíselné hodnoty.
negative_binomial_distribution Třída Vytvoří záporné binomické rozdělení celočíselné hodnoty.

[Rozdělení náhodných čísel]

Normální rozdělení

Název Popis
cauchy_distribution Třída Vytvoří cauchy rozdělení skutečných hodnot (s plovoucí desetinou čárkou).
chi_squared_distribution Třída Vytvoří rozdělení chí-kvadrát skutečných hodnot (s plovoucí desetinou čárkou).
fisher_f_distribution Třída Vytvoří F-rozdělení (označované také jako rozdělení F Snedecoru nebo Fisher-Snedecor rozdělení) skutečných hodnot (s plovoucí desetinou čárkou).
lognormal_distribution Třída Vytvoří normální rozdělení reálných hodnot (s plovoucí desetinou čárkou).
normal_distribution Třída Vytvoří normální rozdělení skutečných hodnot (s plovoucí desetinou čárkou) (Gaussian).
student_t_distribution Třída Vytvoří studentovo t-rozdělení skutečných hodnot (s plovoucí desetinou čárkou).

[Rozdělení náhodných čísel]

Poissonova rozdělení

Název Popis
exponential_distribution Třída Vytvoří exponenciální rozdělení skutečných hodnot (s plovoucí desetinnou čárkou).
extreme_value_distribution Třída Vytvoří extrémní rozdělení hodnot skutečných hodnot (s plovoucí desetinou čárkou).
gamma_distribution Třída Vytvoří gama rozdělení skutečných hodnot (s plovoucí desetinou čárkou).
poisson_distribution Třída Vytvoří Poissonovo rozdělení celočíselné hodnoty.
weibull_distribution Třída Vytvoří Weibullovu distribuci skutečných hodnot (s plovoucí desetinou čárkou).

[Rozdělení náhodných čísel]

Distribuce vzorkování

Název Popis
discrete_distribution Třída Vytvoří diskrétní celočíselné rozdělení.
piecewise_constant_distribution Třída Vytvoří rozdělení skutečných hodnot (s plovoucí desetinou čárkou) po částech.
piecewise_linear_distribution Třída Vytvoří určitou lineární distribuci skutečných hodnot (s plovoucí desetinou čárkou).

[Rozdělení náhodných čísel]

Utility Functions

V této části jsou uvedeny obecné funkce nástroje uvedené v <random> hlavičce.

Název Popis
seed_seq Třída Vygeneruje nepřesnou sekvenci počátečních sekvencí, která není zkreslená. Používá se k zabránění replikaci náhodných variatech. Užitečné v případech, kdy se z motorů vytváří instance mnoha URNG.

Operátory

V této části jsou uvedeny operátory uvedené v <random> hlavičce.

Název Popis
operator== Testuje, zda je URNG na levé straně operátoru roven motoru na pravé straně.
operator!= Testuje, zda se URING na levé straně operátoru nerovná modulu na pravé straně.
operator<< Zapíše informace o stavu do datového proudu.
operator>> Extrahuje informace o stavu z datového proudu.

Motory a distribuce

Informace o každé z těchto kategorií šablon tříd definovaných v následujících částech najdete v <random>následujících částech. Obě tyto kategorie šablon tříd mají typ jako argument a používají názvy parametrů sdílené šablony k popisu vlastností typu, které jsou povoleny jako skutečný typ argumentu, následujícím způsobem:

  • IntTypeshortoznačuje , , int, unsigned shortlong longunsigned intlong, unsigned long, nebo .unsigned long long

  • UIntType označuje unsigned short, , unsigned int, unsigned longnebo unsigned long long.

  • RealType označuje float, doublenebo long double.

Motory

Šablony modulu a šablony adaptéru motoru jsou šablony, jejichž parametry přizpůsobují generátor vytvořený.

Modul je šablona třídy nebo třídy, jejíž instance (generátory) fungují jako zdroj náhodných čísel rovnoměrně rozdělených mezi minimální a maximální hodnotu. Adaptér motoru poskytuje sekvenci hodnot, které mají různé vlastnosti náhodnosti, tím, že vezme hodnoty vytvořené jiným modulem náhodných čísel a použije na tyto hodnoty algoritmus určitého druhu.

Každý adaptér motoru a motoru má následující členy:

  • typedefnumeric-type result_type je typ vrácený generátorem operator(). Předá se numeric-type jako parametr šablony při vytváření instancí.

  • result_type operator() vrátí hodnoty, které jsou rovnoměrně rozděleny mezi min() a max().

  • result_type min() vrátí minimální hodnotu vrácenou generátorem operator(). Adaptéry motoru používají výsledek základního min() motoru.

  • result_type max() vrátí maximální hodnotu vrácenou generátorem operator(). Je-li result_type celočíselný typ (celočíselný) typ, je maximální hodnota, max() která může být skutečně vrácena (včetně); pokud result_type je typ max() s plovoucí desetinou čárkou (real-valued), je nejmenší hodnota větší než všechny hodnoty, které lze vrátit (ne inclusive). Adaptéry motoru používají výsledek základního max() motoru.

  • void seed(result_type s) zasadí generátor s počáteční hodnotou s. Pro moduly je void seed(result_type s = default_seed) podpis pro podporu výchozích parametrů (adaptéry motoru definují samostatný void seed()pododdíl).

  • template <class Seq> void seed(Seq& q)zasadí generátor pomocí .seed_seqSeq

  • Explicitní konstruktor s argumentem result_type x , který vytvoří generátor počáteční jako by voláním seed(x).

  • Explicitní konstruktor s argumentem seed_seq& seq , který vytvoří generátor počáteční jako by voláním seed(seq).

  • void discard(unsigned long long count) efektivně volá operator() count časy a zahodí každou hodnotu.

Adaptéry motoru navíc podporují tyto členy (Engine je prvním parametrem šablony adaptéru motoru, který označuje typ základního motoru):

  • Výchozí konstruktor pro inicializaci generátoru, jako by byl z výchozího konstruktoru základního modulu.

  • Explicitní konstruktor s argumentem const Engine& eng. Jde o podporu konstrukce kopírování pomocí základního motoru.

  • Explicitní konstruktor s argumentem Engine&& eng. Jedná se o podporu konstrukce pohybu pomocí základního motoru.

  • void seed() inicializuje generátor s výchozí počáteční hodnotou základního motoru.

  • const Engine& base() funkce property, která vrací základní modul, který byl použit k vytvoření generátoru.

Každý modul udržuje stav , který určuje posloupnost hodnot, které budou generovány následnými voláními operator(). Stavy dvou generátorů vytvořených z motorů stejného typu lze porovnat pomocí a operator== operator!=. Pokud se tyto dva stavy porovnávají jako stejné, vygenerují stejnou sekvenci hodnot. Stav objektu lze uložit do datového proudu jako posloupnost 32bitových nepodepsaných hodnot pomocí operator<< generátoru. Stav se nezmění uložením. Uložený stav lze načíst do instance generátoru z motoru stejného typu pomocí operator>>.

Distribuce

Rozdělení náhodných čísel je třída nebo šablona třídy, jejíž instance transformují datový proud jednotně distribuovaných náhodných čísel získaných z modulu do datového proudu náhodných čísel, které mají konkrétní rozdělení. Každá distribuce má následující členy:

  • typedefnumeric-type result_type je typ vrácený distribučním operator()typem . Předá se numeric-type jako parametr šablony při vytváření instancí.

  • template <class URNG> result_type operator()(URNG& gen) vrátí hodnoty, které jsou distribuovány podle definice rozdělení, pomocí jako gen zdroj jednotně distribuovaných náhodných hodnot a uložených parametrů rozdělení.

  • template <class URNG> result_type operator()(URNG& gen, param_type p) vrací hodnoty distribuované v souladu s definicí rozdělení, která se používá gen jako zdroj jednotně distribuovaných náhodných hodnot a struktury pparametrů .

  • typedefunspecified-type param_type je balíček parametrů volitelně předaný operator() a používá se místo uložených parametrů k vygenerování jeho návratové hodnoty.

  • const param& Konstruktor inicializuje uložené parametry z argumentu.

  • param_type param() const získá uložené parametry.

  • void param(const param_type&) nastaví uložené parametry z argumentu.

  • result_type min() vrátí minimální hodnotu vrácenou distribuční operator()hodnotou .

  • result_type max() vrátí maximální hodnotu vrácenou rozdělením operator(). Je-li result_type celočíselný typ (celočíselný) typ, je maximální hodnota, max() která může být skutečně vrácena (včetně); pokud result_type je typ max() s plovoucí desetinou čárkou (real-valued), je nejmenší hodnota větší než všechny hodnoty, které lze vrátit (ne inclusive).

  • void reset() zahodí všechny hodnoty uložené v mezipaměti, aby výsledek dalšího volání operator() nezávisel na žádných hodnotách získaných z modulu před voláním.

Struktura parametrů je objekt, který ukládá všechny parametry potřebné pro distribuci. Obsahuje:

  • typedefdistribution-type distribution_type, což je typ jeho rozdělení.

  • Jeden nebo více konstruktorů, které přebírají stejné seznamy parametrů jako konstruktory distribuce.

  • Stejné funkce přístupu k parametrům jako distribuce.

  • Relační operátory rovnosti a nerovnosti.

Další informace najdete v referenčních dílčích tématech pod touto tématií, která byla propojena dříve v tomto článku.

Poznámky

V sadě Visual Studio jsou dvě vysoce užitečné skupiny definovaných uživatelem ,mt19937 random_devicejak je znázorněno v této srovnávací tabulce:

URNG Rychlé Crypto-secure Seedable Deterministický
mt19937 Yes Ne Ano Ano*
random_device Ne Ano No Ne

* Je-li poskytováno se známým semenem.

I když standard ISO C++ nevyžaduje random_device kryptograficky zabezpečení, v sadě Visual Studio se implementuje za účelem kryptografického zabezpečení. (Pojem "kryptograficky zabezpečený" neznamená záruky, ale odkazuje na minimální úroveň entropie , a proto úroveň předvídatelnosti – poskytuje daný algoritmus randomizace. Další informace naleznete v článku Wikipedie Kryptograficky bezpečný pseudorandom čísel generátor.) Vzhledem k tomu, že standard ISO C++ to nevyžaduje, mohou jiné platformy implementovat random_device jako jednoduchý pseudonáhodný generátor čísel (ne kryptograficky zabezpečený) a může být vhodný pouze jako počáteční zdroj pro jiný generátor. Projděte si dokumentaci k těmto platformám při použití random_device v kódu pro různé platformy.

Podle definice random_device nejsou výsledky reprodukovatelné a vedlejším účinkem je, že může běžet výrazně pomaleji než jiné skupiny definovaných uživatelem. Většina aplikací, které nemusí být kryptograficky bezpečné použití mt19937 nebo podobný modul, i když můžete chtít ho zavolat voláním random_device, jak je znázorněno v příkladu kódu.

Viz také

Referenční informace k souborům hlaviček