Funcția Ackermann este un exemplu simplu de funcție computabilă definită peste tot, care nu este recursivă primitivă . Ia două numere întregi nenegative ca parametri și returnează un număr natural , notat cu . Această funcție crește foarte repede, de exemplu, numărul este atât de mare încât numărul de cifre din ordinea acestui număr este de multe ori mai mare decât numărul de atomi din partea observabilă a Universului .
La sfârșitul anilor 1920, matematicienii lui David Hilbert , Gabriel Sudan și Wilhelm Ackermann , au studiat bazele calculului. Sudan și Ackerman sunt faimoși [1] pentru că au descoperit o funcție computabilă definită peste tot (uneori numită pur și simplu „recursivă”) care nu este recursivă primitivă . Sudan a descoperit funcția mai puțin cunoscută Sudan , după care, independent de el, Ackerman și-a publicat funcția în 1928 . Funcția Ackermann a trei argumente a fost definită în așa fel încât pentru aceasta a efectuat operația de adunare, înmulțire sau exponențiere:
și pentru aceasta este extinsă folosind notația săgeată a lui Knuth , publicată în 1976:
.(Pe lângă rolul său istoric de prima funcție computabilă recursivă neprimitivă definită peste tot, funcția originală a lui Ackermann a extins operațiile aritmetice de bază dincolo de exponențiere, deși nu la fel de bine ca funcții dedicate precum secvența hiperoperatorului lui Goodstein .)
În Despre infinit, Hilbert a presupus că funcția lui Ackermann nu este recursivă primitiv, iar Ackerman (secretarul personal și fostul student al lui Hilbert) a demonstrat această presupunere în Construcția numerelor reale a lui Hilbert. Rosa Peter și Raphael Robinson au prezentat ulterior o versiune cu două argumente a funcției Ackermann, pe care mulți autori o preferă acum față de originalul [2] .
Funcția Ackermann este definită recursiv pentru numere întregi nenegative și după cum urmează:
Poate să nu pară evident că recursiunea se termină întotdeauna. Acest lucru rezultă din faptul că, într-un apel recursiv, fie valoarea lui este redusă , fie valoarea este păstrată, dar valoarea este redusă . Aceasta înseamnă că de fiecare dată perechea este redusă din punct de vedere al ordinii lexicografice , ceea ce înseamnă că valoarea va ajunge în cele din urmă la zero: pentru o valoare , există un număr finit de valori posibile (de vreme ce primul apel cu datele a fost realizat cu o anumită valoare și, în plus, dacă valoarea este păstrată, valoarea poate doar să scadă), iar numărul de valori posibile , la rândul său, este de asemenea finit. Cu toate acestea, atunci când scade , valoarea care crește cu este nelimitată și de obicei foarte mare.
(total de blocuri ) |
Deoarece funcția crește foarte repede, funcția inversă , notată cu , crește foarte lent. Această funcție este întâlnită în studiul complexității unor algoritmi , de exemplu, un sistem de mulțimi disjunctive sau algoritmul Chazell pentru construirea unui arbore de întindere minim [3] . Când analizăm asimptoticele , putem presupune că pentru toate numerele care apar practic, valoarea acestei funcții este mai mică de cinci, deoarece nu este mai mică de .
Funcția Ackerman, în virtutea definiției sale, are un nivel foarte profund de recursivitate, care poate fi folosit pentru a testa capacitatea compilatorului de a optimiza recursiunea. Yngwie Sundblad [4] a fost primul care a folosit funcția Ackerman pentru aceasta .
Brian Wichman (coautor al benchmark-ului Whetstone ) a luat în considerare acest articol atunci când a scris o serie de articole despre testarea optimizării apelurilor [5] [6] [7] .
De exemplu, un compilator care, atunci când analizează un calcul, este capabil să stocheze valori intermediare, de exemplu, și , poate accelera calculul de sute și mii de ori. De asemenea, evaluarea directă, în loc să se extindă recursiv, va accelera destul de mult calculul. Calculul durează timp liniar . Calculul necesită timp pătratic, deoarece se extinde în O ( ) apeluri imbricate pentru diverse . Timpul de calcul este proporțional cu .
Valoarea nu poate fi calculată cu o simplă aplicație recursivă într-o perioadă rezonabilă de timp. În schimb, formulele scurte sunt folosite pentru a optimiza apelurile recursive, cum ar fi .
Una dintre modalitățile practice de a calcula valorile funcției Ackermann este memorarea rezultatelor intermediare. Compilatorul poate aplica automat această tehnică unei funcții folosind funcții memo [8] [9] de Donald Michie .
Cifre mari | |
---|---|
Numerele | |
Funcții | |
Notații |