给定两个函数,找到一个阈值,使一个总是大于另一个

Given two functions, find a threshold such that one is always bigger than the other

我在Python中实现了以下两个功能:

def c(m, n):
    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)
    elif m > 1 and n > 0:
        return c(m-1, c(m, n-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

其中输入 mn 都是自然数。我被要求找到一个 x,这样对于所有数字 y >= xc(y,y) > d(y).

一些输入和输出:

c(1, 1) = 3

c(2, 2) = 183

d(1) = 16

d(2) = 65536

d(3) = 115792089237316195423570985008687907853269984665640564039457584007913129639936

如您所见,d 的增长速度比 c 快得多。我该如何解决这个问题?任何帮助将非常感激。

函数 c 是 Ackermann–Péter function 的变体。

它之所以出名是因为它不是 Primitive Recursive,这里的目的是指随着数字变得非常大,它在计算中很快 运行 出栈 space。

问题是找到最小 x,使得 c(y, y) > d(y),对于 y >= x。

我们认为这是 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) 很难计算(即 运行 出栈 space)。然而,我们可以获得一个下限,而不是一个确切的数字 通过限制函数定义中的递归。

这是按如下方式完成的。

# 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) 的早期就停止了递归,所以会更多。