Zikkuratový algoritmus

Aktuální verze stránky ještě nebyla zkontrolována zkušenými přispěvateli a může se výrazně lišit od verze recenzované 21. března 2018; kontroly vyžadují 4 úpravy .

Ziggurat Algorithm ( angl.  Ziggurat Algorithm , Ziggurat Method ) je algoritmus pro vzorkování pseudonáhodných čísel . Jako zástupce třídy vzorkovacích algoritmů s odchylkou se ve své práci opírá o zdroj rovnoměrně rozložených náhodných čísel - obvykle generátor pseudonáhodných čísel nebo předem vypočítanou tabulku. Algoritmus se používá ke generování hodnot na základě monotónně klesajícího rozdělení pravděpodobnosti . Může být také aplikován na symetrické unimodální rozdělení, jako je normální, výběrem hodnot z jedné její poloviny a poté v případě potřeby přechodem na symetrickou hodnotu pomocí operace aritmetické negace. Jedním z autorů algoritmu vyvinutého v 60. letech 20. století je George Marsaglia .

V nejjednodušším případě vyžaduje výpočet hodnoty vrácené algoritmem pouze generování jednoho float a jednoho indexu náhodné tabulky, po kterém následuje jedno vyhledávání v tabulce, jedno násobení a jedno srovnání. Někdy (v mnohem menším počtu případů) jsou vyžadovány složitější výpočty. Tento algoritmus je však z výpočetního hlediska mnohem rychlejší než dvě nejběžněji používané metody pro generování normálně rozdělených náhodných čísel: Marsaglia polární metoda a Box-Mullerova transformace , které vyžadují výpočet alespoň jednoho logaritmu a jednoho čtverce . kořen pro každou dvojici generovaných hodnot. Protože je však algoritmus Zikkurat složitější na implementaci, nejčastěji se používá v případech, kdy je vyžadováno velké množství náhodných čísel.

Samotný termín „Zikkuratský algoritmus“ se objevuje ve společné práci Marsaglia a Wai Van Tsanga v roce 2000 a je tak pojmenován, protože je koncepčně založen na pokrytí rozdělení pravděpodobnosti pomocí pravoúhlých segmentů naskládaných na sebe v pořadí klesající velikosti (když při pohledu zdola nahoru), výsledkem je postava připomínající zikkurat .

Teoretický základ

Algoritmus zikkuratu je algoritmus vzorkování zkreslení. Náhodně vygeneruje bod, který se mírně odchyluje od požadovaného rozložení, a poté zkontroluje, zda vygenerovaný bod spadá přesně do něj. Pokud ne, algoritmus se pokusí znovu. Leží-li bod pod křivkou funkce hustoty pravděpodobnosti, pak jeho x -ová souřadnice bude požadované náhodné číslo s požadovaným rozdělením.

Distribuce, ze které algoritmus vzorky sestává z oblastí o stejné ploše; obdélník pokrývá hlavní část požadované distribuce a je "pyramida" na nepravoúhlé základně, která zahrnuje zbytek nebo "ocas" distribuce.

Pro danou monotónně klesající funkci hustoty pravděpodobnosti definovanou pro všechny je základ zikkuratu definován jako všechny body v distribuci a pod některými . Skládá se z pravoúhlé části od do a (obvykle nekonečného) zbytku (ocasu) rozdělení, kde (a ).

Tato úroveň (nazvěme ji úroveň 0) má plochu . K jeho vrcholu přidáme novou obdélníkovou úroveň šířky a výšky , takže jeho plocha bude také rovna . Vrchol této úrovně je ve výšce a protíná funkci hustoty v bodě , kde . Tato úroveň zahrnuje všechny body funkce hustoty mezi a , ale (na rozdíl od základní úrovně) zahrnuje i další body, jako například , které nepatří do požadované distribuce.

Všechny následující úrovně se překrývají stejným způsobem. Chcete-li použít předem vypočítanou tabulku velikostí ( používanou velmi často), měli byste zvolit takovou , aby horní obdélníková úroveň s číslem dosáhla vrcholu rozdělení přesně v bodě .

Úroveň s číslem na výšku zaujímá místo od do a lze ji rozdělit na šířku do dvou oblastí: část od do (obvykle větší), která je celá obsažena v daném rozložení, a část od do (menší), která je uvnitř obsažena jen částečně.

Když na chvíli zapomeneme na otázku speciálního případu s úrovní 0 a s rovnoměrně rozloženými čísly a , lze algoritmus popsat takto:

  1. Vyberte si náhodnou úroveň .
  2. Dejte .
  3. Pokud , vraťte se .
  4. Dejte .
  5. Vypočítejte . Pokud , vraťte se .
  6. V opačném případě vyberte nová náhodná čísla a vraťte se ke kroku 1.

Krok 1 je náhodné vzorkování úrovně. Krok 3 zkontroluje, zda souřadnice leží dobře v dané funkci hustoty i bez jakýchkoli informací o souřadnici . Pokud tomu tak není, krok 4 vypočítá souřadnici a krok 5 zkontroluje, zda je uvnitř požadované oblasti.

Pokud je počet úrovní dostatečně velký a mají malou výšku, pak je stejná "riziková zóna", která se kontroluje po kroku 3, velmi malá a algoritmus se na značnou část času zastaví v kroku 3. Všimněte si, že horní úroveň však v tomto testu vždy selže, protože .

Úroveň 0 lze také rozdělit na centrální a hraniční oblast, ale hraniční oblast bude obsahovat nekonečný zbytek funkce. Chcete-li použít stejný algoritmus ke kontrole, zda bod patří do centrální oblasti, vyplatí se vygenerovat figurínu . S body se souřadnicí se bude zacházet jednoduše a pro ten vzácný případ, kdy byla zvolena úroveň 0 a , budete muset použít speciální záložní algoritmus k náhodnému výběru bodu z "ocasu" funkce. Vzhledem k tomu, že takovýto záložní algoritmus bude používán extrémně zřídka (vzácnost je relativní a závisí na vrstvení), jeho rychlost nebude mít významný dopad na celkový výkon.

Kompletní Zigguratův algoritmus pro nesymetrické rozdělení je tedy následující:

  1. Vyberte si náhodnou úroveň .
  2. Dejte .
  3. Pokud , vraťte se .
  4. Pokud , vygenerujte bod z "ocasu" pomocí záložního algoritmu.
  5. Dejte .
  6. Vypočítejte . Pokud , vraťte se .
  7. V opačném případě vyberte nová náhodná čísla a vraťte se ke kroku 1.

Pro symetrickou distribuci lze výsledek samozřejmě v 50 % případů jednoduše obrátit. Často může být vhodné vygenerovat a otestovat v kroku 3 .

Záložní algoritmy pro konec funkce

Vzhledem k tomu, že algoritmus Zikkurat generuje většinu hodnot pouze velmi rychle a vyžaduje záložní algoritmus v případech , jsou věci složitější než přímá 6kroková implementace. Záložní algoritmus závisí na dané distribuci.

V případě exponenciálního rozdělení je ocas ve formě distribučního těla. Jedním ze způsobů je vrátit se k nejzákladnějšímu algoritmu a vložit . Dalším způsobem je rekurzivně volat algoritmus Zikkurat a přidat k výsledku.

V případě normální distribuce Marsaglia navrhuje kompaktní algoritmus:

  1. Dejte .
  2. Dejte .
  3. Pokud , vraťte se .
  4. V opačném případě se vraťte ke kroku 1.

Protože tabulky mají víceméně typické velikosti, test v kroku 3 téměř vždy uspěje.

Optimalizace

Algoritmus lze efektivně provést pomocí předpočítaných tabulek a , ale existuje několik úprav, které jej ještě více urychlí:

Generování tabulky

Je možné buď ponechat tabulku předem vypočítanou a úplnou, nebo pouze zahrnout hodnoty , , , a implementaci do zdrojového kódu a zbývající hodnoty vypočítat při inicializaci generátoru náhodných čísel (v závislosti na tom, co je pro nás dražší: výpočetní čas nebo paměť).

Můžete najít a . Opakujte pro všechny úrovně zikkuratu. Mělo by to nakonec vyjít .

Do konečného vyplňování tabulky je potřeba dát a , přičemž drobné nesrovnalosti (pokud opravdu vyšly malé) přijmete jako chyby zaokrouhlování .

Hledat a

Pokud existuje počáteční hodnota (vypočtená, pokud ne přesně, pak přibližně), zbývá pouze vypočítat plochu ocasní části funkce, pro kterou . Můžete počítat pomocí numerických integračních metod .

Dále je možné z oblasti ocasní části zjistit oblast základní úrovně: .

Potom se vypočítá řada a , jak je uvedeno výše. Pokud pro nějaký , pak počáteční hodnota byla příliš malá, což vedlo k velké ploše . Pokud , pak byla počáteční hodnota příliš velká.

Vzhledem k výše uvedenému můžete použít numerické řešení rovnic (například metoda půlení ) k nalezení hodnoty , které se hodnota co nejvíce blíží . Alternativně lze zvážit a najít hodnoty pro oblast nejvyšší úrovně , co nejblíže požadované hodnotě .

Poznámky

  1. Jurgen A. Doornik. "Vylepšená metoda zikkuratu pro generování normálních náhodných vzorků" (anglicky) // Nuffield College, Oxford. - 2005. Archivováno 7. března 2016.

Literatura

Odkazy