📜  阿克曼函数

📅  最后修改于: 2021-09-27 14:27:54             🧑  作者: Mango

在可计算性理论中,以威廉·阿克曼( 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] = 3next、goal、value 和 current 的值相应地发生变化。这是值如何变化的解释,

最后返回值,例如 4
本算法分析:

  • 该算法的时间复杂度为: O(mA(m, n))来计算 A(m, n)
  • 该算法的空间复杂度为: O(m)计算 A(m, n)

让我们通过解决问题来理解定义!

这里是生成阿克曼函数的最简单的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


如果您仍然希望可视化此结果是如何得出的,您可以查看此页面,该页面对每个递归步骤的计算进行了动画处理。