Analyzing an algorithm with recurrence T(n) = T(n - 1) + T(n - 2) + T(n -3)?

后端 未结 3 1498
野趣味
野趣味 2021-02-02 03:42

So, someone posted this question earlier, but essentially no effort was put into it, it was poorly tagged and then closed. Nonetheless, I think it could have been a good questi

3条回答
  •  一整个雨季
    2021-02-02 03:58

    The recurrence you have set up is the following:

    T(n) = T(n - 1) + T(n - 2) + T(n - 3)

    I assume the base cases are probably

    T(0) = T(1) = T(2) = 1

    If you start to expand out the terms of this recurrence, you get

    • T(0) = 1
    • T(1) = 1
    • T(2) = 1
    • T(3) = 3
    • T(4) = 5
    • T(5) = 9
    • T(6) = 17
    • T(7) = 31
    • ...

    There doesn't seem to be an obvious pattern here. Fortunately, we can go to the Online Encyclopedia of Integer Sequences and punch in the terms 1, 1, 1, 3, 5, 9, 17 and you'll find that this is the Tribonacci sequence whose first three terms are 1.

    If you look at the information about the Tribonacci numbers, you'll see the following:

    a(n)/a(n-1) tends to the tribonacci constant, 1.839286755...

    (here, a(n) is the notation the site uses for my T(n)). Since the ratio of consecutive terms of the Tribonacci sequence tends to approximately 1.839286755, we know that the Tribonacci sequence must be exponentially growing, and it grows exponentially at a rate that is approximately Θ(1.839286755n). (Compare this to the Fibonacci sequence, which is known to grow at Θ(φn), where φ is the golden ratio). Doing some further reading on Wikipedia gives this formula for the Tribonacci constant:

    enter image description here

    and confirms the exponential growth rate.

    Consequently, we can conclude that the runtime is Θ(1.839286755n).

    So... how would you compute this on your own? The easiest way to do this (and I think the way that these values are known) is to use generating functions. You can try to derive a generating function for the recurrence you have written out here, then try to rewrite the generating function in a closed-form to get the exact value. This is one way to get the closed-form for Fibonacci numbers, and it should generalize here (though it might be a lot of slogging through unpleasant math.) Alternatively, as @tmyklebu points out, you could write out this matrix:

         | 0 1 0 |
     M = | 0 0 1 |
         | 1 1 1 |
    

    and compute its eigenvalues, the largest of which will come out to the Tribonacci constant. (Note that this matrix has the property that

     | 0 1 0 |   |a|   |    b    |
     | 0 0 1 | x |b| = |    c    |
     | 1 1 1 |   |c|   |a + b + c|
    

    Consequently, if you put three consecutive values from the recurrence into a column vector v and compute Mv, you get back a new column vector holding the latter two values from the recurrence, plus the next value in the recurrence. In this way, you can compute the kth value of the recurrence by computing Mkv and looking at the first component of the vector.)

    Hope this helps!

提交回复
热议问题