Основная теорема о рекуррентных соотношениях

В этой статье вы познакомитесь с основной теоремой о рекуррентных соотношениях и узнаете, как использовать ее для решения рекуррентных соотношений.

Основная теорема о рекуррентных соотношениях — это формула, предназначенная для решения рекуррентных соотношений следующего вида:

T(n) = aT(n/b) + f(n), где
n = объем входных данных
a = количество подзадач в рекурсии
n/b = размер каждой подзадачи. Предполагается, что все подзадачи имеют одинаковый размер.
f(n) = оценка выполненной работы вне рекурсивных вызовов.

Также она включает в себя вычислительную стоимость деления на подзадачи объединения решений этих подзадач.

Здесь a ≥ 1 и b > 1 — константы, а f(n) — асимптотически положительная функция.

Асимптотически положительная функция — функция, где при достаточно больших значениях n f(n)>0.

Основная теорема о рекуррентных соотношениях — простой и быстрый способ вычисления временной сложности рекуррентных соотношений (например, «Разделяй и властвуй»).

Формулировка теоремы

Если a ≥ 1 и b > 1 — константы, а f(n) — асимптотически положительная функция, то временная сложность рекуррентного соотношения задается выражением: 

T(n) = aT(n/b) + f(n)

T(n) имеет следующие асимптотические оценки:

  1. Если f(n) = O(nlogb a-ϵ), то T(n) = Θ(nlogb a).
  2. Если f(n) = Θ(nlogb a), то T(n) = Θ(nlogb a*log n).
  3. Если f(n) = Ω(nlogb a+ϵ), то T(n) = Θ(f(n)).

ϵ > 0 — константа.

Каждое из этих условий можно интерпретировать следующим образом:

  1. Если стоимость решения подзадач на каждом уровне увеличивается на некий коэффициент, то значение f(n) станет полиномиально меньше, чем nlogb a. То есть, временная сложность зависит от стоимости последнего уровня — nlogb a.
  2. Если стоимость решения подзадач на каждом уровне примерно одинакова, то значение f(n) станет равно nlogb a. То есть, временная сложность будет равна f(n), умноженной на количество уровней — nlogb a*log n. 
  3. Если стоимость решения подзадач на каждом уровне уменьшается на некий коэффициент, то значение f(n) станет полиномиально больше, чем nlogb a. То есть, временная сложность зависит от стоимости f(n).

Пример использования 

T(n) = 3T(n/2) + n²
Здесь:
a = 3
n/b = n/2
f(n) = n²
logb a = log2 3 ≈ 1.58 < 2
то есть f(n) > nlogb a+ϵ, где ϵ — константа.
То есть, это 3 случай.
Следовательно, T(n) = f(n) = Θ(n²)

Откуда в теореме берется величина nlogb a? Запустите блок-схему ниже: она моделирует дерево рекурсии для a = 2 и b = 2 — на каждом уровне задача делится пополам, а количество подзадач удваивается. Введите n, например 16 или 64.

n = int(input())
a = 2
b = 2
levels = 0
leaves = 1
while n > 1:
    n = n // b
    levels = levels + 1
    leaves = leaves * a
print("Уровней рекурсии:", levels)
print("Подзадач на нижнем уровне:", leaves)

Уровней получается logb n, а подзадач на нижнем уровне — alogb n, то есть nlogb a. Именно с этой величиной теорема сравнивает f(n), чтобы понять, какой из трех случаев применить.

Когда не работает

Основную теорему о рекуррентных соотношениях нельзя использовать в следующих случаях:

  • T(n) не монотонна — например, T(n) = sin n.
  • f(n) не полиномиальна — например, f(n) = 2n.
  • a не константа — например, а = 2n.
  • a < 1.
Проверьте себя
1. Для рекуррентного соотношения T(n) = aT(n/b) + f(n) что означает параметр a?
AРазмер каждой подзадачи
BКоличество подзадач в рекурсии
CСтоимость объединения решений
DМинимальный размер входных данных
2. Дано T(n) = 3T(n/2) + n². Так как f(n) = n² = Ω(n^(log₂3 + ε)) ≈ Ω(n^1.58), какой случай теоремы применяется?
AСлучай 1: T(n) = Θ(n^log_b a)
BСлучай 3: T(n) = Θ(f(n)) = Θ(n²)
CСлучай 2: T(n) = Θ(n^log_b a · log n)
DТеорема не применима
3. В каком случае основную теорему о рекуррентных соотношениях нельзя применить?
AКогда a = 2 и b = 2
BКогда f(n) = n · log n
CКогда задача делится на две равные подзадачи
DКогда f(n) = 2ⁿ (не полиномиальная функция)
4. Для T(n) = 2T(n/2) + O(n) (сортировка слиянием): log₂2 = 1, f(n) = O(n) = O(n^log_b a). Какой случай теоремы?
AСлучай 1: T(n) = Θ(n)
BСлучай 3: T(n) = Θ(n²)
CСлучай 2: T(n) = Θ(n log n)
DСлучай 1: T(n) = Θ(log n)