阿克曼函数理解

时间:2012-10-01 17:30:36

标签: python function recursion

我发现很难理解Ackermann功能是如何工作的。我认为我对递归的理解存在缺陷?

以下是Python中的代码:

  def naive_ackermann(m, n):
    global calls
    calls += 1
    if m == 0:
        return n + 1
    elif n == 0:
        return naive_ackermann(m - 1, 1)
    else:
        return naive_ackermann(m - 1, naive_ackermann(m, n - 1))

如果我执行naive_ackermann(3,4)的函数调用,我最终如何以及为什么得到125?

评论将不胜感激。

谢谢

4 个答案:

答案 0 :(得分:12)

A(3,4)的计算并不像参数的小值那样容易或简短。 Ackermann函数的复杂度(迭代步骤数)随着参数的增长而迅速增长,计算结果也是如此。

以下是来自Wikipedia的Ackermann函数的定义:

enter image description here

正如您所看到的,在每次迭代中, m 的值会减少,直到达到 0 的最后一步为止,此时最终值为 n (+1)为您提供答案。因此,对于答案,您只需要跟踪在执行递归迭代时 n 的变化情况。为什么Ackermann函数增长如此之快,你可以看一下wiki的this小节。

正如Joran Beasley已经提到的, A(3,4)确实是125,正如维基百科所写。但是,获得此结果的过程并不短。事实上,正如我所发现的那样,需要通过递归 315 Ackermann函数值来计算得到 A(3,4),所需的迭代次数大致成比例那个。

如果您仍希望可视化此结果的结果,可以查看this page,它会为每个递归步骤的计算设置动画。但是要注意, A(3,4)将永远在这里完成动画制作,但至少你可能会用较小的参数了解这个过程。

答案 1 :(得分:7)

这是打印解释的版本:

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(2,2)

使用参数2,2输出就是这个。 (3,4已经变得有点太多了)

A(2,2)
A(1,A(2,1))
A(1,A(1,A(2,0)))
A(1,A(1,A(1,1)))
A(1,A(1,A(0,A(1,0))))
A(1,A(1,A(0,A(0,1))))
A(1,A(1,A(0,2)))
A(1,A(1,3))
A(1,A(0,A(1,2)))
A(1,A(0,A(0,A(1,1))))
A(1,A(0,A(0,A(0,A(1,0)))))
A(1,A(0,A(0,A(0,A(0,1)))))
A(1,A(0,A(0,A(0,2))))
A(1,A(0,A(0,3)))
A(1,A(0,4))
A(1,5)
A(0,A(1,4))
A(0,A(0,A(1,3)))
A(0,A(0,A(0,A(1,2))))
A(0,A(0,A(0,A(0,A(1,1)))))
A(0,A(0,A(0,A(0,A(0,A(1,0))))))
A(0,A(0,A(0,A(0,A(0,A(0,1))))))
A(0,A(0,A(0,A(0,A(0,2)))))
A(0,A(0,A(0,A(0,3))))
A(0,A(0,A(0,4)))
A(0,A(0,5))
A(0,6)
7

答案 2 :(得分:3)

ackerman(3,4) 

=ackerman(2,ackerman(3,3)) = ackerman(2,61)    #ackerman(3,3) = 61 ...
=ackerman(1,ackerman(2,60)) = ackerman (1,123)  #ackerman(2,60) = 123...
=ackerman(0,ackerman(1,122)) = ackerman (0,124)  #ackerman(1,122) = 124...
= 124+1 = 125

在此处查看http://goo.gl/jDDEA可视化ackerman(2,3)(可视化3,4太久了)

答案 3 :(得分:0)

def ackermann(m,n):
    """computes the value of the Ackermann function for the input integers m and n.
       the Ackermann function being:
       A(m,n)=n+1               if m=0
             =A(m-1,1)          if m>0 and n=1
             =A(m-1,A(m,n-1)    if m>0 and n>0"""
    if m==0:
        print (n+1)
        return n+1
    elif m>0 and n==0:
        print ("ackermann(",m-1,",",1,")")                                          #just 2 chk intrmdt val. and no. of steps invlvd.can be dltd if necessary
        return ackermann(m-1,1)
    elif m>0 and n>0:
        print ("Ackermann(",m-1,",","Ackermann(",m,",",n-1,")",")")                  #just 2 chk intrmdt val. and no. of steps invlvd.can be dltd if necessary
        return ackermann(m-1,ackermann(m,n-1)) 

只需对代码进行简单修改,以便程序打印每个步骤而不仅仅是结果。代码看起来应该与本页末尾的代码类似。运行它,(可能需要几秒钟),然后你就可以了解如何计算Ackermann函数。