Ziggurat-algoritmi

Kokeneet kirjoittajat eivät ole vielä tarkistaneet sivun nykyistä versiota, ja se voi poiketa merkittävästi 21. maaliskuuta 2018 tarkistetusta versiosta . tarkastukset vaativat 4 muokkausta .

Ziggurat-algoritmi ( eng.  Ziggurat Algorithm , Ziggurat Method ) on algoritmi näennäissatunnaisten lukujen näytteenottoon . Koska hän edustaa näytteenottoalgoritmien luokkaa, jolla on poikkeama , hän luottaa työssään tasaisesti jakautuneiden satunnaislukujen lähteeseen - yleensä pseudosatunnaislukugeneraattoriin tai ennalta laskettuun taulukkoon. Algoritmilla luodaan arvoja monotonisesti laskevan todennäköisyysjakauman perusteella . Sitä voidaan soveltaa myös symmetriseen unimodaaliseen jakaumaan, kuten normaalijakaumaan , valitsemalla arvoja sen toisesta puoliskosta ja sitten tarvittaessa muuttamalla symmetriseksi arvoksi aritmeettisen negaatiooperaation avulla. Yksi 1960-luvulla kehitetyn algoritmin tekijöistä on George Marsaglia .

Yksinkertaisimmassa tapauksessa algoritmin palauttaman arvon laskeminen vaatii vain yhden kelluvan ja yhden satunnaistaulukkoindeksin luomisen, jota seuraa yksi taulukkohaku, yksi kertolasku ja yksi vertailu. Joskus (paljon harvemmissa tapauksissa) tarvitaan monimutkaisempia laskelmia. Tämä algoritmi on kuitenkin laskennallisesti paljon nopeampi kuin kaksi yleisimmin käytettyä normaalijakauman satunnaislukujen generointimenetelmää: Marsaglian polaarimenetelmä ja Box-Muller-muunnos , jotka edellyttävät vähintään yhden logaritmin ja yhden neliön laskemista. juuri jokaiselle luodulle arvoparille. Koska Ziggurat-algoritmi on kuitenkin monimutkaisempi toteuttaa, sitä käytetään useimmiten tapauksissa, joissa tarvitaan suuri määrä satunnaislukuja.

Itse termi "Ziggurat Algorithm" esiintyy Marsaglian ja Wai Van Tsangin yhteisessä työssä vuonna 2000, ja se on saanut nimensä, koska se perustuu käsitteellisesti todennäköisyysjakauman kattamiseen suorakaiteen muotoisilla segmenteillä pinottuina päällekkäin pienenevän koon mukaan (kun alhaalta ylöspäin katsottuna), jolloin tuloksena on zikguraattia muistuttava hahmo .

Teoreettinen perusta

Ziggurat-algoritmi on bias-näytteenottoalgoritmi. Se luo satunnaisesti pisteen, joka poikkeaa hieman halutusta jakaumasta, ja tarkistaa sitten, osuuko luotu piste tarkalleen sen sisään. Jos ei, algoritmi yrittää uudelleen. Jos piste sijaitsee todennäköisyystiheysfunktion käyrän alla, niin sen x -koordinaatti on haluttu satunnaisluku halutulla jakaumalla.

Jakauma, josta algoritminäytteet koostuu alueista, joiden pinta-ala on yhtä suuri; suorakulmio kattaa pääosan halutusta jakaumasta ja on "pyramidi" ei-suorakulmaisella pohjalla, joka sisältää jakauman loppuosan tai "häntä".

Tietylle kaikille määritetylle monotonisesti pienenevälle todennäköisyystiheysfunktiolle zikguratin kanta määritellään kaikiksi pisteiksi jakauman sisällä ja joidenkin alapuolella . Se koostuu suorakaiteen muotoisesta osasta - , ja (yleensä äärettömästä) jakauman jäännöksestä (häntä), jossa (ja ).

Tämän tason (kutsutaanko sitä tasoksi 0) pinta-ala on . Lisätään sen yläosaan uusi suorakaiteen muotoinen leveys- ja korkeustaso , jotta sen pinta-ala on myös yhtä suuri kuin . Tämän tason yläosa on korkeudella ja leikkaa tiheysfunktion kohdassa, jossa . Tämä taso sisältää kaikki tiheysfunktiopisteet välillä ja , mutta (toisin kuin perustaso) sisältää myös muita pisteitä, kuten , jotka eivät kuulu haluttuun jakaumaan.

Kaikki seuraavat tasot asetetaan päällekkäin samalla tavalla. Valmiiksi lasketun kokotaulukon käyttämiseksi ( käytetään hyvin usein), tulee valita sellainen , että ylempi suorakaiteen muotoinen taso numerolla saavuttaa jakauman huipun täsmälleen pisteessä .

Taso, jonka korkeus on numero , on paikan päällä ja se voidaan jakaa leveydeltään kahteen alueeseen: osaan alkaen - (yleensä suurempi), joka sisältyy kokonaan tiettyyn jakaumaan, ja osaan -lta - (pienempi), joka sisältyy vain osittain.

Unohtaen hetkeksi kysymyksen tason 0 erikoistapauksesta, jolla on tasaisesti jakautuneet luvut ja , algoritmia voidaan kuvata seuraavasti:

  1. Valitse satunnainen taso .
  2. Laita .
  3. Jos , palauta .
  4. Laita .
  5. Laske . Jos , palauta .
  6. Muussa tapauksessa valitse uudet satunnaisluvut ja palaa vaiheeseen 1.

Vaihe 1 on tason satunnainen otanta. Vaiheessa 3 tarkistetaan, onko koordinaatti hyvin annetussa tiheysfunktiossa, vaikka koordinaatista ei olisikaan tietoa . Jos ei, vaihe 4 laskee koordinaatin ja vaihe 5 tarkistaa, onko se halutun alueen sisällä.

Jos tasojen määrä on riittävän suuri ja niillä on pieni korkeus, niin sama "riskivyöhyke", joka tarkistetaan vaiheen 3 jälkeen, on hyvin pieni ja algoritmi pysähtyy vaiheeseen 3 merkittävän osan ajasta. Huomaa, että ylempi taso kuitenkin aina epäonnistuu tässä testissä, koska .

Taso 0 voidaan jakaa myös keski- ja raja-alueeseen, mutta raja-alue sisältää loputtoman osan funktiosta. Jos haluat käyttää samaa algoritmia tarkastaaksesi, kuuluuko piste keskialueelle, kannattaa luoda dummy . Koordinaattipisteet käsitellään yksinkertaisesti, ja siinä harvinaisessa tapauksessa, että taso 0 ja valittiin , sinun on käytettävä erityistä varaalgoritmia valitaksesi satunnaisesti piste funktion "pyrstöstä". Koska tällaista varaalgoritmia käytetään erittäin harvoin (harvinaisuus on suhteellinen ja riippuu tasosta), sen nopeudella ei ole merkittävää vaikutusta yleiseen suorituskykyyn.

Siten täydellinen Ziggurat-algoritmi epäsymmetriselle jakaumille on seuraava:

  1. Valitse satunnainen taso .
  2. Laita .
  3. Jos , palauta .
  4. Jos , luo piste "hännästä" käyttämällä varaalgoritmia.
  5. Laita .
  6. Laske . Jos , palauta .
  7. Muussa tapauksessa valitse uudet satunnaisluvut ja palaa vaiheeseen 1.

Symmetrisen jakauman tapauksessa tulos voidaan tietysti yksinkertaisesti kääntää 50% ajasta. Se voi usein olla kätevää luoda ja testata vaiheessa 3 .

Varaalgoritmit funktion hännän

Koska Ziggurat-algoritmi luo vain suurimman osan arvoista erittäin nopeasti ja vaatii varaalgoritmin tapauksissa , asiat ovat monimutkaisempia kuin suora 6-vaiheinen toteutus. Varaalgoritmi riippuu annetusta jakaumasta.

Eksponentiaalisen jakauman tapauksessa häntä on jakaumakappaleen muodossa. Yksi tapa on palata alkeisimpaan algoritmiin ja laittaa . Toinen tapa on kutsua rekursiivisesti Ziggurat-algoritmia ja lisätä tulokseen.

Normaalijakauman tapauksessa Marsaglia ehdottaa kompaktia algoritmia:

  1. Laita .
  2. Laita .
  3. Jos , palauta .
  4. Muussa tapauksessa palaa vaiheeseen 1.

Koska taulukot ovat enemmän tai vähemmän tyypillisiä kokoja, vaiheen 3 testi onnistuu melkein aina.

Optimoinnit

Algoritmi voidaan tehdä tehokkaasti käyttämällä esilaskettuja taulukoita ja , mutta on olemassa muutamia muutoksia, jotka nopeuttavat sitä entisestään:

Taulukon luominen

Taulukko voidaan joko pitää valmiiksi laskettuna ja täydellisenä tai vain sisällyttää arvot , , ja toteutus lähdekoodiin ja laskea loput arvot satunnaislukugeneraattorin alustuksen yhteydessä (riippuen siitä, mitä meille kalliimpi: laskentaaika tai muisti).

Voit löytää ja . Toista zikguratin kaikilla tasoilla. Sen pitäisi onnistua lopulta .

Taulukon lopulliseen täyttöön tulee laittaa ja hyväksyen pienet epäjohdonmukaisuudet (jos ne todella tulivat pieniksi) pyöristysvirheiksi .

Hae ja

Jos alkuarvo on (laskettu, jos ei tarkalleen, niin likimääräinen), jää vain laskea funktion loppuosan pinta-ala, jolle . Voit laskea numeerisilla integrointimenetelmillä .

Lisäksi sieltä on mahdollista löytää , hännän osan alueelta on pohjatason alue: .

Sitten sarja ja lasketaan edellä esitetyllä tavalla. Jos jollekin , niin alkuperäinen arvo oli liian pieni, mikä johti suureen alueeseen . Jos , niin alkuperäinen arvo oli liian suuri.

Yllä olevan perusteella voit käyttää yhtälöiden numeerista ratkaisua (esimerkiksi puolittamismenetelmää ) löytääksesi arvon , jonka arvo on mahdollisimman lähellä . Vaihtoehtoisesti voidaan harkita ja löytää arvoja ylimmän tason alueelle, , mahdollisimman lähellä haluttua arvoa .

Muistiinpanot

  1. Jurgen A. Doornik. "Parannettu Ziggurat-menetelmä normaalien satunnaisnäytteiden luomiseksi" (englanniksi) // Nuffield College, Oxford. - 2005. Arkistoitu 7. maaliskuuta 2016.

Kirjallisuus

Linkit