You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

理论上能否优化Ackermann函数?其时间复杂度可降低吗?

是否存在时间复杂度优于标准版本的Ackermann函数实现?

我出于好奇想知道,有没有时间复杂度比标准实现更优的Ackermann函数写法——这不是作业,纯粹是个人兴趣。我清楚Ackermann函数递归深度极大,除了做性能基准外没实际用途,而且数值增长快到离谱,我完全不关心计算出的具体结果。

Python 3不会有整数溢出问题,但时间有限,我先根据维基百科的定义实现了一个版本,只算了极小值验证输出正确:

def A(m, n):
    if not m:
        return n + 1
    return A(m - 1, A(m, n - 1)) if n else A(m - 1, 1)

这完全是定义的直接转译,但速度慢得离谱,我不知道该怎么优化,难道这个函数根本没法优化?

我首先想到的是记忆化(memoization),但递归是反向进行的,每次递归调用的参数之前都没出现过——参数是递减而非递增的,所以首次调用新参数时,记忆化完全帮不上忙。只有再次调用相同参数时,才能读取缓存结果,但只要输入(m,n)≥(4,2),解释器还是会直接崩溃。

我还照着Stack Overflow上的一个回答实现了另一个版本:

def ack(x, y):
    for i in range(x, 0, -1):
        y = ack(i, y - 1) if y else 1
    return y + 1

结果这个版本速度更慢:

In [2]: %timeit A(3, 4)
1.3 ms ± 9.75 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

In [3]: %timeit ack(3, 4)
2 ms ± 59.9 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

补充测试结果

A(3,9)和A(4,1)会直接导致解释器崩溃,A(3,8)的性能测试如下:

In [2]: %timeit A(3, 8)
432 ms ± 4.63 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [3]: %timeit ack(3, 8)
588 ms ± 10.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

进一步验证参数重复情况

我写了代码统计调用次数:

from collections import Counter
from functools import cache

c = Counter()
def A1(m, n):
    c[(m, n)] += 1
    if not m:
        return n + 1
    return A(m - 1, A(m, n - 1)) if n else A(m - 1, 1)

def test(m, n):
    c.clear()
    A1(m, n)
    return c

发现参数确实会重复,但缓存对首次调用完全没用:

In [9]: %timeit Ackermann = cache(A); Ackermann(3, 4)
1.3 ms ± 10.1 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

只有再次调用相同参数时,缓存才发挥作用:

In [14]: %timeit Ackermann(3, 2)
101 ns ± 0.47 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)

多次测试不同参数,首次调用都没有效率提升。

现在的核心问题是:理论上能否优化Ackermann函数?如果不能,能不能证明它的时间复杂度无法降低?


内容的提问来源于stack exchange,提问作者Ξένη Γήινος

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 20:52:42