在可计算性理论中,以威廉·阿克曼( Wilhelm Ackermann)命名的阿克曼函数是非原始递归的全可计算函数的最简单和最早发现的例子之一。所有原始递归函数都是全可计算的,但阿克曼函数说明并非所有全可计算函数都是原始递归。有关更多信息,请参阅此内容。
这是一个带有两个参数的函数,每个参数都可以分配任何非负整数。
阿克曼函数定义为:
阿克曼算法:
Ackermann(m, n)
{next and goal are arrays indexed from 0 to m, initialized so that next[O]
through next[m] are 0, goal[O] through goal[m - l] are 1, and goal[m] is -1}
repeat
value <-- next[O] + 1
transferring <-- true
current <-- O
while transferring do begin
if next[current] = goal[current] then goal[current] <-- value
else transferring <-- false
next[current] <-- next[current]+l
current <-- current + 1
end while
until next[m] = n + 1
return value {the value of A(m, n)}
end Ackermann
这是给定算法的解释:
让我以 A(1, 2) 为例解释算法,其中 m = 1 和 n = 2
所以根据最初的算法, next、goal、value 和 current 的值是:
虽然next[current] !=goal[current] ,所以 else 语句将执行并且传输变为假。
所以现在, next、goal、value 和 current 的值分别是:
类似地,通过跟踪算法直到 next[m] = 3 , next、goal、value 和 current 的值相应地发生变化。这是值如何变化的解释,
最后返回值,例如 4
本算法分析:
- 该算法的时间复杂度为: O(mA(m, n))来计算 A(m, n)
- 该算法的空间复杂度为: O(m)计算 A(m, n)
让我们通过解决问题来理解定义!
Solve A(1, 2)?
Answer:
Given problem is A(1, 2)
Here m = 1, n = 2 e.g m > 0 and n > 0
Hence applying third condition of Ackermann function
A(1, 2) = A(0, A(1, 1)) ———- (1)
Now, Let’s find A(1, 1) by applying third condition of Ackermann function
A(1, 1) = A(0, A(1, 0)) ———- (2)
Now, Let’s find A(1, 0) by applying second condition of Ackermann function
A(1, 0) = A(0, 1) ———- (3)
Now, Let’s find A(0, 1) by applying first condition of Ackermann function
A(0, 1) = 1 + 1 = 2
Now put this value in equation 3
Hence A(1, 0) = 2
Now put this value in equation 2
A(1, 1) = A(0, 2) ———- (4)
Now, Let’s find A(0, 2) by applying first condition of Ackermann function
A(0, 2) = 2 + 1 = 3
Now put this value in equation 4
Hence A(1, 1) = 3
Now put this value in equation 1
A(1, 2) = A(0, 3) ———- (5)
Now, Let’s find A(0, 3) by applying first condition of Ackermann function
A(0, 3) = 3 + 1 = 4
Now put this value in equation 5
Hence A(1, 2) = 4
So, A (1, 2) = 4
Let’s solve another two questions on this by yourself!
Question: Solve A(2, 1)?
Answer: 5
Question: Solve A(2, 2)?
Answer: 7
这里是生成阿克曼函数的最简单的c和Python递归函数代码
C++
// C++ program to illustrate Ackermann function
#include
using namespace std;
int ack(int m, int n)
{
if (m == 0){
return n + 1;
}
else if((m > 0) && (n == 0)){
return ack(m - 1, 1);
}
else if((m > 0) && (n > 0)){
return ack(m - 1, ack(m, n - 1));
}
}
// Driver code
int main()
{
int A;
A = ack(1, 2);
cout << A << endl;
return 0;
}
// This code is contributed by SHUBHAMSINGH10
C
// C program to illustrate Ackermann function
#include
int ack(int m, int n)
{
if (m == 0){
return n+1;
}
else if((m > 0) && (n == 0)){
return ack(m-1, 1);
}
else if((m > 0) && (n > 0)){
return ack(m-1, ack(m, n-1));
}
}
int main(){
int A;
A = ack(1, 2);
printf("%d", A);
return 0;
}
// This code is contributed by Amiya Rout
Java
// Java program to illustrate Ackermann function
class GFG
{
static int ack(int m, int n)
{
if (m == 0)
{
return n + 1;
}
else if((m > 0) && (n == 0))
{
return ack(m - 1, 1);
}
else if((m > 0) && (n > 0))
{
return ack(m - 1, ack(m, n - 1));
}else
return n + 1;
}
// Driver code
public static void main(String args[])
{
System.out.println(ack(1, 2));
}
}
// This code is contributed by AnkitRai01
Python3
# Python program to illustrate Ackermann function
def A(m, n, s ="% s"):
print(s % ("A(% d, % d)" % (m, n)))
if m == 0:
return n + 1
if n == 0:
return A(m - 1, 1, s)
n2 = A(m, n - 1, s % ("A(% d, %% s)" % (m - 1)))
return A(m - 1, n2, s)
print(A(1, 2))
# This code is contributed by Amiya Rout
C#
// C# program to illustrate Ackermann function
using System;
class GFG
{
static int ack(int m, int n)
{
if (m == 0)
{
return n + 1;
}
else if((m > 0) && (n == 0))
{
return ack(m - 1, 1);
}
else if((m > 0) && (n > 0))
{
return ack(m - 1, ack(m, n - 1));
}else
return n + 1;
}
// Driver code
public static void Main()
{
Console.WriteLine(ack(1, 2));
}
}
// This code is contributed by mohit kumar 29
Javascript
如果您仍然希望可视化此结果是如何得出的,您可以查看此页面,该页面对每个递归步骤的计算进行了动画处理。