函数c是Ackermann–Péter function的变体。
它之所以成名,是因为它不是Primitive Recursive,在这里,它的目的是意味着随着数量变得非常大,它很快就会用完堆栈空间。
问题是找到最小值x,使得y> = x时c(y,y)> d(y)。
我们认为这是c(3,3),但无法计算。我们确实计算了1和2:
d(1)= 16,d(2)= 65536,d(3)= 115792089237316195423570985008687907853269984665640564039457584007913129639936
c(1)= 3,c(2,2)= 183,c(3,3)=?
由于它不是原始递归的,因此c(3,3)难以计算(即耗尽堆栈空间)。但是,我们可以获取一个较低的
通过限制函数定义中的递归。
操作如下。
# Will use Memoization which eliminates repeated calculations in recursive functions
class Memoize:
def __init__(self,fn):
self.fn = fn
self.memo = {}
def __call__(self,*args):
if args not in self.memo:
self.memo[args] = self.fn(*args)
return self.memo[args]
@Memoize
def c(m,n,cnt = 0,MAX_RECURSION = 20):
" Refactor function c to have a max recursion depth "
if cnt > MAX_RECURSION:
return 0 # We know the return value is always >= 0,but normally
# much larger. By quitting early and returning zero we are
# ensuring our final computation will be smaller than it would
# otherwise if we had not limited the recurison depth
#
if m == 0:
return 0
elif m == 1 and n >= 0:
return n**2+n+1
elif m > 1 and n == 0:
return c(m-1,1,cnt+1)
elif m > 1 and n > 0:
return c(m-1,c(m,n-1,cnt+1),cnt+1)
def d(n):
exp_num = n-1
result = 2
while exp_num != -1:
result = result**2
exp_num -= 1
final_result = 2**result
return final_result
value_d = d(3)
value_c = c(3,3)
print('Number of digits in d(3) is {}'.format(len(str(value_d))))
#>>> Number of digits in d(3) is 78
print('Number of digits in c(3,3) is {}'.format(len(str(value_c))))
#>>>Number of digits in c(3,3) is 74176
因此,我们看到c(3,3)比d(3)多了约1K位数。自从我们在计算c(3,3)的早期就停止了递归以来,情况将会更加严重。
本文链接:https://www.f2er.com/2856225.html