Шаг 52.
Рекурсия на Python. Анализ времени выполнения рекурсивных алгоритмов. Рекуррентные соотношения. Метод расширения. Основная теорема

    На этом шаге мы рассмотрим эту теорему.

    Основная теорема (master theorem) может использоваться в качестве быстрого способа определения временнОй сложности вычисления алгоритмов, основанных на стратегии "разделяй и властвуй". В частности, её можно применить к рекуррентным соотношениям следующего вида:

            c,               если n = 1
    T(n) = 
            aT(n/b) + f (n), если n > 1, 
где a ≥ 1, b > 1, c ≥ 0 и f() - асимптотически положительная функция. Подобные алгоритмы обычно относятся к тем задачам, исходный размер которых делится на некоторое положительное число b, не меньшее двух. Последующая обработка или объединение решений подзадач требуют f(n) операций. В зависимости от вклада слагаемых aT(n/b) и f(n) в стоимость выполнения алгоритма основная теорема в её самой общей форме утверждает, что можно определить асимптотическую жёсткую границу для T в следующих трех случаях:
  1. Если f(n) = Ο(nlogba-ε) для некоторой константы ε > 0, то T(n) ∈ Θ(nlogba);

  2. Если f(n) = Θ(nlogba (log n)k), где k ≥ 0, то T(n) ∈ Θ(nlogba (log n)k+1);

  3. Если f(n) = Ω(nlogba+ε), где ε > 0 и f(n) удовлетворяет так называемому условию регулярности a * f(n/b) ≤ d * f(n) для некоторой константы d < 1 и для всех достаточно больших n, то T(n) ∈ Θ(f(n)).

    Например, для

            1,           если n = 1
    T(n) = 
            T(n/2) + 2n, если n > 1
можно найти такое ε > 0, что порядок f(n) = 2n будет больше n(log21)+ε = nε. Действительно, в этом примере допустимо любое значение ε > 0, поскольку порядок показательной функции 2n всегда выше порядка полиномиальной. Таким образом, это рекуррентное соотношение относится к третьему случаю основной теоремы, который подразумевает, что T(n) ∈ Θ(2n).

    Если f(n) - полином степени k, то можно воспользоваться следующей более простой версией основной теоремы:

             Θ(nk),       если a * bk < 1
    T(n)  ∈  Θ(nk log n), если a * bk = 1    (3.28)
             Θ(n logb a), если a * bk > 1

    Этот результат может быть получен методом расширения. Рассмотрим следующее рекуррентное соотношение:

            c,                если n = 1
    T(n) =                                        (3.29)
            aT(n/b) + d * nk, если n > 1
где a ≥ 1, b > 1, c ≥ 0 и d ≥ 0. Процесс его расширения:
    T(n) = aT(n/b) + dnk = a[aT(n/b2) + d(n/b)k] + dnk = 
           = a2T(n/b2) + dnk(1 + a/bk) = a2[aT(n/b3) + d(n/b2)k] + dnk(1 + a/bk) = 
           = a3T(n/b3) + dnk(1 + a/bk + a2/b2k) = 
           .   .   .   .
                             i-1   
           = aiT(n/bi) + dnk  (a / bk)j.
                             j=1

    Начальное условие T(1) = c достигается при i = logb n, а подстановка этого значения в формулу даёт:

                             logbn-1                           logbn-1
    T(n) = c * alogbn + d * nk  (a / bk)j = c * nlogba + d * nk	 (a / bk)j ,
                              j=0                               j=0
где в зависимости от значений a, b и k возможны три случая.
  1. Если a < bk, то
      logbn-1
         (a / bk)j
        j=0
    
    будет постоянной величиной (которая не может быть бесконечностью). Отметим, что бесконечная сумма
        
         ri = 1 / (r - 1)   -
        i=0
    
    константа при r < 1 (то есть не расходится).

        Таким образом, в этом случае

        T(n) = c * nlogba + dKnk
    
    для некоторой постоянной K. Кроме того, поскольку a < bk, то есть logb a < k, то nk - член высшего порядка. Следовательно:
        T(n) ∈ Θ(nk)         .
    
  2. Если a = bk, то
                               logbn-1
        T(n) = c * nk  + d * nk  1 = c * nk + d * nk logb n ,
                                j=0
    
    из чего следует, что
        T(n) ∈ Θ(nk log n)         .
    
  3. Если a > bk, то, вычислив сумму геометрической прогрессии, получим:
        T(n) = c * nlogba + dnk((a/bk)logbn - 1))/(a/bk - 1) = 
             = c * nlogba + dnk(nlogba/nk - 1) K = 
             = (c + dK) nlogba - dKnk,
    
    где K = 1/(a/bk - 1) - константа. Наконец, поскольку a > bk , то есть logb a > k, мы имеем:
        T(n) ∈ Θ(nlogba)         .
    

    На следующем шаге мы рассмотрим дополнительные примеры.




Предыдущий шаг Содержание Следующий шаг