Понимание функции аккермана

Внешние ссылки [ править ]

  • «Функция Аккермана» . Энциклопедия математики . EMS Press . 2001 .
  • Вайсштейн, Эрик В. «Функция Аккермана» . MathWorld .
  •  Эта статья включает материалы, являющиеся общественным достоянием  из  документа NIST :  Блэк, Пол Э. «Функция Аккермана» . Словарь алгоритмов и структур данных .
  • Анимированный калькулятор функции Аккермана
  • Функция Акермана, реализованная с помощью цикла for
  • Скотт Ааронсон , кто может назвать самое большое число? (1999)
  • Функции Аккермана . Включает таблицу некоторых значений.
  • Гипероперации: функция Аккермана и новая арифметическая операция
  • Большие номера Роберта Munafo в описывает несколько вариаций на определение A .
  • Габриэль Ниваш, Обратный Аккерман без боли об обратной функции Аккермана.
  • Раймунд Зайдель, Понимание обратной функции Аккермана (презентация в формате PDF).
  • Функция Аккермана, написанная на разных языках программирования (на Rosetta Code )
  • Функция Аккермана ( Архивировано 24 октября 2009 г.) — Некоторое исследование и программирование Гарри Дж. Смита.
Авторитетный контроль

1. Встроенная функция range.

Встроенная функция range() используется для построения числовых последовательностей. В примере используем команду и функцию range для выполнения ровно 10 итераций с выводом значения от 0 до 10.

>>> for x in range(10)
…     print(x, end=’ ‘)
…0 1 2 3 4 5 6 7 8 9

При передаче только одного аргумента, последовательность будет начинаться с 0 и до значения аргумента (10), не включая его. Одна из самых распространённых ошибок, это когда разработчик предполагает, что значение аргумента функции range включается в сгенерированную последовательность. 

Приведем пример с двумя аргументами. Выведем последовательность от 20 до 30.

>>> for x in range(20, 30)
…     print(x, end=’ ‘)
…20 21 22 23 24 25 26 27 28 29

2.2. Создание числового списка с помощью функции range. 

С помощью функции range удобно строить числовые списки. 

>>> numbers = list(range(5, 25))
>>> print(numbers)

Функция range может создавать последовательности, пропуская числа в заданном диапазоне. Например, приведем пример построения списка от 0 до 100, с шагом 15.

>>> numbers = list(range(0, 100, 15))
>>> print(numbers)

С помощью цикла for и функции range можно создавать практически любой числовой список. К примеру, создадим список квадратов всех числе от 1 до 10. Операция возведения в степень обозначается двумя звездочками (**).

>>> a = []
>>> for i in range(1, 11)
…     a.append(i**2)

>>> print(a)

На каждом цикле переменная возводится в квадрат и добавляется в список. 

2.4. Перебор списка по индексам с помощью функции range

С помощью цикла и функции список можно перебирать по индексам и с каждым значением в списки, производить любые операции. Приведем пример, перебора списка по индексам, с помощью функции и функции, которая определяет длину списка. 

>>> list_1 =
>>> index ((list_1)):
…     list_1 += 100

>>> print(list_1)

В начале определим длину списка с помощью функции. Затем это значение передается функции. В нашем примере длина списка равна 6. С каждым проходом цикла , index принимает значения от 0 до 6 (не включая 6). В теле цикла мы вызываем список list_1 и обращаемся к элементам списка по индексам, равные значению переменной index. Каждое значение индекса мы увеличивает на 100. Затем с помощью функции print выводим список на экран и видим что все значения увеличены на 100. 

С помощью индексов и функции мы можем объединять информацию из разных списков. В примере ниже мы имеем список с именами, а второй список с фамилиями. Выведем на экран имя и фамилию:

>>> list_4 =
>>> list_5 =
>>> index ((list_4)):
…     print(list_4, list_5)
…Artem Ivanov
Serg Petrov
Georgy Sidorov
Petr Ulyanov

В результате получили общие данные на экране.

Аналогично можно создавать новые списки из двух или трех списков. Приведем пример перемножения трех списков:

>>> list_1 =
>>> list_2 =
>>> list_3 =
>>> list_new = []
>>> index ((list_1)):
…     list_new.(list_1 * list_2 * list_3)

>>> print(list_new)

В начале мы создадим пустой новый список вне цикла, куда будем добавлять результат с помощью функции . В результате мы получим новый список с результатом перемножения предыдущих списков по индексам. 

Важно помнить, что программа будет работать, если вы уверены, что списки одинаковой длины. Проверить это вы всегда можете с помощью встроенной функции . 

История

В конце 1920-х годов математики Габриэль Судан и Вильгельм Акерманн , ученики Дэвида Гильберта , изучали основы вычислений. И Судану, и Аккерману приписывают открытие тотальных вычислимых функций (называемых просто «рекурсивными» в некоторых источниках), которые не являются примитивно рекурсивными . Судан опубликовал менее известную функцию Судана , а вскоре после этого и независимо, в 1928 году, Аккерман опубликовал свою функцию (греческая буква фи ). Функция Аккермана с тремя аргументами определяется таким образом, что для p = 0, 1, 2 она воспроизводит основные операции сложения , умножения и возведения в степень как φ {\ displaystyle \ varphi} φ ( м , п , п ) {\ Displaystyle \ varphi (м, п, р)}

φ ( м , п , ) знак равно м + п , {\ Displaystyle \ varphi (т, п, 0) = т + п,}
φ ( м , п , 1 ) знак равно м × п , {\ Displaystyle \ varphi (м, п, 1) = м \ раз п,}
φ ( м , п , 2 ) знак равно м п , {\ Displaystyle \ varphi (м, п, 2) = м ^ {п},}

а для p > 2 он расширяет эти базовые операции способом, который можно сравнить с гипероперациями :

φ ( м , п , 3 ) знак равно м 4 ( п + 1 ) , {\ Displaystyle \ varphi (м, п, 3) = м (п + 1), \, \!}
φ ( м , п , п ) ⪆ м п + 1 ( п + 1 ) , за  п > 3. {\ displaystyle \ varphi (m, n, p) \ gtrapprox m (n + 1) {\ text {, for}} p> 3. \, \!}

(Помимо исторической роли полностью вычислимой, но не примитивно-рекурсивной функции, исходная функция Аккермана расширяет основные арифметические операции за пределы возведения в степень, хотя и не так гладко, как варианты функции Аккермана, специально разработанные для эта цель, такие как Гудстейна гипероператор последовательности.)

В О Infinite , Давид Гильберт выдвинул гипотезу о том , что функция Аккермана не примитивно рекурсивная, но это было Ackermann, Гильберта личный секретарь и бывший студент, который на самом деле доказал гипотезу в своей статье О построении Гильберта вещественных чисел .

Позже Рожа Петер и Рафаэль Робинсон разработали версию функции Акермана с двумя переменными, которая стала предпочтительной для многих авторов.

Обобщенная последовательность гиперопераций , например , также является версией функции Аккермана. г ⁡ ( м , а , б ) знак равно а м б {\ displaystyle \ operatorname {G} (m, a, b) = a b}

В 1963 году Р. К. Бак основал интуитивно понятный вариант с двумя переменными (F) на последовательности гиперопераций :

F ⁡ ( м , п ) знак равно 2 м п {\ displaystyle \ operatorname {F} (m, n) = 2 n} .

По сравнению с большинством других версий функция Бака не имеет несущественных смещений:

F ⁡ ( , п ) знак равно 2 п знак равно п + 1 F ⁡ ( 1 , п ) знак равно 2 1 п знак равно 2 + п F ⁡ ( 2 , п ) знак равно 2 2 п знак равно 2 × п F ⁡ ( 3 , п ) знак равно 2 3 п знак равно 2 п F ⁡ ( 4 , п ) знак равно 2 4 п знак равно 2 2 2 . . . 2 . . . {\ displaystyle {\ begin {array} {lr} \ operatorname {F} (0, n) = 2 n = n + 1 \\\ operatorname {F} (1, n) = 2 n = 2 + n \\\ имя оператора {F} (2, n) = 2 n = 2 \ times n \\\ имя оператора {F} (3, n) = 2 n = 2 ^ {n } \\\ имя оператора {F} (4, n) = 2 n = 2 ^ {2 ^ {2 ^ {} ^ {. \, ^ {. \, ^ {. \, ^ {2} }}}}}} \\ … \ end {массив}}}

Примеры расширений

Чтобы увидеть, как функция Аккермана так быстро растет, полезно расширить некоторые простые выражения, используя правила из исходного определения. Например, полностью оценить можно так: А ( 1 , 2 ) {\ Displaystyle А (1,2)}

А ( 1 , 2 ) знак равно А ( , А ( 1 , 1 ) ) знак равно А ( , А ( , А ( 1 , ) ) ) знак равно А ( , А ( , А ( , 1 ) ) ) знак равно А ( , А ( , 2 ) ) знак равно А ( , 3 ) знак равно 4. {\ Displaystyle {\ begin {align} A (1,2) & = A (0, A (1,1)) \\ & = A (0, A (0, A (1,0))) \\ & = A (0, A (0, A (0,1))) \\ & = A (0, A (0,2)) \\ & = A (0,3) \\ & = 4. \ конец {выровнен}}}

Чтобы продемонстрировать, как вычисления выполняются за много шагов и в большом количестве: А ( 4 , 3 ) {\ Displaystyle А (4,3)}

А ( 4 , 3 ) знак равно А ( 3 , А ( 4 , 2 ) ) знак равно А ( 3 , А ( 3 , А ( 4 , 1 ) ) ) знак равно А ( 3 , А ( 3 , А ( 3 , А ( 4 , ) ) ) ) знак равно А ( 3 , А ( 3 , А ( 3 , А ( 3 , 1 ) ) ) ) знак равно А ( 3 , А ( 3 , А ( 3 , А ( 2 , А ( 3 , ) ) ) ) ) знак равно А ( 3 , А ( 3 , А ( 3 , А ( 2 , А ( 2 , 1 ) ) ) ) ) знак равно А ( 3 , А ( 3 , А ( 3 , А ( 2 , А ( 1 , А ( 2 , ) ) ) ) ) ) знак равно А ( 3 , А ( 3 , А ( 3 , А ( 2 , А ( 1 , А ( 1 , 1 ) ) ) ) ) ) знак равно А ( 3 , А ( 3 , А ( 3 , А ( 2 , А ( 1 , А ( , А ( 1 , ) ) ) ) ) ) ) знак равно А ( 3 , А ( 3 , А ( 3 , А ( 2 , А ( 1 , А ( , А ( , 1 ) ) ) ) ) ) ) знак равно А ( 3 , А ( 3 , А ( 3 , А ( 2 , А ( 1 , А ( , 2 ) ) ) ) ) ) знак равно А ( 3 , А ( 3 , А ( 3 , А ( 2 , А ( 1 , 3 ) ) ) ) ) знак равно А ( 3 , А ( 3 , А ( 3 , А ( 2 , А ( , А ( 1 , 2 ) ) ) ) ) ) знак равно А ( 3 , А ( 3 , А ( 3 , А ( 2 , А ( , А ( , А ( 1 , 1 ) ) ) ) ) ) ) знак равно А ( 3 , А ( 3 , А ( 3 , А ( 2 , А ( , А ( , А ( , А ( 1 , ) ) ) ) ) ) ) ) знак равно А ( 3 , А ( 3 , А ( 3 , А ( 2 , А ( , А ( , А ( , А ( , 1 ) ) ) ) ) ) ) ) знак равно А ( 3 , А ( 3 , А ( 3 , А ( 2 , А ( , А ( , А ( , 2 ) ) ) ) ) ) ) знак равно А ( 3 , А ( 3 , А ( 3 , А ( 2 , А ( , А ( , 3 ) ) ) ) ) ) знак равно А ( 3 , А ( 3 , А ( 3 , А ( 2 , А ( , 4 ) ) ) ) ) знак равно А ( 3 , А ( 3 , А ( 3 , А ( 2 , 5 ) ) ) ) знак равно … знак равно А ( 3 , А ( 3 , А ( 3 , 13 ) ) ) знак равно … знак равно А ( 3 , А ( 3 , 65533 ) ) знак равно … знак равно А ( 3 , 2 65536 — 3 ) знак равно … знак равно 2 2 65536 — 3. {\ Displaystyle {\ begin {align} A (4,3) & = A (3, A (4,2)) \\ & = A (3, A (3, A (4,1))) \\ & = A (3, A (3, A (3, A (4,0)))) \\ & = A (3, A (3, A (3, A (3,1)))) \\ & = A (3, A (3, A (3, A (2, A (3,0))))) \\ & = A (3, A (3, A (3, A (2, A ( 2,1))))) \\ & = A (3, A (3, A (3, A (2, A (1, A (2,0)))))) \\ & = A (3 , A (3, A (3, A (2, A (1, A (1,1)))))) \\ & = A (3, A (3, A (3, A (2, A ( 1, А (0, А (1,0))))))) \\ & = А (3, А (3, А (3, А (2, А (1, А (0, А (0, 1))))))) \\ & = A (3, A (3, A (3, A (2, A (1, A (0,2)))))) \\ & = A (3 , А (3, А (3, А (2, А (1,3))))) \\ & = А (3, А (3, А (3, А (2, А (0, А (1 , 2)))))) \\ & = A (3, A (3, A (3, A (2, A (0, A (0, A (1,1))))))) \\ & = А (3, А (3, А (3, А (2, А (0, А (0, А (0, А (1,0))))))) \\ & = А (3 , А (3, А (3, А (2, А (0, А (0, А (0, А (0,1))))))) \\ & = А (3, А (3, A (3, A (2, A (0, A (0, A (0,2))))))) \\ & = A (3, A (3, A (3, A (2, A ( 0, A (0,3)))))) \\ & = A (3, A (3, A (3, A (2, A (0,4))))) \\ & = A (3 , A (3, A (3, A (2,5)))) \\ & = \ ldots \\ & = A (3, A (3, A (3,13))) \\ & = \ ldots \\ & = A (3, A (3,65533)) \\ & = \ ldots \\ & = A (3,2 ^ {65536} -3) \\ & = \ ldots \\ & = 2 ^ { 2 ^ {\ overset {65536} {}}} — 3. \\\ конец {выровнен}}}

Проверяет, что все элементы в последовательности True.

Описание:

Функция возвращает значение , если все элементы в итерируемом объекте — истинны, в противном случае она возвращает значение .

Если передаваемая последовательность пуста, то функция также возвращает .

Функция применяется для проверки на ВСЕХ значений в последовательности и эквивалентна следующему коду:

def all(iterable):
    for element in iterable
        if not element
            return False
    return True

Так же смотрите встроенную функцию

В основном функция применяется в сочетании с оператором ветвления программы . Работу функции можно сравнить с оператором в Python, только работает с последовательностями:

>>> True and True and True
# True
>>> True and False and True
# False

>>> all()
# True
>>> all()
# False

Но между и в Python есть два основных различия:

  • Синтаксис.
  • Возвращаемое значение.

Функция всегда возвращает или (значение )

>>> all()
# True
>>> all(])
# False

Оператор , возвращает ПОСЛЕДНЕЕ истинное значение, при условии, что в выражении все значения а если в выражении присутствует значение (ложное значение), то ПЕРВОЕ ложное значение. Что бы добиться поведения как у функции , необходимо выражение с оператором обернуть в функцию .

>>> 3 and 1 and 2 and 6
# 6
>>> 3 and  and 3 and []
# 0

>>> bool(3 and 1 and 2 and 6)
# True
>>> bool(3 and  and 3 and [])
# False

Из всего сказанного можно сделать вывод, что для успешного использования функции необходимо в нее передавать последовательность, полученную в результате каких то вычислений/сравнений, элементы которого будут оцениваться как или . Это можно достичь применяя функцию или выражения-генераторы списков, используя в них встроенные функции или методы, возвращающие значения, операции сравнения, оператор вхождения и оператор идентичности .

num = 1, 2.0, 3.1, 4, 5, 6, 7.9
# использование встроенных функций или
# методов на примере 'isdigit()'
>>> str(x).isdigit() for x in num
# 

# использование операции сравнения
>>> x > 4 for x in num
# 

# использование оператора вхождения `in`
>>> '.' in str(x) for x in num
# 

# использование оператора идентичности `is`
>>> type(x) is int for x in num
# 

# использование функции map()
>>> list(map(lambda x x > 1, num))
# 

Примеры проводимых проверок функцией .

Допустим, у нас есть список чисел и для дальнейших операций с этой последовательностью необходимо знать, что все числа например положительные.

>>> num1 = range(1, 9)
>>> num2 = range(-1, 7)
>>> all()
# True
>>> all()
# False

Или проверить, что последовательность чисел содержит только ЦЕЛЫЕ числа.

>>> num1 = 1, 2, 3, 4, 5, 6, 7
>>> num2 = 1, 2.0, 3.1, 4, 5, 6, 7.9
>>> all()
# True
>>> all()
# False

Или есть строка с числами, записанными через запятую и нам необходимо убедится, что в строке действительно записаны только цифры. Для этого, сначала надо разбить строку на список строк по разделителю и проверить каждый элемент полученного списка на десятичное число методом . Что бы учесть правила записи десятичных чисел будем убирать точку перед проверкой строки на десятичное число.

>>> line1 = "1, 2, 3, 9.9, 15.1, 7"
>>> line2 = "1, 2, 3, 9.9, 15.1, 7, девять"
>>> all()
# True
>>> all()
# False

Еще пример со строкой. Допустим нам необходимо узнать, есть ли в строке наличие открытой И закрытой скобки?

>>> simbols = '(', ')'
>>> line1 = "функция 'all()' всегда возвращает 'False' или 'True'"
>>> line2 = "функция any всегда возвращает значение bool"
>>> all()
# True
>>> all()
# False

Ссылки [ править ]

  1. ^ Монино & Hinchey 2003 , стр. 61.
  2. ^ Б Ackermann 1928 .
  3. ^ «Десятичное разложение A (4,2)» . kosara.net . 27 августа, 2000. Архивировано из оригинала на 20 января 2010 года.
  4. ^ Calude, Marcus & Tevy 1979 .
  5. ^ Гильберт 1926 , стр. 185.
  6. ^ Хейенорта 1967 .
  7. ^ Петер 1935 .
  8. ^ Робинсон 1948 .
  9. Перейти ↑ Ritchie 1965 , p. 1028.
  10. ^ с обратным порядком параметров
  11. ^ Бак 1963 .
  12. Ву, Чи (17 декабря 2009 г.). «Функция Аккермана не является примитивно рекурсивной | planetmath.org» . planetmath.org . Архивировано из оригинала на 2013-05-09.
  13. ^ «Цикл Купа (функция Аккермана в цикле For) | timkoop» . timkoop.com . 2021-04-27 . Проверено 27 апреля 2021 .
  14. ^ Pettie 2002 .
  15. Перейти ↑ Matos 2014 .
  16. Перейти ↑ Vaida 1970 .
  17. ^ Sundblad 1971 .
  18. Перейти ↑ Wichmann, 1976 .
  19. Wichmann 1977 .
  20. Перейти ↑ Wichmann 1982 .

Синтаксис

Простой пример: Вы торгуете мёдом, и после каждой продажи вам нужно печатать чек. В нём должно быть указано: название фирмы, дата продажи, список наименований проданных товаров, их количество, цены, общая сумма, а также сакраментальная фраза «Спасибо за покупку!».

Если не пользоваться функциями, всё придётся прописывать вручную. В простейшем случае программа будет выглядеть так:

А теперь представьте, что произойдёт, когда вы раскрутитесь, и покупатели станут приходить один за другим. В таком случае, чеки надо будет выдавать очень быстро. Но что делать, если вдруг нагрянет ваш любимый клиент и купит 10 сортов мёда в разных количествах? Далеко не все в очереди согласятся ждать, пока вы посчитаете общую сумму и внесёте её в чек.

Хорошо, что данный процесс можно легко оптимизировать с использованием функций.

Встаёт резонный вопрос: где же обещанное упрощение и куда подевались товары? Как раз для этого, мы и будем описывать состав покупки не напрямую в функции, а в отдельном списке кортежей. Каждый кортеж состоит из трёх элементов: название товара, количество и цена.

Теперь этот список передадим в функцию как аргумент, и самостоятельно считать больше не придётся.

Да, код стал более массивным. Однако теперь для печати чека вам не придётся самостоятельно вычислять итог. Достаточно лишь изменить количество и цену товаров в списке. Существенная экономия времени! Слава функциям!

Таблица значений

Вычисление функции Аккермана можно переформулировать в терминах бесконечной таблицы. Сначала разместите натуральные числа в верхнем ряду. Чтобы определить число в таблице, возьмите число сразу слева. Затем используйте это число, чтобы найти необходимое число в столбце, заданном этим числом, и на одну строку вверх. Если слева от него нет числа, просто посмотрите на столбец с заголовком «1» в предыдущей строке. Вот небольшая верхняя левая часть таблицы:

Значения A ( m n )
п м 1 2 3 4 п
1 2 3 4 5 п + 1 {\ displaystyle n + 1}
1 2 3 4 5 6 п + 2 знак равно 2 + ( п + 3 ) — 3 {\ Displaystyle п + 2 = 2 + (п + 3) -3}
2 3 5 7 9 11 2 п + 3 знак равно 2 ⋅ ( п + 3 ) — 3 {\ Displaystyle 2n + 3 = 2 \ cdot (п + 3) -3}
3 5 13 29 61 125 2 ( п + 3 ) — 3 {\ Displaystyle 2 ^ {(п + 3)} — 3}
4 13 знак равно 2 2 2 — 3 {\ displaystyle = {2 ^ {2 ^ {2}}} — 3} знак равно 2 ↑↑ 3 — 3 {\ displaystyle = 2 \ uparrow \ uparrow 3–3} 65533 знак равно 2 2 2 2 — 3 {\ displaystyle = {2 ^ {2 ^ {2 ^ {2}}}} — 3} знак равно 2 ↑↑ 4 — 3 {\ displaystyle = 2 \ uparrow \ uparrow 4–3} 2 65536  — 3 знак равно 2 2 2 2 2 — 3 {\ displaystyle = {2 ^ {2 ^ {2 ^ {2 ^ {2}}}}} — 3} знак равно 2 ↑↑ 5 — 3 {\ displaystyle = 2 \ uparrow \ uparrow 5-3} 2 2 65536 — 3 {\ displaystyle {2 ^ {2 ^ {65536}}} — 3} знак равно 2 2 2 2 2 2 — 3 {\ displaystyle = {2 ^ {2 ^ {2 ^ {2 ^ {2 ^ {2}}}}}} — 3} знак равно 2 ↑↑ 6 — 3 {\ displaystyle = 2 \ uparrow \ uparrow 6-3} 2 2 2 65536 — 3 {\ displaystyle {2 ^ {2 ^ {2 ^ {65536}}}} — 3} знак равно 2 2 2 2 2 2 2 — 3 {\ displaystyle = {2 ^ {2 ^ {2 ^ {2 ^ {2 ^ {2 ^ {2}}}}}}} — 3} знак равно 2 ↑↑ 7 — 3 {\ displaystyle = 2 \ uparrow \ uparrow 7-3} 2 2 ⋅ ⋅ ⋅ 2 ⏟ п + 3 — 3 {\ displaystyle {\ begin {matrix} \ underbrace {{2 ^ {2}} ^ {{\ cdot} ^ {{\ cdot} ^ {{\ cdot} ^ {2}}}}} _ {n + 3 } -3 \ end {matrix}}} знак равно 2 ↑↑ ( п + 3 ) — 3 {\ displaystyle = 2 \ uparrow \ uparrow (n + 3) -3}
5 65533 знак равно 2 ↑↑ ( 2 ↑↑ 2 ) — 3 {\ displaystyle = 2 \ uparrow \ uparrow (2 \ uparrow \ uparrow 2) -3} знак равно 2 ↑↑↑ 3 — 3 {\ displaystyle = 2 \ uparrow \ uparrow \ uparrow 3–3} 2 ↑↑↑ 4 — 3 {\ displaystyle 2 \ uparrow \ uparrow \ uparrow 4–3} 2 ↑↑↑ 5 — 3 {\ displaystyle 2 \ uparrow \ uparrow \ uparrow 5-3} 2 ↑↑↑ 6 — 3 {\ displaystyle 2 \ uparrow \ uparrow \ uparrow 6-3} 2 ↑↑↑ 7 — 3 {\ displaystyle 2 \ uparrow \ uparrow \ uparrow 7-3} 2 ↑↑↑ ( п + 3 ) — 3 {\ displaystyle 2 \ uparrow \ uparrow \ uparrow (n + 3) -3}
6 2 ↑↑↑↑ 3 — 3 {\ displaystyle 2 \ uparrow \ uparrow \ uparrow \ uparrow 3–3} 2 ↑↑↑↑ 4 — 3 {\ displaystyle 2 \ uparrow \ uparrow \ uparrow \ uparrow 4–3} 2 ↑↑↑↑ 5 — 3 {\ displaystyle 2 \ uparrow \ uparrow \ uparrow \ uparrow 5–3} 2 ↑↑↑↑ 6 — 3 {\ displaystyle 2 \ uparrow \ uparrow \ uparrow \ uparrow 6-3} 2 ↑↑↑↑ 7 — 3 {\ displaystyle 2 \ uparrow \ uparrow \ uparrow \ uparrow 7-3} 2 ↑↑↑↑ ( п + 3 ) — 3 {\ displaystyle 2 \ uparrow \ uparrow \ uparrow \ uparrow (n + 3) -3}
м ( 2 → ( 3 ) → ( м — 2 ) ) — 3 {\ Displaystyle (2 \ rightarrow (3) \ rightarrow (м-2)) — 3} ( 2 → ( 4 ) → ( м — 2 ) ) — 3 {\ Displaystyle (2 \ rightarrow (4) \ rightarrow (м-2)) — 3} ( 2 → ( 5 ) → ( м — 2 ) ) — 3 {\ Displaystyle (2 \ rightarrow (5) \ rightarrow (м-2)) — 3} ( 2 → ( 6 ) → ( м — 2 ) ) — 3 {\ Displaystyle (2 \ rightarrow (6) \ rightarrow (м-2)) — 3} ( 2 → ( 7 ) → ( м — 2 ) ) — 3 {\ Displaystyle (2 \ rightarrow (7) \ rightarrow (м-2)) — 3} ( 2 → ( п + 3 ) → ( м — 2 ) ) — 3 {\ Displaystyle (2 \ rightarrow (п + 3) \ rightarrow (м-2)) — 3}

Числа здесь, которые выражаются только с помощью рекурсивного возведения в степень или стрелок Кнута , очень велики и занимают слишком много места для записи в виде простых десятичных цифр.

Несмотря на большие значения, встречающиеся в этом раннем разделе таблицы, были определены некоторые даже большие числа, такие как число Грэма , которое нельзя записать с помощью небольшого количества стрелок Кнута. Это число создается с помощью техники, аналогичной рекурсивному применению функции Аккермана к самому себе.

Это повторение приведенной выше таблицы, но значения заменены соответствующим выражением из определения функции, чтобы четко показать шаблон:

Значения A ( m n )
п м 1 2 3 4 п
0 + 1 1 + 1 2 + 1 3 + 1 4 + 1 п + 1
1 А (0, 1) А (0, А (1, 0)) = А (0, 2) А (0, А (1, 1)) = А (0, 3) А (0, А (1, 2)) = А (0, 4) А (0, А (1, 3)) = А (0, 5) А (0, А (1, n −1))
2 А (1, 1) А (1, А (2, 0)) = А (1, 3) А (1, А (2, 1)) = А (1, 5) А (1, А (2, 2)) = А (1, 7) А (1, А (2, 3)) = А (1, 9) А (1, А (2, п — 1))
3 А (2, 1) А (2, А (3, 0)) = А (2, 5) А (2, А (3, 1)) = А (2, 13) А (2, А (3, 2)) = А (2, 29) А (2, А (3, 3)) = А (2, 61) A (2, A (3, n −1))
4 А (3, 1) А (3, А (4, 0)) = А (3, 13) А (3, А (4, 1)) = А (3, 65533) А (3, А (4, 2)) А (3, А (4, 3)) A (3, A (4, n −1))
5 А (4, 1) А (4, А (5, 0)) А (4, А (5, 1)) А (4, А (5, 2)) А (4, А (5, 3)) A (4, A (5, n −1))
6 А (5, 1) А (5, А (6, 0)) А (5, А (6, 1)) А (5, А (6, 2)) А (5, А (6, 3)) А (5, А (6, n −1))

Функции гена CYP1A2

CYP1A2 метаболизирует:
  • Кофеин (CYP1A2 является главным кофеин-метаболизирующим ферментом) ()
  • Гормоны: мелатонин и эстрогены (эстрон и эстрадиол) ()
  • Метаболические отходы, такие как билирубин и уропорфириногены ()
  • Токсины, такие как ароматические гетероциклические амины (в сигаретном дыме, обугленном мясе), полициклические ароматические углеводороды (в сигаретном дыме, выхлопе дизельного двигателя) и афлатоксин B1 (в загрязненных пищевых продуктах) ()
  • Лекарственные средства: теофиллин, такрин, атипичные антипсихотики, Тайленол (ацетаминофен) и MDMA (экстази) (, 7, 8)

Фермент CYP1A2 активируется через рецептор ароматических углеводородов (Ahr) ()

Ген CYP1A2 демонстрирует значительную степень разнообразия своей активности (разница может достигать до 40 раз) между разными людьми в зависимости от их наследственных генов, происхождения и факторов окружающей среды (например, курения, потребления кофе и практикуемой диеты). (, 3)

Исследования по наследуемости этого гена показывают, что генетические варианты могут определять до 75% активности фермента CYP1A2, в то время как еда, пищевые добавки и курение ответственны за остальные 25%. (, 10)

Полезные возможности CYP1A2

Этот фермент важен для удаления токсичных химических веществ из нашего тела и переработки гормонов и других продуктов нашего метаболизма.

Потенциальный вред CYP1A2

CYP1A2 активирует канцерогенные агенты, как ароматические гетероциклические амины, полициклические ароматические углеводороды (ПАУ) и афлатоксин В1. () Затем они должны быть нейтрализованы другими ферментами.

Как повышенная, так и пониженная активность фермента CYP1A2 связана с ростом рисков развития злокачественных опухолей. (, , 13)

numerals.js — Числа Черча

В 30-х годах прошлого века перед математиками встала так называемая проблема разрешения (Entscheidungsproblem), сформулированная Давидом Гильбертом. Суть её в том, что вот есть у нас некий формальный язык, на котором можно написать какое-либо утверждение. Существует ли алгоритм, за конечное число шагов определяющий его истинность или ложность? Ответ был найден двумя великими учёными того времени Алонзо Чёрчем и Аланом Тьюрингом. Они показали (первый — с помощью изобретённого им λ-исчисления, а второй — теории машины Тьюринга), что для арифметики такого алгоритма не существует в принципе, т.е. Entscheidungsproblem в общем случае неразрешима.

Так лямбда-исчисление впервые громко заявило о себе, но ещё пару десятков лет продолжало быть достоянием математической логики. Пока в середине 60-х Питер Ландин не отметил, что сложный язык программирования проще изучать, сформулировав его ядро в виде небольшого базового исчисления, выражающего самые существенные механизмы языка и дополненного набором удобных производных форм, поведение которых можно выразить путем перевода на язык базового исчисления. В качестве такой основы Ландин использовал лямбда-исчисление Чёрча. И всё заверте…

В основе лямбда-исчисления лежит понятие, известное ныне каждому программисту, — анонимная функция. В нём нет встроенных констант, элементарных операторов, чисел, арифметических операций, условных выражений, циклов и т. п. — только функции, только хардкор. Потому что лямбда-исчисление — это не язык программирования, а формальный аппарат, способный определить в своих терминах любую языковую конструкцию или алгоритм. В этом смысле оно созвучно машине Тьюринга, только соответствует функциональной парадигме, а не императивной.

Как уже говорилось ранее, в чистом бестиповом лямбда-исчислении отсутствует всё, кроме функций. Так что даже такие элементарные вещи, как числа или булевы значения необходимо реализовывать самим. Точнее, надо создать некие активные сущности, которые будут вести себя подобно необходимым нам объектам. И, естественно, процесс кодирования будет заключаться в написании соответствующих функций.

Натуральные числа реализованные посредством лямбда-исчисления, называются числами Черча, и являются отличной разминкой для мозга. В основе реализации по-прежнему будут лежать функции, ведущие себя в заданном контексте подобно единице, двойке и т.д. Собственно, это одна из особенностей лямбда-исчисления: сущности, записанные в его терминах, не обладают самодостаточностью, поскольку воплощают поведение того или иного объекта.

p.s. Вероятно, это задание не решить без чтения статей по лямбда-исчислению, но поверьте, оно того стоит.

Реализуйте число Zero и операцию Succ (увеличение на единицу). Не забудьте про экспорт.

Пример:

Аннотация типов

Python — язык с динамической типизацией. По этой причине вполне возможны ситуации, когда вопреки ожиданиям разработчика в функцию подаются, например, не целые числа, а, допустим, строки. Чтобы отслеживать подобные случаи и сильнее контролировать процесс выполнения программы, была изобретена аннотация типов.

С помощью аннотации типов мы указываем, что параметры в функции имеют строго определенный тип.

В этой функции мы показали, что аргументы и результат должны быть целыми. Если передать , то функция выполнится как обычно, однако IDE предупредит нас, что было получено неожиданное значение.

PyCharm предупреждает о передаче типа «str» вместо «int»

При этом интерпретатор считывает аннотации типов, но никак их не обрабатывает.

4 ответа

Лучший ответ

Вычисление A (3,4) не так просто и коротко, как может показаться на первый взгляд из небольших значений аргументов. Сложность (число итерационных шагов) функции Аккермана растет очень быстро с ее аргументами, как и вычисляемый результат.

Вот определение функции Аккермана из Википедии:

Как вы можете видеть, на каждой итерации значение m уменьшается до тех пор, пока не достигнет , что будет последним шагом, после чего окончательное значение n (+1) дает вам ответ. Поэтому для ответа вам нужно только проследить, как n изменяется, когда вы проходите рекурсивные итерации. Почему функция Ackermann растет так быстро, вы можете взглянуть на подраздел вики.

Как уже упоминал Джоран Бизли, A (3,4) действительно 125, как написано в Википедии. Однако процесс достижения этого результата не очень короткий. На самом деле, как я выяснил, для получения A (3,4) требуется вычислить с помощью рекурсии 315 значений функции Аккермана, причем число необходимых итераций приблизительно пропорционально к этому.

Если вы все еще хотите визуализировать, как достигается этот результат, вы можете посмотреть это страница , которая анимирует вычисление каждого шага рекурсии. Имейте в виду, однако, что A (3,4) потребуется целая вечность, чтобы закончить анимацию здесь, но по крайней мере вы могли бы получить некоторое представление о процессе с меньшими аргументами.

12

Abhranil Das
5 Окт 2012 в 17:26

Просто внесите в свой код простую модификацию, чтобы программа печатала все шаги, а не только результат. Код должен выглядеть примерно так, как в конце этой страницы. Запустите его (это может занять несколько секунд), и тогда вы сможете оценить, как вычисляется функция Аккермана.

K. W. Cooper
15 Мар 2017 в 04:47

Вот версия, которая печатает объяснение:

С аргументами 2,2 вывод таков. (С 3,4 становится уже слишком много)

7

Janne Karila
1 Окт 2012 в 18:30

3

Joran Beasley
1 Окт 2012 в 18:19

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Все про сервера
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: