Рубрики
Без рубрики

Найти nth последовательность фибоначчи

Последовательность Фибоначчи представляет собой рекурсивную функцию, определенную как (N-1) + Фибоначчи (п … Теги с Python, учебник.

Последовательность Фибоначчи – рекурсивная функция, определенная как Фибоначчи (N) (N-1) + Фибоначчи (N-2) . Другими словами:

n            | 0  | 1  | 2  | 3  | 4  | 5  | 6  | 7  | 8  | 9  | 10 |
Fibonacci(n) | 0  | 1  | 1  | 2  | 3  | 5  | 8  | 13 | 21 | 34 | 55 |

Последовательность Фибоначчи является «Hello World» рекурсии, потому что это относительно легко понять. Однако сегодня мы собираемся расстаться на монотонности и научиться рассчитать значение N с суммы. Другими словами, мы сделаем функцию, которая принимает номер 55 и выплескивает 10. Мы также узнаем, как обрабатывать исключительно большие суммы, где нам нужно будет использовать приближение.

Последовательность Фибоначчи имеет некоторые применения в области математики и информатики, но я не математик, ни ученый, поэтому, честно говоря, я не знаю, какого реального мира целятся что-то вроде этого. Настоящая точка зрения – согнуть нашу проблему, решая мышцы, думая о старой проблеме по-новому.

На первый взгляд решение для этой проблемы кажется очевидным: сделать последовательность фибоначчи, затем напишите другую функцию, которая принимает число и петли через функцию FIBONACCI, пока не будет совпадение.

Функция Фибоначчи:

def fib(n):
  ar = [0, 1]
  if n < len(ar):
    return ar[n]
  else:
    while n > len(ar) - 1:
    ar.append(
      ar[len(ar)-1] + ar[len(ar) - 2]
    )
  return ar[n]

Достаточно легко, но давайте убедимся (я назвал этот файл fib.py):

>>> from fib import *
>>> fib(10)
55

Идеально. Теперь, давайте напишем функцию, которая даст нам 10, когда пройдем его 55:

def find_fib(sum):
  n = 0
  while True:
    if fib(n) > sum:
      return -1 # This is our error code
    elif fib(n):
      n = n+1
    else:
      return n

Эта функция принимает в сумме, скажем, 55, а затем начинает вычислять номер фибоначчи в течение 0 через бесконечность. Первая строка после в то время как Петля проверяет, если fibonacci (n) больше, чем пройденная сумма (я скажу вам, почему через секунду). Если это не так, мы увеличиваем на один так, чтобы в следующей цикле мы рассчитываем следующий номер фибоначчи. Наконец, если FIB (N) не больше, чем и меньше, чем сумма , это должно быть равно, то есть мы нашли наши n и таким образом вернуть его.

Мы проверяем, если FIB (N) больше, чем сумма, потому что это возможно, что номер пройдено не является числом фибоначчи вообще. Предположим, мы прошли эту функцию номер 25. В 8 итерации FIB (N) будет 21, а в следующем он будет 34, пропуская 25. Мы возвращаем -1, чтобы показать, что сумма, передаваемая этой функции, не является номером фибоначчи.

Мне нравится проходить -1 в этой функции вместо сообщения об ошибке, как «Это не номер Fibonacci», потому что я не думаю, что Mathy Functions должен вернуть слова. Это просто выбор личного дизайна, и фактическая реализация зависит от вас:)

Давайте пойдем вперед и проверим эту функцию:

>>> from fib import *
>>> fib(20)
6725
>>> find_fib(6725)
20
>>> find_fib(25)
-1

Потрясающий. Есть одна вещь, которую мне не нравится в этом решении, хотя: это медленно. Предположим, почему-то сумма, которую вы искали, была 2000-й последовательностью. Продолжай и попробуй:

>>> x = fib(2000)
>>> find_fib(x)
2000

Это все еще работает, но твой простоял, чтобы выяснить это? Мои уверены, мне интересно, есть ли способ ускорить его (оповещение спойлера, есть).

Угадай, что? Существует фактически формула для поиска приближенного значения числа фибоначчи без вычисления всех чисел до:

Fibonacci(n) = (Phi^n)/5^0.5

Так что, если мы действительно хотели найти N, мы бы использовали:

n = log base Phi of (5^0.5 * Fibonacci(n))

Обратите внимание, что число до 0,5 питания является квадратным корнем, я не знаю, как писать радикал в Markdown 🤷. Также примечание, номер «PHI»:

Phi = ((5^0.5) + 1)/2

Давайте поставим это в функцию:

import math
def find_fib_formula(sum):
  Phi = (math.sqrt(5) + 1)/2
  formula_result = round(math.log((sum * math.sqrt(5)), Phi))
  return formula_result

Круто, давайте попробуем это

>>> from fib import *
>>> x = fib(1000)
>>> find_fib_formula(x)
1000

Оно работает! Есть проблема, хотя. Так как мы используем круглый Чтобы вернуть результат, мы могли бы вступить в проблему, где передается номер неибоначчи, но возвращается. Например, мы знаем, что Fibonacci (1000) – 1 не является номером фибоначчи, а посмотреть:

>>> x = fib(1000)
>>> find_fib_formula(x - 1)
1000

Это возвращает неправильное значение, поэтому нам нужно бросить в то, что двойные проверки. Перепишите свою функцию, чтобы проверить, если fib (formula_result) и вернуть код ошибки (-1), если нет:

def find_fib_formula(sum):
  Phi = (math.sqrt(5) + 1)/2
  formula_result = round(math.log((sum * math.sqrt(5)), Phi))
  if fib(formula_result) == sum:
    return formula_result
  else:
    return -1

И давайте проверим это еще раз:

>>> from fib import *
>>> x = fib(1000)
>>> find_fib_formula(x)
1000
>>> find_fib_formula(x - 1)
-1

Потрясающий! Но еще раз, эта функция не совсем идеальна, вы можете догадаться, почему? Попробуйте использовать его с результатом FIB (2000) . Вы получили ошибку, сказав, что INT слишком большой, чтобы преобразовать в Float? Это потому, что эти цифры получают Действительно Большой, поскольку мы становимся выше, и часть нашего уравнения умножается в целое число Big OL на квадратный корень из пяти, что составляет около 2,23. Python не может превратить это большое целое число в десятичное число, поэтому нам придется найти способ.

Поскольку проблема в том, что мы не можем превратить эти большие целые числа в поплавке, мы просто не собираемся. Когда мы хотим умножить сумму на PHI, мы на самом деле просто собираемся умножить его на 2, а затем найти базовую базу журнала этого номера. Поскольку этот путь менее точен, мы также увидимся, чтобы убедиться, что результаты нашей формулы являются точными, а если нет, мы попробуем несколько других чисел вокруг нашего результата. Это будет выглядеть так:

def find_big_fib(sum):
  Phi = (math.sqrt(5) + 1)/2
  possible_solution = round(math.log(sum*2, Phi))
  if fib(possible_solution) == sum:
    return possible_solution
  else:
    possible_solutions = [
      possible_solution - 1,
      possible_solution - 2,
      possible_solution - 3,
      possible_solution + 1,
      possible_solution + 2,
      possible_solution + 3,
    ]
    for i in possible_solutions:
      if fib(i) == sum:
        return i
    return -1

Можете ли вы сказать, что здесь происходит? Как и в прошлый раз, мы сначала рассчитаем стоимость PHI. Затем мы запускаем ту же формулу, что и предыдущая функция, но на этот раз мы используем 2 вместо квадратного корня 5, избегая необходимости поворота невероятно гигантского целого числа в поплавок. Чтобы убедиться, что мы не потеряли слишком много точности путем приближения, мы проверяем, мы проверяем, если число мы поднялись, равна числу, которое мы передали при поставке через функцию Fibonacci. Если нет, мы попробуем плюс или минус 1, 2 и 3 Номер, который мы подошли. Если ни один из них не прав, мы заключаем, что сумма, переданная нам, не является последовательностью фибоначчи и возврат -1.

>>> from fib import *
>>> x = fib(3000)
>>> find_big_fib(x)
3000

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

Я добавил некоторые условные условные скрипту Python так, что вы всегда можете использовать find_fib Функция, и она решит, нужно ли использовать find_fib_formula, Кто решит, должен ли он использовать find_big_fib Отказ Вот код в полном объеме:

import math

def fib(n):
  ar = [0, 1]
  if n < len(ar):
    return ar[n]
  else:
    while n > len(ar)-1:
      ar.append(
        ar[len(ar)-1] + ar[len(ar)-2]
      )
    return ar[n]

def find_fib(sum):
  if sum < fib(500):
    n = 0
    while True:
      if fib(n) > sum:
        return -1 # This is an error code
      elif fib(n) < sum:
        n = n+1
      else:
        return n
  else:
    return find_fib_formula(sum)

def find_fib_formula(sum):
  if sum <= fib(1000):
    Phi = (math.sqrt(5) + 1)/2
    formula_result = round(math.log((sum * math.sqrt(5)), Phi))
    if fib(formula_result) == sum:
      return formula_result
    else:
      return -1
  else:
    return find_big_fib(sum)

def find_big_fib(sum):
  Phi = (math.sqrt(5) + 1)/2
  possible_solution =  round(math.log(sum * 2, Phi))
  if fib(possible_solution) == sum:
    return possible_solution
  else:
    possible_solutions = [
      possible_solution - 1,
      possible_solution - 2,
      possible_solution - 3,
      possible_solution + 1,
      possible_solution + 2,
      possible_solution + 3,
    ]
    for i in possible_solutions:
      if fib(i) == sum:
        return i
    return -1

Оригинал: “https://dev.to/erikwhiting88/find-the-nth-sequence-of-a-fibonacci-sum-462d”