【问题标题】:Outlier in linear algorithm for nth Fibonacci第 n 次斐波那契线性算法中的异常值
【发布时间】:2018-02-22 06:22:12
【问题描述】:

所以我被教导使用斐波那契数的递归关系,我可以得到一个 O(n) 算法。但是,由于大 n 的斐波那契数的大小,相加所花费的时间相应地更长:这意味着时间复杂度不再是线性的。

这一切都很好,但是在这个图表 (source) 中,为什么有一个接近 1800000 的数字比它的邻居需要更长的计算时间?

编辑:如答案中所述,异常值约为 180000,而不是 1800000

【问题讨论】:

    标签: performance fibonacci


    【解决方案1】:

    异常值发生在 180,000,而不是 1,800,000。我不知道在 python 中存储了多大的整数,但假设 32 位字存储为二进制,fib(180000) 需要接近 100,000 字节。我怀疑测试存在问题,为什么 180,000 比 181,000 或 179,000 花费的时间要长得多。

    @cdlane 提到了从 fib(170000) 到 fib(200000) 所需的时间,但增量为 1000,因此将是 30 个测试用例,每个测试用例运行 10 次,所需时间不到 20 分钟。

    链接到的文章提到了用于计算斐波那契数的矩阵变体,这是一个 log2(n) 过程。这可以使用类似逻辑的卢卡斯序列进一步优化(重复平方以将矩阵提升到幂)。 64 位无符号整数的示例 C 代码:

    uint64_t fibl(uint64_t n) {
        uint64_t a, b, p, q, qq, aq;
        a = q = 1;
        b = p = 0;
        while(1) {
            if(n & 1) {
                aq = a*q;
                a = b*q + aq + a*p;
                b = b*p + aq;
            }
            n >>= 1;
            if(n == 0)
                break;
            qq = q*q;
            q = 2*p*q + qq;
            p = p*p + qq;
        }
        return b;
    }
    

    【讨论】:

    • 是的,我错过了原文章cmets中埋藏的1000增量。 Python 会在 n = 93 左右从 int 表示切换到 bignums,遗憾的是在 1000 的增量处无法在图表上看到。
    【解决方案2】:

    可能时间测量是在一个系统上完成的 任务是同时执行的,这导致了一个单一的 计算花费的时间比预期的要长。

    OP 未复制的部分图表显示:

    注意:每个数据点都是 10 次计算的平均值[原文如此]。

    所以这似乎否定了这种解释,除非它是一个巨大差异并且我们只看到它与正常时间的平均值。

    (我的 2012 年老式 Mac mini 使用作者的代码在 1/2 秒内计算出第 200,000 个数字。产生此数据的机器花了 4 多秒来计算第 200,000 个数字。我拿出一台 2009 年的老式 MacBook 到确认这是可信的。)

    我用修改后的代码做了我自己的粗略图表,每次开始时都没有重新启动,而是保持运行总时间,并得出以下图表:

    时间比预期的要长一些,因为我使用的算法会在每次计算中增加一些打印开销。但在 180,000 到 195,000 之间并没有太大的异常。

    【讨论】:

      猜你喜欢
      • 2010-12-04
      • 2020-02-09
      • 2022-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-03
      • 1970-01-01
      相关资源
      最近更新 更多