【问题标题】:How to solve a recurrence relation by unrolling?如何通过展开来解决递归关系?
【发布时间】:2020-02-19 21:59:56
【问题描述】:

如果我有 T(n) = T(n-1) + T(n-2)+ cn; T(1) = T(2) = d

如何应用展开来求解 T(n) 的封闭形式?

当我尝试通过替换展开它时,我的方程式变得非常长且难以跟踪。

【问题讨论】:

    标签: algorithm recursion math fibonacci


    【解决方案1】:

    您可以使用 Python 的符号数学库 sympy 来写出这些术语。

    from sympy.abc import c, d
    
    def T(n):
        if n <= 0:
            return None
        elif n <= 2:
            return d
        else:
            return T(n-1) + T(n-2) + c*n
    
    for i in range(1, 11):
        print(i, T(i))
    

    这给出了:

    1 d
    2 d
    3 3*c + 2*d
    4 7*c + 3*d
    5 15*c + 5*d
    6 28*c + 8*d
    7 50*c + 13*d
    8 86*c + 21*d
    9 145*c + 34*d
    10 241*c + 55*d
    

    d 的系数显然是斐波那契数。 c 的系数可以在 oeis 中查找到 A023552。这给出了一个很长的明确公式,还有Fibonacci(n+2) + 2*Fibonacci(n) - (n+3)

    使用sqrt(5)Fibonacci 替换为Binet 的公式,得到T(n) 的以下表达式:

    -2**(-n)*(c*(20*2**n*n + 60*2**n + 8*sqrt(5)*((1 - sqrt(5))**n - (1 + sqrt(5))**n) + sqrt(5)*((1 - sqrt(5))**(n + 2) - (1 + sqrt(5))**(n + 2))) + 4*sqrt(5)*d*((1 - sqrt(5))**n - (1 + sqrt(5))**n))/20
    

    这个公式与上面n = 1 .. 10 的值非常吻合。但它看起来不像是“手工”计算的公式。 (请注意,Python 使用** 表示功率并保留^ 用于异或。)

    或者,可以尝试Sympy's rsolve 来获得一个明确的公式:

    from sympy import Function, rsolve
    from sympy.abc import n, c, d
    
    f = Function('f')
    T = f(n) - f(n-1) - f(n-2) - c*n
    s = rsolve(T, f(n), {f(1): d, f(2): d})
    print (s.simplify())
    

    哪些输出:

    2**(1 - n)*d*(-2**n*c*n - 2**(n + 1)*c + c*(1 + sqrt(5))**n - (1 - sqrt(5))**n + (1 + sqrt(5))**n)/(-5*c + sqrt(5)*c + 2*sqrt(5))
    

    不幸的是,这似乎是错误的。

    【讨论】:

      【解决方案2】:

      让我们重新安排一下

      T(n) - T(n-1) - T(n-2) = cn

      由于T的左边是线性的,所以有一个标准解法:求通解,求任意特解,然后找到该通解的右实例加到特解中,以求得匹配边界条件 T(1) = T(2) = d。

      一般解决方案

      我们要找到 T′(n) - T′(n-1) - T′(n-2) = 0 的所有解。 T′(n) 的解不是原问题的解, 因为右边为零;但是求解这个方程很有用,因为通过线性,原始问题的解决方案加上“等于零”问题的任何解决方案都会为原始问题提供另一个解决方案。

      这是一个线性递推关系,所以我们可以猜测对于某些 x ≠ 0 的解具有 T′(n) = xn 的形式。代入得到 xn - xn-1 - xn-2 = 0,除以 xn-2 得到二次方程 x 2 - x - 1 = 0。通过应用二次公式,这个方程有两个解,恰好是golden ratio x = φ 和 x = -1/φ。

      所以 T′(n) = φn 和 T′(n) = (-1/φ)n 都是解,因为方程是线性的,这些的任何线性组合也是一种解决方案。一般形式为 T′(n) = aφn + b(-1/φ)n 其中 a 和 b 是任意常数。

      特殊解决方案

      我们想找到 T(n) - T(n-1) - T(n-2) = cn 的任何解。由于右手边是 n 中的 1 次多项式,我们可以猜测对于一些 p,q 的解具有 T(n) = pn + q 的形式。将其代入给出

      (pn + q) - (pn - p + q) - (pn - 2p + q) = cn

      等式系数,-pn = cn 和 3p - q = 0,所以我们有 p = -c 和 q = -3c,因此特解是 T(n) = -cn - 3c。

      边界条件

      所以我们正在寻找 a 和 b 的值,这样

      T(n) = aφn + b(-1/φ)n - cn - 3c

      满足边界条件 T(1) = T(2) = d。代入,我们得到

      • aφ + b(-1/φ) - c - 3c = d
      • 2 + b(-1/φ)2 - 2c - 3c = d

      由于 c、d 和 φ 是常数,因此这是一个包含两个变量 a 和 b 的线性方程组。它可以通过应用诸如消除或替换之类的标准技术来解决,或者只是plugged into Wolfram Alpha,给出唯一的解决方案

      这当然可以简化以消除分母中的平方根,但我认为这对于演示求解方法不是必需的。

      【讨论】:

      • 不错。 WolframAlpha 有一个复制粘贴错误:b 需要一个减号。修正符号后,数值与我的相同。顺便说一下,简化的表达式是a = (5 * c + sqrt(5) * (7 * c + 2 * d)) / 10b = (5 * c - sqrt(5) * (7 * c + 2 * d)) / 10
      • 哇!优雅+简单!
      猜你喜欢
      • 2020-11-09
      • 1970-01-01
      • 2020-01-30
      • 1970-01-01
      • 2021-12-17
      • 2014-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多