在可计算性理论中,以Wilhelm Ackermann命名的Ackermann函数是不是原始递归的总可计算函数的最简单且最早发现的例子之一。所有基本的递归函数都是合计且可计算的,但是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,目标,值和current的值是:
尽管next [current]!=目标[current] ,否则else语句将执行并且传输变为false。
所以现在, next,目标,值和current的值是:
类似地,通过跟踪算法直到next [m] = 3 , next,目标,值和电流的值也相应地变化。这是值如何变化的解释,
最后返回值,例如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
这是用于生成Ackermann函数的最简单的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
如果您仍然希望可视化如何得出此结果,则可以看一下该页面,该页面可以对每个递归步骤的计算进行动画处理。