Ackermann-funktio on yksinkertainen esimerkki kaikkialla määritellystä laskettavasta funktiosta , joka ei ole primitiivinen rekursiivinen . Se ottaa kaksi ei-negatiivista kokonaislukua parametreiksi ja palauttaa luonnollisen luvun , joka on merkitty . Tämä funktio kasvaa hyvin nopeasti, esimerkiksi luku on niin suuri, että numeroiden määrä tämän luvun järjestyksessä on monta kertaa suurempi kuin atomien lukumäärä universumin havaittavassa osassa .
1920-luvun lopulla David Hilbertin matemaatikot Gabriel Sudan ja Wilhelm Ackermann tutkivat tietojenkäsittelyn perusteita. Sudan ja Ackerman ovat kuuluisia [1] siitä, että he ovat löytäneet kaikkialla määritellyn laskettavan funktion (jota joskus kutsutaan yksinkertaisesti "rekursiiviseksi"), joka ei ole primitiivinen rekursiivinen . Sudan löysi vähemmän tunnetun funktion Sudan , jonka jälkeen Ackerman hänestä riippumatta julkaisi tehtävänsä vuonna 1928 . Kolmen argumentin Ackermann-funktio määriteltiin siten, että se suoritti sille yhteen-, kerto- tai eksponentiooperaation:
ja sitä on laajennettu käyttämällä Knuthin vuonna 1976 julkaistua nuolen merkintää:
.(Sen lisäksi, että Ackermannin alkuperäinen funktio oli historiallinen rooli ensimmäisenä kaikkialla määriteltynä ei-primitiivisenä rekursiivisena laskettavana funktiona, se laajensi aritmeettisia perusoperaatioita eksponentioinnin ulkopuolelle, vaikkakaan ei yhtä hyvin dedikoituja toimintoja, kuten Goodsteinin hyperoperaattorisekvenssiä .)
Teoksessaan On the Infinite Hilbert arveli, että Ackermannin funktio ei ole primitiivisesti rekursiivinen, ja Ackerman (Hilbertin henkilökohtainen sihteeri ja entinen oppilas) osoitti tämän olettamuksen teoksessa On Hilbert's Construction of the Real Numbers. Rosa Peter ja Raphael Robinson esittelivät myöhemmin kaksiargumenttisen version Ackermann-funktiosta, jota monet kirjoittajat pitävät nykyään parempana kuin alkuperäinen [2] .
Ackermann-funktio määritellään rekursiivisesti ei-negatiivisille kokonaisluvuille seuraavasti :
Ei ehkä näytä itsestään selvältä, että rekursio päättyy aina. Tämä johtuu siitä, että rekursiivisessa kutsussa joko arvoa pienennetään tai arvo säilytetään, mutta arvoa pienennetään . Tämä tarkoittaa, että joka kerta kun paria pienennetään leksikografisen järjestyksen suhteen , mikä tarkoittaa, että arvo saavuttaa lopulta nollan: yhdelle arvolle on rajallinen määrä mahdollisia arvoja (koska ensimmäinen puhelu datalla oli tehty jollain tietyllä arvolla , ja lisäksi, jos arvo säilytetään, arvo voi vain pienentyä), ja mahdollisten arvojen määrä puolestaan on myös äärellinen. Kuitenkin, kun pienennetään , arvo, joka kasvaa arvolla, on rajoittamaton ja yleensä erittäin suuri.
( lohkot yhteensä ) |
Koska funktio kasvaa hyvin nopeasti, käänteisfunktio , jota merkitään , kasvaa hyvin hitaasti. Tämä funktio on tavattu tutkittaessa joidenkin algoritmien monimutkaisuutta , esimerkiksi disjunktijoukkojen järjestelmää tai Chazell-algoritmia minimivirittävän puun rakentamiseen [3] . Analysoitaessa asymptotiikkaa voidaan olettaa, että kaikilla käytännössä esiintyvillä luvuilla tämän funktion arvo on pienempi kuin viisi, koska se ei ole pienempi kuin .
Ackerman-funktiolla on määritelmänsä perusteella erittäin syvä rekursiotaso, jonka avulla voidaan testata kääntäjän kykyä optimoida rekursio. Yngwie Sundblad [4] käytti ensimmäisenä Ackerman-funktiota tähän .
Brian Wichman ( Whetstone-benchmarkin toinen kirjoittaja ) otti tämän artikkelin huomioon kirjoittaessaan artikkelisarjan puhelun optimointitestauksesta [5] [6] [7] .
Esimerkiksi kääntäjä, joka pystyy laskentaa analysoidessaan tallentamaan väliarvot, esimerkiksi ja , voi nopeuttaa laskentaa satoja ja tuhansia kertoja. Myös suora arviointi rekursiivisen laajennuksen sijaan nopeuttaa laskentaa melkoisesti. Laskenta kestää lineaarista aikaa . Laskenta vaatii neliöaikaa, koska se laajenee O ( ) sisäkkäisiksi kutsuiksi eri . Laskenta-aika on verrannollinen .
Arvoa ei voida laskea yksinkertaisella rekursiivisella sovelluksella kohtuullisessa ajassa. Sen sijaan rekursiivisten kutsujen optimointiin käytetään pikakaavoja, kuten .
Yksi käytännöllisistä tavoista laskea Ackermann-funktion arvot on välitulosten muistiin tallentaminen . Kääntäjä voi soveltaa tätä tekniikkaa funktioon automaattisesti käyttämällä muistiofunktioita [8] [9] , kirjoittaja Donald Michie .
Isoja lukuja | |
---|---|
Numerot | |
Toiminnot | |
Merkinnät |