временная сложность вычислений числа Фибоначчи зависит от используемого алгоритма. Существует как минимум 4 алгоритма их вычисления (с разной временной сложностью):
Сначала отметим, что мы можем понять это, посмотрев на граф вызовов рекурсивной функции Фибоначчи. .
Callgraph на самом деле является деревом.
![введите здесь описание изображения](https://i.stack.imgur.com/oPTFd.png)
Мы можем свести все к тому, чтобы узнать, сколько узлов у этого дерева.
Количество узлов в графе вызовов для F(n) имеет корень и количество узлов в графе вызовов F(n-1) + количество узлов в графе вызовов F(n-2).
Мы будем обозначать количество узлов в F(n) через L(n) (и вы увидите, что буква L не случайна).
Как мы описали выше, L(n) = L(n-1) + L(n-2) + 1.
Но подождите, есть еще! Оказывается, это точно числа Леонардо, и они имеют общая закрытая форма:
![введите здесь описание изображения](https://i.stack.imgur.com/HTsAb.png)
( "a(n) is the number of nodes in the Fibonacci tree of order n."
A001595)
O(n)
Существует еще один алгоритм, включающий запоминание, который имеет сложность O(n) (вот пример и еще один). Это включает в себя сохранение результатов T(n) в векторе и постепенное вычисление T(n) для n=1 до требуемого n.
Если вы хотите быть действительно очень правильным, это также не O (n), поскольку предполагается, что числовая стоимость добавления равна O (1), однако ... по мере того, как F (n) становится больше, стоимость добавления два числа Фибоначчи равны O(n). Вы можете узнать больше об этом здесь. , это прекрасное изложение этого. Таким образом, фактическая сложность этой реализации составляет O(n^2).
O(1)
Существует также другой алгоритм сложности O(1), если вы используете арифметику произвольной точности или умное округление. Это происходит из формулы Бине. Доказательство формулы Бине см. в разделе 1.3 на стр. 13 здесь с помощью генерирующих функций или вы можете найти собственное разложение матрицы, а затем использовать его для вычислить энную степень . После этого ваша формула в закрытой форме окажется в одной из ячеек n-й матрицы мощности.
Если вы хотите быть очень точным, на самом деле это O(log(n)), так как это возведение в степень путем возведения в квадрат (также называемый повторным возведением в квадрат, алгоритмом двоичного усиления или двоичным возведением в степень), который вы используете вычислить формулу Бине.
Обычно мы предполагаем, что степень x^n
равна O (1), но это не так, это O (log (n)) в количестве умножений. Чтобы быть по-настоящему точным, вы должны учитывать стоимость умножения, которая зависит от алгоритма умножения используется.
Вот формула Бине, кстати:
![введите здесь описание изображения](https://i.stack.imgur.com/Jk7Nt.gif)
Вот как выглядит последовательность Фибоначчи в матричной форме:
![введите здесь описание изображения](https://i.stack.imgur.com/U7b4g.png)
Вот возведение в степень в квадрате:
![введите здесь описание изображения](https://i.stack.imgur.com/t9NkA.png)
ОБНОВЛЕНИЕ 2015-06-29:
О (лог (п))
Есть еще один подход к вычислению чисел Фибоначчи в O(log(n)) . Используются два идентификатора
![](https://i.imgur.com/Dyru8Fu.png)
Они позволяют вычислять F(2*n+1) на основе F(n),F(n+1) и F(2*n) на основе F(n-1),F(n),F(n+1). Алгоритм находит старший значащий бит n и повторяется до наименее значащий бит при использовании идентификаторов по пути для вычисления числа Фибоначчи. Здесь есть реализация алгоритма. Два идентификатора могут быть получены (как в предыдущей ссылке) в квадратичном поле ℚ( √5) или они могут быть получены из n-й и 2n-й степеней матрицы, упомянутой выше (см. раздел 2.5, озаглавленный «Матричные методы», на стр. 23 документа «Алгоритмы быстрого вычисления чисел Фибоначчи» Дж. Л. Холлоуэя) .
person
Community
schedule
21.03.2013
Fib(0) = 0
иFib(1) = 1
. В данном случаеg(-1) = 1
иg(0) = 1
. - person Gio Borje   schedule 22.03.2013