Общий вид рекуррентного соотношения
Рекуррентные соотношения для большинства алгоритмов могут быть записаны в следующем общем виде:
$$T(N) = aT(\frac{N}{b}) + f(N)$$
Общий вид рекуррентного соотношения
В приведённой формуле:
- $a \geqslant 1$ – количество рекурсивных вызовов на каждом уровне
- $b > 1$ – количество подзадач, на которые бьётся текущая задача
- $f(N)$ – время, необходимое на выполнение этапов разделения и слияния
Общий вид рекуррентного соотношения
Пример для сортировки слиянием:
$$T(N) = 2T(\frac{N}{2}) + \Theta(N)$$
Решение данного соотношения:
$$T(N) = log_b(N) \cdot f(N) = \Theta(Nlog_2(N))$$
Другие соотношения
- Рассмотрим другие соотношения, чтобы понять, что позволяет приходить к такому решению
- Для начала возьмём меньшую степень для $N$ в $f(N)$, т.е. пусть $f(N) = \Theta(N^0) = \Theta(1)$
- Также примем $a = 1$ и $b = 2$
- Построим дерево рекурсии
Дерево рекурсии
Анализ соотношения
- В данном случае сложность алгоритма, заданного таким соотношением составит $log_2(N) \cdot \Theta(1) = \Theta(log_2(N))$
- Примечательно, что это снова соответствует $log_b(N) \cdot f(N)$
- Также отметим, что данное соотношение соответствует алгоритму двоичного поиска
Другие соотношения
- Рассмотрим ещё одно соотношение, теперь с большей степенью для $N$
- Пусть $f(N) = \Theta(N^2)$
- Также примем $a = 9$ и $b = 3$
- Построим дерево рекурсии
Дерево рекурсии
Предварительный анализ дерева
Как видно, не все величины на дереве известны. Выведем их:
- Начнём с высоты дерева
- На каждом уровне размер отдельной подзадачи уменьшается в $b$ раз
- Тогда на $i$-ом уровне размер отдельной подзадачи равен $\frac{N}{b^i}$
- Задачи бьются до тех пор, пока объём отдельной подзадачи не станет равен $1$
Предварительный анализ дерева
Тогда:
\begin{multline}
\frac{N}{b^h} = 1\\
N = b^h\\
h = log_b(N),
\end{multline}
где $h$ – высота дерева.
Предварительный анализ дерева
- Теперь разберёмся с количеством листьев
- На каждом уровне создаётся в $a$ раз больше рекурсивных вызовов
- Тогда на $i$-ом уровне будет создано $a^i$ рекурсивных вызовов
- Листья находятся на $h$-ом уровне, а значит их количество равно $a^h$
Предварительный анализ дерева
Преобразуем, подставив значение $h$ и воспользовавшись свойством логарифмов:
$$a^h = a^{log_b(N)} = N^{log_b(a)}$$
Теперь, когда все пробелы закрыты, снова построим дерево.
Дерево рекурсии
Анализ соотношения
- Проанализируем соотношение по дереву
- Для начала посчитаем сумму сложности каждого уровня
Анализ соотношения
- На первом уровне сложность, очевидно, равна $$f(N) = N^2$$
- На втором уровне сложность равна $$9f(\frac{N}{3}) = 9(\frac{N}{3})^2 = 9\frac{N^2}{9} = N^2$$
Анализ соотношения
- На третьем уровне сложность равна $$N^{log_b(a)}f(1) = N^{log_3(9)} \cdot 1 = N^2$$
Анализ соотношения
- Как видно, для всех уровней сложность равна $$\Theta(N^2)$$
- Как мы помним, всего таких уровней $$h + 1 = log_b(N) + 1$$
- А значит, общая сложность равна $$(log_b(N) + 1) \cdot N^2 = \Theta(N^2log_b(N))$$
Анализ соотношения
- Важно заметить, что мы снова получили сложность $T(N) = log_b(N) \cdot f(N)$
- Следует выяснить, что именно позволяет нам сохранять это равенство на совершенно разных рекуррентных соотношениях
- Рассмотрим подробнее значения каждого из элементов соотношения
Анализ соотношения
№ |
$a$ |
$b$ |
$f(N)$ |
1 |
$1$ |
$2$ |
$N^0$ |
2 |
$2$ |
$2$ |
$N^1$ |
3 |
$9$ |
$3$ |
$N^2$ |
Анализ соотношения
- Методом пристального взгляда на таблицу можно убедиться, что во всех трёх случая соблюдается одно важнейнее соотношение: $$f(N) = N^d\\d = log_b(a)$$
- Именно это соотношение позволяет сохранить хрупкий баланс, состоящий в том, что каждый уровень рекурсии вносит равный вклад в сложность
Другие случаи
- Посмотрим, что будет, если соотношение не соблюдается
- Если $d > log_b(a)$, каждый следующий уровень будет вносить всё меньший вклад в рекурсию, а значит, сложность будет определяться корнем дерева, то есть $$T(N) = f(N)$$
Другие случаи
- Если же $d < log_b(a)$, каждый следующий уровень будет вносить всё больший вклад в рекурсию, а значит, сложность будет определяться суммой листьев дерева, то есть $$T(N) = N^{log_b(a)}$$