Функция Аккермана: различия между версиями
[отпатрулированная версия] | [непроверенная версия] |
У меня не получается нормально добавить программу вычисления функции на Pascal'е (текст разбивается на части). |
Нет описания правки |
||
Строка 1: | Строка 1: | ||
'''Функция Аккермана''' — простой пример [[Вычислимая функция|вычислимой функции]], которая не является [[Примитивно рекурсивная функция|примитивно рекурсивной]]. Она принимает два неотрицательных [[Целое число|целых числа]] в качестве параметров и возвращает [[натуральное число]], обозначается <math>A(m,\;n)</math>. Эта функция растёт очень быстро, например, число <math>A(4,\;4)</math> настолько велико, что количество цифр в порядке этого числа многократно превосходит количество атомов в наблюдаемой части Вселенной. |
'''Функция Аккермана''' — простой пример [[Вычислимая функция|вычислимой функции]], которая не является [[Примитивно рекурсивная функция|примитивно рекурсивной]]. Она принимает два неотрицательных [[Целое число|целых числа]] в качестве параметров и возвращает [[натуральное число]], обозначается <math>A(m,\;n)</math>. Эта функция растёт очень быстро, например, число <math>A(4,\;4)</math> настолько велико, что количество цифр в порядке этого числа многократно превосходит количество атомов в наблюдаемой части Вселенной. |
||
==История== |
|||
В конце 20-х годов XX века математики-ученики [[Гильберт, Давид|Давида Гильберта]] [[Судан, Габриэль|Габриэль Судан]] и [[Аккерман, Вильгельм|Вильгельм Аккерман]] изучали основы вычислений. Судан и Аккерман известны<ref>{{cite journal | author=Cristian Calude, Solomon Marcus and Ionel Tevy | journal = Historia Math. | title=The first example of a recursive function which is not primitive recursive | month=November | year=1979 | pages=380–84 | volume=6 | issue=4 | doi=10.1016/0315-0860(79)90024-7}}</ref> за открытие всюду определенной [[вычислимая функция|вычислимой]] (иногда называемой просто "рекурсивной"), не являющейся [[Примитивно рекурсивная функция|примитивно рекурсивной]]. Судан открыл менее известную [[функция Судана|функцию Судана]], после чего, независимо от него, в 1928 Аккерман опубликовал его функцию <math>\varphi\,\!</math>. Функция трех аргументов Аккермана <math>\varphi(m, n, p)\,\!</math> определялась так, что для ''p'' = 0, 1, 2, она проводила операцию сложения, умножения или возведения в степень: |
|||
:<math>\varphi(m, n, 0) = m+n,\,\!</math> |
|||
:<math>\varphi(m, n, 1) = m\cdot n,\,\!</math> |
|||
:<math>\varphi(m, n, 2) = m^n,\,\!</math> |
|||
а для ''p'' > 2 она доопределяется с помощью [[Стрелочная нотация Кнута|стрелочной нотации Кнута]]: |
|||
:<math>\varphi(m, n, p) = m\uparrow^{p - 1}(n + 1)\,\!</math>. |
|||
(Помимо её исторической роли как первой всюду определенной не примитивно рекурсивной вычислимой функции, оригинальная функция Аккермана расширяла основные арифметические операции за возведение в степень, хотя и не так хорошо, как специально предназначенные для этого функции вроде последовательности [[гипероператор|гипероператоров]] [[Гудстейн, Рубен|Гудстейна]].) |
|||
В статье ''On the Infinite'' Гильберт высказал гипотезу, что функция Аккермана не является примитивно рекурсивной, и Аккерман (личный секретарь и бывший студент Гильберта) доказал эту гипотезу в статье ''On Hilbert’s Construction of the Real Numbers''. [[Роза Петер]] и [[Рафаэль Робинсон]] позже представили двухаргументную версию функции Аккермана, которую теперь многие авторы предпочитают оригинальной.<ref>{{cite journal | author=Raphael M. Robinson | title=Recursion and Double Recursion | journal=[[Bulletin of the American Mathematical Society]] | year=1948 | volume=54 | pages=987-993 | url=http://projecteuclid.org/DPubS?verb=Display&version=1.0&service=UI&handle=euclid.bams/1183512393&page=record | doi=10.1090/S0002-9904-1948-09121-2 | issue=10}}</ref> |
|||
== Определение == |
== Определение == |
||
Функция |
Функция Аккермана определяется [[Рекурсия|рекурсивно]] для неотрицательных целых чисел <math>m</math> и <math>n</math> следующим образом: |
||
: <math>A(m,\;n)=\begin{cases}n+1,&m=0;\\A(m-1,\;1),&m>0,\;n=0;\\A(m-1,\;A(m,\;n-1)),&m>0,\;n>0.\end{cases}</math> |
: <math>A(m,\;n)=\begin{cases}n+1,&m=0;\\A(m-1,\;1),&m>0,\;n=0;\\A(m-1,\;A(m,\;n-1)),&m>0,\;n>0.\end{cases}</math> |
||
Может показаться неочевидным, что рекурсия всегда заканчивается. Это следует из того, что при рекурсивном вызове или уменьшается значение <math>m</math>, или значение <math>m</math> сохраняется, но уменьшается значение <math>n</math>. Это означает, что каждый раз пара <math>(m,\;n)</math> уменьшается с точки зрения [[Лексикографический порядок|лексикографического порядка]], значит, значение <math>m</math> в итоге достигнет нуля: для одного значения <math>m</math> существует конечное число возможных значений <math>n</math> (так как первый вызов с данным <math>m</math> был произведён с каким-то определённым значением <math>n</math>, а в дальнейшем, если значение <math>m</math> сохраняется, значение <math>n</math> может только уменьшаться), а количество возможных значений <math>m</math>, в свою очередь, тоже конечно. Однако, при уменьшении <math>m</math> значение, на которое увеличивается <math>n</math>, неограничено и обычно очень велико. |
Может показаться неочевидным, что рекурсия всегда заканчивается. Это следует из того, что при рекурсивном вызове или уменьшается значение <math>m</math>, или значение <math>m</math> сохраняется, но уменьшается значение <math>n</math>. Это означает, что каждый раз пара <math>(m,\;n)</math> уменьшается с точки зрения [[Лексикографический порядок|лексикографического порядка]], значит, значение <math>m</math> в итоге достигнет нуля: для одного значения <math>m</math> существует конечное число возможных значений <math>n</math> (так как первый вызов с данным <math>m</math> был произведён с каким-то определённым значением <math>n</math>, а в дальнейшем, если значение <math>m</math> сохраняется, значение <math>n</math> может только уменьшаться), а количество возможных значений <math>m</math>, в свою очередь, тоже конечно. Однако, при уменьшении <math>m</math> значение, на которое увеличивается <math>n</math>, неограничено и обычно очень велико. |
||
Строка 85: | Строка 96: | ||
== Обратная функция == |
== Обратная функция == |
||
⚫ | Так как функция <math>f(n)=A(n,\;n)</math> растёт очень быстро, обратная функция <math>f^{-1}(n)=\min\{k\geqslant 1:A(k,\;k)\geqslant n\}</math>, обозначаемая α, растёт очень медленно. Эта функция встречается при исследовании [[Теория сложности вычислений|сложности]] некоторых [[алгоритм]]ов, например, [[система непересекающихся множеств|системы непересекающихся множеств]] или алгоритма Чазелла для построения [[минимальное остовное дерево|минимального остовного дерева]]<ref>[http://rain.ifmo.ru/cat/view.php/theory/graph-spanning-trees/mst-2006 Дискретная математика: алгоритмы. Минимальные остовные деревья]</ref>. При [[Анализ алгоритмов|анализе]] [[Асимптотическая оценка|асимптотики]] можно считать, что для всех практически встречающихся чисел значение этой функции меньше пяти, так как A(4, 4) одного порядка с <math>2^{2^{10^{19729}}}</math>. |
||
==Использование в [[Бенчмарк (компьютер)|бенчмарках]]== |
|||
Функция Аккермана в силу своего определения имеет очень глубокий уровень рекурсии, что можно использовать для проверки способности [[компилятор]]а оптимизировать рекурсию. Первым функцию Аккермана для этого использовал Ингви Сандблад <ref>{{cite journal | author=Y. Sundblad | title=The Ackermann function, A theoretical, computational and formula manipulative study | journal=BIT | year=1971 | volume=11 | pages=107–119 | url=http://www.springerlink.com/content/t0701h82385w7718/ | doi=10.1007/BF01935330}}</ref>. |
|||
Брайан Вичман (соавтор бенчмарка [[Whetstone]]) учел эту статью при написании серии статей о тестировании оптимизации вызовов <ref>{{cite web | title=Ackermann's Function: A Study In The Efficiency Of Calling Procedures | year=1975 | url=http://history.dcs.ed.ac.uk/archive/docs/Imp_Benchmarks/ack.pdf}}</ref><ref>{{cite web | title=How to Call Procedures, or Second Thoughts on Ackermann's Function | year=1977 | url=http://history.dcs.ed.ac.uk/archive/docs/Imp_Benchmarks/ackpe.pdf}}</ref><ref>{{cite web | title=Latest results from the procedure calling test, Ackermann's function | year=1982 | url=http://history.dcs.ed.ac.uk/archive/docs/Imp_Benchmarks/acklt.pdf}}</ref>. |
|||
Например, компилятор, который анализируя вычисление ''A''(3, 30) способен сохранять промежуточные значения вроде ''A''(3, ''n'') и ''A''(2, ''n''), может ускорить вычисление ''A''(3, 30) в сотни и тысячи раз. Также вычисление ''A''(2, ''n'') напрямую вместо рекурсивного раскрытия в ''A''(1, ''A''(1, ''A''(1,...''A''(1, 0)...))) прилично ускорит вычисление. Вычисление ''A''(1, ''n'') занимает линейное время ''n''. Вычисленние ''A''(2, ''n'') требует квадратичное время, т.к. оно раскрывается в [[O большое|O]](''n'') вложенных вызовов ''A''(1, ''i'') для различных ''i''. Вычисление ''A''(3, ''n'') требует времени пропорционально 4<sup>''n''+1</sup>. |
|||
''A''(4, 2) невозможно посчитать с помощью простого рекурсивного применения за разумное время. Вместо этого для оптимизации рекурсивных вызовов используются сокращенные формулы вроде ''A''(3, ''n'') = 8×2<sup>''n''</sup>−3. |
|||
Один из практичных способов вычисления значений функции Аккермана - [[Мемоизация]] промежуточных результатов. Компилятор может применить эту технику к функции автоматически, используя memo functions <ref name="Michie1968">Michie, Donald, "Memo Functions and Machine Learning," ''Nature'', No. 218, pp. 19–22, 1968.</ref><ref>[http://www.gtoal.com/plsql/ackerman-memo.pls.html Example: Explicit memo function version of Ackermann's function] implemented in PL/SQL</ref> Дональда Мичи. |
|||
== Примечания == |
|||
⚫ | Так как функция <math>f(n)=A(n,\;n)</math> растёт очень быстро, обратная функция <math>f^{-1}(n)=\min\{k\geqslant 1:A(k,\;k)\geqslant n\}</math> растёт очень медленно. Эта функция встречается при исследовании [[Теория сложности вычислений|сложности]] некоторых [[алгоритм]]ов |
||
<references/> |
|||
== Ссылки == |
== Ссылки == |
Версия от 15:24, 13 августа 2011
Функция Аккермана — простой пример вычислимой функции, которая не является примитивно рекурсивной. Она принимает два неотрицательных целых числа в качестве параметров и возвращает натуральное число, обозначается . Эта функция растёт очень быстро, например, число настолько велико, что количество цифр в порядке этого числа многократно превосходит количество атомов в наблюдаемой части Вселенной.
История
В конце 20-х годов XX века математики-ученики Давида Гильберта Габриэль Судан и Вильгельм Аккерман изучали основы вычислений. Судан и Аккерман известны[1] за открытие всюду определенной вычислимой (иногда называемой просто "рекурсивной"), не являющейся примитивно рекурсивной. Судан открыл менее известную функцию Судана, после чего, независимо от него, в 1928 Аккерман опубликовал его функцию . Функция трех аргументов Аккермана определялась так, что для p = 0, 1, 2, она проводила операцию сложения, умножения или возведения в степень:
а для p > 2 она доопределяется с помощью стрелочной нотации Кнута:
- .
(Помимо её исторической роли как первой всюду определенной не примитивно рекурсивной вычислимой функции, оригинальная функция Аккермана расширяла основные арифметические операции за возведение в степень, хотя и не так хорошо, как специально предназначенные для этого функции вроде последовательности гипероператоров Гудстейна.)
В статье On the Infinite Гильберт высказал гипотезу, что функция Аккермана не является примитивно рекурсивной, и Аккерман (личный секретарь и бывший студент Гильберта) доказал эту гипотезу в статье On Hilbert’s Construction of the Real Numbers. Роза Петер и Рафаэль Робинсон позже представили двухаргументную версию функции Аккермана, которую теперь многие авторы предпочитают оригинальной.[2]
Определение
Функция Аккермана определяется рекурсивно для неотрицательных целых чисел и следующим образом:
Может показаться неочевидным, что рекурсия всегда заканчивается. Это следует из того, что при рекурсивном вызове или уменьшается значение , или значение сохраняется, но уменьшается значение . Это означает, что каждый раз пара уменьшается с точки зрения лексикографического порядка, значит, значение в итоге достигнет нуля: для одного значения существует конечное число возможных значений (так как первый вызов с данным был произведён с каким-то определённым значением , а в дальнейшем, если значение сохраняется, значение может только уменьшаться), а количество возможных значений , в свою очередь, тоже конечно. Однако, при уменьшении значение, на которое увеличивается , неограничено и обычно очень велико.
Таблица значений
- Подробнее о hyper см Гипероператор
\ | |||||||
---|---|---|---|---|---|---|---|
(всего блоков ) |
Обратная функция
Так как функция растёт очень быстро, обратная функция , обозначаемая α, растёт очень медленно. Эта функция встречается при исследовании сложности некоторых алгоритмов, например, системы непересекающихся множеств или алгоритма Чазелла для построения минимального остовного дерева[3]. При анализе асимптотики можно считать, что для всех практически встречающихся чисел значение этой функции меньше пяти, так как A(4, 4) одного порядка с .
Использование в бенчмарках
Функция Аккермана в силу своего определения имеет очень глубокий уровень рекурсии, что можно использовать для проверки способности компилятора оптимизировать рекурсию. Первым функцию Аккермана для этого использовал Ингви Сандблад [4].
Брайан Вичман (соавтор бенчмарка Whetstone) учел эту статью при написании серии статей о тестировании оптимизации вызовов [5][6][7].
Например, компилятор, который анализируя вычисление A(3, 30) способен сохранять промежуточные значения вроде A(3, n) и A(2, n), может ускорить вычисление A(3, 30) в сотни и тысячи раз. Также вычисление A(2, n) напрямую вместо рекурсивного раскрытия в A(1, A(1, A(1,...A(1, 0)...))) прилично ускорит вычисление. Вычисление A(1, n) занимает линейное время n. Вычисленние A(2, n) требует квадратичное время, т.к. оно раскрывается в O(n) вложенных вызовов A(1, i) для различных i. Вычисление A(3, n) требует времени пропорционально 4n+1.
A(4, 2) невозможно посчитать с помощью простого рекурсивного применения за разумное время. Вместо этого для оптимизации рекурсивных вызовов используются сокращенные формулы вроде A(3, n) = 8×2n−3.
Один из практичных способов вычисления значений функции Аккермана - Мемоизация промежуточных результатов. Компилятор может применить эту технику к функции автоматически, используя memo functions [8][9] Дональда Мичи.
Примечания
- ↑ Cristian Calude, Solomon Marcus and Ionel Tevy (1979). "The first example of a recursive function which is not primitive recursive". Historia Math. 6 (4): 380—84. doi:10.1016/0315-0860(79)90024-7.
{{cite journal}}
: Неизвестный параметр|month=
игнорируется (справка) - ↑ Raphael M. Robinson (1948). "Recursion and Double Recursion". Bulletin of the American Mathematical Society. 54 (10): 987–993. doi:10.1090/S0002-9904-1948-09121-2.
- ↑ Дискретная математика: алгоритмы. Минимальные остовные деревья
- ↑ Y. Sundblad (1971). "The Ackermann function, A theoretical, computational and formula manipulative study". BIT. 11: 107—119. doi:10.1007/BF01935330.
- ↑ Ackermann's Function: A Study In The Efficiency Of Calling Procedures (1975).
- ↑ How to Call Procedures, or Second Thoughts on Ackermann's Function (1977).
- ↑ Latest results from the procedure calling test, Ackermann's function (1982).
- ↑ Michie, Donald, "Memo Functions and Machine Learning," Nature, No. 218, pp. 19–22, 1968.
- ↑ Example: Explicit memo function version of Ackermann's function implemented in PL/SQL
Ссылки
- Weisstein, Eric W. Ackermann Function (англ.) на сайте Wolfram MathWorld.
В другом языковом разделе есть более полная статья Ackermannfunktion (нем.). |
Это заготовка статьи по математике. Помогите Википедии, дополнив её. |