Научная статья на тему 'ОБ ОДНОЙ ВОЗМОЖНОСТИ ВЫЧИСЛЕНИЯ ЧИСЕЛ ФИБОНАЧЧИ С ПОМОЩЬЮ ФОРМУЛЫ БИНЕ'

ОБ ОДНОЙ ВОЗМОЖНОСТИ ВЫЧИСЛЕНИЯ ЧИСЕЛ ФИБОНАЧЧИ С ПОМОЩЬЮ ФОРМУЛЫ БИНЕ Текст научной статьи по специальности «Математика»

CC BY
186
24
i Надоели баннеры? Вы всегда можете отключить рекламу.
Ключевые слова
ЧИСЛА ФИБОНАЧЧИ / ФОРМУЛА БИНЕ / ЯЗЫК ПИТОН

Аннотация научной статьи по математике, автор научной работы — Файфель Борис Леонидович

В статье рассмотрен алгоритм прямого вычисления чисел Фибоначчи с использованием формулы Бине без привлечения арифметики с плавающей точкой за время O(log n). Приведена реализация метода на языке Питон.

i Надоели баннеры? Вы всегда можете отключить рекламу.
iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.
i Надоели баннеры? Вы всегда можете отключить рекламу.

A WAY TO CALCULATE FIBONACCI NUMBERS USING BINET’S FORMULA

The article describes an algorithm for direct calculation of Fibonacci numbers using Binet’s formula without the floating point arithmetic in O (log n) time. The Python programming language is applied to implement the given methodology.

Текст научной работы на тему «ОБ ОДНОЙ ВОЗМОЖНОСТИ ВЫЧИСЛЕНИЯ ЧИСЕЛ ФИБОНАЧЧИ С ПОМОЩЬЮ ФОРМУЛЫ БИНЕ»

УДК 004.9

Б.Л. Файфель

ОБ ОДНОЙ ВОЗМОЖНОСТИ ВЫЧИСЛЕНИЯ ЧИСЕЛ ФИБОНАЧЧИ С ПОМОЩЬЮ ФОРМУЛЫ БИНЕ

Аннотация. В статье рассмотрен алгоритм прямого вычисления чисел Фибоначчи с использованием формулы Бине без привлечения арифметики с плавающей точкой за время O(log n). Приведена реализация метода на языке Питон.

Ключевые слова: числа Фибоначчи, формула Бине, язык Питон

B.L. Fayfel

A WAY TO CALCULATE FIBONACCI NUMBERS USING BINET'S FORMULA

Abstract. The article describes an algorithm for direct calculation of Fibonacci numbers using Binet's formula without the floating point arithmetic in O (log n) time. The Python programming language is applied to implement the given methodology.

Keywords: Fibonacci numbers, Binet's formula, Python

ВВЕДЕНИЕ

Как хорошо известно, числа Фибоначчи - это целочисленная последовательность, первые два члена которой равны единице, а каждый последующий равен сумме двух предыдущих. За 500 лет, прошедших с момента ввода этой последовательности в математический обиход, она основательно изучена. Открыто много интереснейших формул с участием чисел Фибоначчи. Но одной из «непреходящих» учебных задач является вычисление чисел Фибоначчи. Для этого придумано много способов: от прямой рекурсии, основанной на формуле

^п = F-n—1 + Fn—2,

до матричного метода, описанного, например, в книге Д. Кнута [1]. Большая часть этих подходов (кроме матричного метода Кнута) основаны на рекуррентных свойствах после-

довательности Фибоначчи и позволяют вычислить величину Fn в лучшем случае за время О(п). Матричный метод Кнута (использующий матричное возведение в степень) позволяет вычислить число Фибоначчи за логарифмическое время [2].

Особняком в этом ряду алгоритмов располагается формула Бине (известная еще Муавру), имеющая вид

Эта формула кажется, на первый взгляд, привлекательной, однако она содержит иррациональное число, которое при компьютерных вычислениях мы вынуждены представлять в форме числа с плавающей точкой (т. е. заменить бесконечную непериодическую дробь конечной).

Сказанное означает, что вычисления не будут точными; в них вносится погрешность ограничения. Автору однажды попалась на глаза публикация [3], в которой использовалась формула Бине для вычисления очень большого числа Фибоначчи, но реализация предполагала использование плавающей арифметики сверхвысокой разрядности (с тем чтобы нужное число полностью уместилось в мантиссу).

В настоящей статье описана совершенно другая схема использования формулы Бине, которая вообще не использует плавающую точку.

где а и Ь - целые числа. Представляется вполне очевидным, что это множество алгебраически замкнуто относительно операций обычного сложения и умножения:

Кроме того, ноль и единица принадлежат к рассматриваемому множеству триви-

ОПИСАНИЕ МЕТОДА

Рассмотрим множество чисел вида

х = а + * Ь,

(а + Ь^5) + (с + = ((а + с) + (Ь + (а + Ь^5)(с + = ((ас + 5 Ъй) + (ай + Ьс)^5).

Вполне естественно реализуется вычитание:

(а + Ь^5) - (с + = ((а - с) + (Ь -

Другими словами, рассматриваемое множество образует кольцо [4]. Теперь можно реализовать арифметику на множестве пар (a, b), в которой сложение, вычитание и умножение будут описываться формулами:

(а, Ь) + (с, d) = ((а + с), (b + d)),

(a, b) - (с, d) = ((а - с), (b - d)),

(а, Ь) * (с, d) = ((ас + 5bd), (ad + be)).

При этом будут соблюдаться все обычные аксиомы сложения и умножения. Таким образом, можно «благополучно забыть» про V5 и реализовать прямое вычисление по формуле Бине.

В результате числитель дроби будет представлять собой пару вида (0, г

Деление этого иррационального числа на дает искомый целый результат. Естественно, что в действительности делить не требуется, достаточно вычислить (используя описанную выше арифметику пар) два бинома

A = (J+®1 и В = (-±—^,

2п 2п '

и затем произвести вычитание. РЕАЛИЗАЦИЯ

В качестве языка реализации будет использован очень популярный язык Питон. В данном случае Питон хорош тем, что в него встроена арифметика целых неограниченной точности. Понятно, что алгоритм может быть реализован на любом языке, но наличие «под руками» неограниченной разрядности целых сильно облегчает задачу. Вот как выглядят нужные функции: def prod_pairs(a,b):

return (a[0] *b[0]+5*a[1] *b[1],a[0] *b[1]+a[1] *b[0]) def sub_pairs(a,b):

return (a[0]-b[0],a[1]-b[1]) def pow_pair(a,n): c=a

for _ in range(n-1): c=prod_pairs(c,a) return c def flb_bine(n):

x1=pow_pair((1,1),n)

x2=pow_pair((1,-1),n) z=sub_pairs(x1,x2) return z[1]//(2**n)

Можно ли ускорить этот код? Да, можно, если ускорить возведение в степень (аналогично тому, как это сделано в [2]). Для ускорения возведения в степень имеется стандартный подход, заключающийся в том, что для вычисления xn вычисляется цепочка x -> x2 -> x4 ->... ->x2k до тех пор, пока 2k<=n, а затем аналогичным образом вычисляется x(n-2k). Используя эту схему, можно переписать функцию возведения в степень: def pow_pair(a,n): if (n==1):

return a c=copy(a) k=1

while k*2<=n: if k<=n:

c=prod_pairs(c,c) k=k*2 p=n-k if p>=1:

tmp=pow_pair(a,p) return prod_pairs(tmp,c) else:

return c

Использование этого приема позволяет вычислять числа Фибоначчи за время, близкое к логарифмическому, по формуле Бине и без использования арифметики с плавающей точкой.

Ниже приведены результаты тестов, сравнивающие время вычисления чисел Фибоначчи простой итерацией: def flb_ite(n): c,p=0,1

for _ in range(n):

c,p=c+p,c return c

и кодом, использующим функцию fib_bine. Несмотря на очевидную простоту кода fib_ite, функция fib_bine показывает значительно лучшие результаты. Так, на компьютере автора четырехсоттысячное число Фибоначчи по описываемому алгоритму вычисляется примерно за 2 с, а прямыми итерациями - за 27 с.

На рисунке по горизонтальной оси откладывается номер рассчитываемого числа Фибоначчи, по вертикальной - время в секундах.

Сравнение производительности алгоритмов вычисления

ЗАКЛЮЧЕНИЕ

Цель, сформулированная во введении к настоящей статье, полностью достигнута -описанный метод вычисления чисел Фибоначчи по формуле Бине оказывается весьма быстрым и может быть легко реализован в любой среде разработки, поддерживающий целые числа неограниченной разрядности (Python, Lisp, Haskell). Метод не нуждается в арифметике с плавающей точкой.

СПИСОК ЛИТЕРАТУРЫ

1. Кнут Д. Искусство программирования на ЭВМ, Т. 1. Основные алгоритмы. М: Вильямс, 2017. 720 с.

2. N-е число Фибоначчи за O(log N). URL: https://habr.com/ru/post/148336/ Время доступа: 08/12/2021 12:10

3. Расчет миллионного числа Фибоначчи. URL: https://habr.com/ru/company/skillfactory /blog/555914/ Время доступа: 08/12/2021 12:15

4. Ленг С. Алгебра. М.: Наука, 1965. 431 c.

СВЕДЕНИЯ ОБ АВТОРЕ

Файфель Борис Леонидович -

кандидат физико-математических наук, доцент кафедры прикладных информационных технологий Саратовского государственного технического университета имени Гагарина Ю.А.

Boris L. Fayfel -

PhD (Physics and Mathematics), Associate Professor, Department of Applied Information Technologies, Yuri Gagarin State Technical University of Saratov

Статья поступила в редакцию 01.12.21, принята к опубликованию 17.12.21

i Надоели баннеры? Вы всегда можете отключить рекламу.